Sync boolean on players

Options
Please, explain me how to fix that problem.

Situation:

I have players which throwing ball player from player. I set in PlayerController boolean value "haveBall"
if haveball is true, ball mesh shows above the player.

void updateBallOwner() { if (haveBall) { transform.Find("Ball").GetComponent<MeshRenderer>().enabled = true; } else { transform.Find("Ball").GetComponent<MeshRenderer>().enabled = false; } }

I have function that control throwing ball by player:

void handleBallThrow() { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { if (hit.transform.name.Contains("PlayerPrefab")) { hit.transform.GetComponent<PhotonView>().RPC("receiveBall", PhotonTargets.AllBuffered); haveBall = false; } } } }

handleBallThrow() executes in Update() after condition mPhotonView.isMine == true

My RPC function receiveBall()
[PunRPC] void receiveBall(string sender) { haveBall = true; }

Problem:

Player-sender shows ball on player-receiver and ball dissapears on player-sender.
But in other client, player-receiver shows ball above his prefab, but don't removing ball (haveBall not setting to false) on player-sender.

I tried to send with RPC string with player-sender nickname, and run on gameobjects to compare photonview.owner.nickname with sender string and set haveBall to false but it's not working for me. (Strange, but my debug logs shows right messages, but booleans still wrong).

Please help me with my problem, i spend 4 days with many solutions but i cant sync this variable over clients. (One way working is send it over NetworkStream>receiveNext,sendNext, but is laggy and i know it very bad solution)

Thanks!

Comments

  • Frosty
    Options
    If there is a maximum of 1 ball in a game then a quick solution would be this.

    Set haveBall to be a public variable. Or simply create a function to change it. Doesn't matter.
    Then write this into your "void receiveBall(string sender)" function.
    
    foreach (PlayerController playerController in FindObjectsOfType<PlayerController>())
    {
        if (playerController != this)
        {
            playerController.haveBall = false;
        }
    }
    
    If, however, there are multiple balls, then you a way to find players' playercontrollers. Without creating some kind of a manager. You could do this:

    Add a public int playerId variable to your PlayerController.cs script.

    Into this script, add this function:
    void OnPhotonInstantiate(PhotonMessageInfo info)
        {
            playerId = info.sender.ID;
        }
    Now, change your RPC call to this:
    hit.transform.GetComponent<PhotonView>().RPC("receiveBall", hit.transform.GetComponent<PlayerController>().playerId);

    And change your receiveBall to this:
    
    [PunRPC]
    void receiveBall(int _playerId)
    {
        foreach ((PlayerController playerController in FindObjectsOfType<PlayerController>())
        {
            if (playerController.playerId == _playerId)
            {
                playerController.haveBall = false;
            }
        }
    }
    
  • dekamaru
    Options
    @Frosty it dont work for me. After throwing, ball dissapears and all players with boolean haveBall = false.