Method with attribute [Command] is not called when playing from the client

17 views Asked by At

A method with the Command attribute is not called when playing from the client. I'm making a building system, and the blocks I place in the world should be synchronized using the Method with Command attribute and calling the function - Network Spawn. But when I start the game and go Host, everything works, but not on the Client. With the help of Debug Log I found out that the method Cmd Set Block - (method with which I Instantiate blocks) is not called.

I tried different versions of attributes that are put before methods, I was afraid of - But the problem was not in this.

using Unity.VisualScripting;
using UnityEngine;
using Mirror;

public class BuildingsGrid : NetworkBehaviour
{
    [SerializeField] private GameObject ground, brickWall;
    [SerializeField] private Vector2Int gridSize;
    [SerializeField] private Building buildingScript;
    [SerializeField] private int money;
    [SerializeField] private int[,] objectSizes;

    private int chooseCounter;
    private GameObject followingBlock;
    //private GameObject settedBlock;
    private GameObject[,] blocks;
    private Camera mainCamera;

    private void Start()
    {
        chooseCounter = 1;
        blocks = new GameObject[gridSize.x, gridSize.y];
        objectSizes = new int[1, 1];
        objectSizes[0, 0] = 1;
        mainCamera = Camera.main;
    }

    private void Update()
    {
        if (!isLocalPlayer)
        {
            return;
        }
        else if (isLocalPlayer)
        {
            Debug.Log("isLocalPlayer");
        }

        Vector2 mousePosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);

        int x = Mathf.RoundToInt(mousePosition.x);
        int y = Mathf.RoundToInt(mousePosition.y);

        Vector2Int worldPosition = new Vector2Int(x, y);

        bool availeable = true;

        if (worldPosition.x < 0 || worldPosition.x > gridSize.x) availeable = false;
        if (worldPosition.y < 0 || worldPosition.y > gridSize.y) availeable = false;

        if (availeable && IsPlaceTaken(worldPosition)) availeable = false;
        if (availeable && followingBlock != null && money < followingBlock.GetComponent<Building>().Cost) availeable = false;
        
        SpawnFollowBlock(worldPosition);
        
        if (followingBlock != null)
        {
            Debug.Log("FollowingBlock != null");
            ChooseBlock();            
            CmdSetBlock(worldPosition, availeable);
            CmdBlocksDestroyer(worldPosition);
            followingBlock.transform.position = new Vector3(worldPosition.x, worldPosition.y);
        }
    }

    private void SpawnFollowBlock(Vector2Int mousePosition)
    {
        if (followingBlock != null)
        {
            Destroy(followingBlock.gameObject);
        }

        if (chooseCounter == 1)
        {
            followingBlock = Instantiate(ground, 
                new Vector3(mousePosition.x, mousePosition.y), Quaternion.identity);
        }
        else if (chooseCounter == 2)
        {
            followingBlock = Instantiate(brickWall, 
                new Vector3(mousePosition.x, mousePosition.y), Quaternion.identity);
        }
    }

    [Command]
    private void CmdSetBlock(Vector2Int mousePosition, bool avaliable)
    {
        Debug.Log("SetBlock");

        if (followingBlock != null && avaliable && Input.GetMouseButton(0))
        {
            Destroy(followingBlock.gameObject);

            money -= followingBlock.GetComponent<Building>().Cost;

            if (chooseCounter == 1)
            {
                GameObject settedBlock = Instantiate(ground, new Vector3(mousePosition.x, mousePosition.y), 
                    Quaternion.identity);
                NetworkServer.Spawn(settedBlock);
                blocks[mousePosition.x, mousePosition.y] = settedBlock;
            }
            else if (chooseCounter == 2)
            {
                GameObject settedBlock = Instantiate(brickWall, new Vector3(
                    mousePosition.x, mousePosition.y), Quaternion.identity);
                NetworkServer.Spawn(settedBlock);
                blocks[mousePosition.x, mousePosition.y] = settedBlock;
            }
        }
    }

    private void ChooseBlock()
    {
        if (Input.GetKeyDown(KeyCode.Keypad1))
        {
            chooseCounter = 1;
        }
        else if (Input.GetKeyDown(KeyCode.Keypad2))
        {
            chooseCounter = 2;
        }
    }

    private bool IsPlaceTaken(Vector2Int worldPosition)
    {
        for (int x = 0; x < objectSizes[0, 0]; x++)
        {
            for (int y = 0; y < objectSizes[0, 0]; y++)
            {
                if (blocks[worldPosition.x + x, worldPosition.y + y] != null) return true;
            }
        }

        return false;
    }

    [Command]
    private void CmdBlocksDestroyer(Vector2Int worldPosition)
    {
        if (Input.GetMouseButton(1))
        {
            if (blocks[worldPosition.x, worldPosition.y] != null)
            {
                NetworkServer.Destroy(blocks[worldPosition.x, worldPosition.y].gameObject);
                money += blocks[worldPosition.x, worldPosition.y].GetComponent<Building>().Cost;
                blocks[worldPosition.x, worldPosition.y] = null;
            }
        }
    }
}
0

There are 0 answers