Tom Quinn
Tom Quinn

Reputation: 623

PUN2: No OnPhotonSerializeView call for updating array values?

It seems like whatever logic PUN uses to determine if an observed script's properties have changed doesn't look at the values in arrays. Changing the values of all other properties generates automatic OnPhotonSerializeView calls, but changing values in arrays does not. Is there a way to get PUN to check array contents, or am I supposed to create a meaningless bool to flip whenever I want to force an update?

NOTE: I have my PhotonView set to Unreliable On Change. I've tried byte[], which Photon seems to indicate is supported, and I've also tried bool[].

Upvotes: 0

Views: 1679

Answers (1)

derHugo
derHugo

Reputation: 90659

First of all: I'm really no Photon expert so I have to trust my Google power :P


In general: make sure the GameObject with your component on it is actually in the PhotonView's "Observe" list, otherwise it won't get OnPhotonSerializeView called at all.


I would guess: An array is a reference type. Photon probably does not iterate over the entire array all the time in order to track any changes but only checks whether the reference itself changed.

As alternative you can however afaik after a change simply manually send the array like e.g.

public bool[] myBools;

...
    photonView.RPC("SetArrayRPC", PhotonTargets.All, (object)myBools);
...    

[PunRPC]
private void SetArrayRPC(bool[] array)
{
    myBools = array;
}

But afaik this should actually also do it

public class Example : Photon.MonoBehaviour
{
    public bool[] myBools = new bool[5];

    // Hit "Test" in the context menu in order to invert all values
    // Then everywhere you should see in the Inspector the updated array
    [ContextMenu(nameof(Test))]
    private void Test()
    {
        for(var i = 0; i < myBools.Length; i++)
        {
            myBools[i] = !myBools[i];
        }
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.IsWriting)
        {
            // We own this player: send the others our data
            stream.SendNext(myBools);
        }
        else
        {
            // Network player, receive data
            myBools = (bool[])stream.ReceiveNext();
        }
    }
}

Upvotes: 1

Related Questions