Syncing Large Number of Children Transform using OnPhotonSerializeView

I'm attempting to achieve two main objectives:
  1. Sync transform state of root gameobject with many (200+) children
  2. Be able to add and delete children gameobjects from under the root gameobject and sync their states
To achieve this, I've implemented OnPhotonSerializeView that does the following:

public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
		if (stream.isWriting) {
			for (int i = 0; i < childrenTransforms.Length; i++) {
				if (childrenTransforms[i] != null) {
					stream.SendNext(childrenTransforms[i].localPosition);
					stream.SendNext(childrenTransforms[i].localRotation);
					stream.SendNext(childrenTransforms[i].localScale);
				}
			}
		} else {
			for (int i = 0; i < childrenTransforms.Length; i++) {
				if (childrenTransforms[i] != null) {
					childrenTransforms[i].localPosition = (Vector3)stream.ReceiveNext();
					childrenTransforms[i].localRotation = (Quaternion)stream.ReceiveNext();
					childrenTransforms[i].localScale = (Vector3)stream.ReceiveNext();
				}
			}
		}
	}
}
Three main questions:
  1. Does this seem like the right approach to handle syncing of large gameobject transform hierarchies?
  2. If the root gameobjects transform changes, does that send update message for all of it's children?
  3. This currently works fine with small transform hierarchies but I've tested with very large ones and I get numerous InvalidCastExceptions on the clients listening for updates and the connection drops.

Answers

  • Hi @talothman,

    Does this seem like the right approach to handle syncing of large gameobject transform hierarchies?


    This seems to be fine so far and it is by far the better approach than adding a PhotonView component to each of the child objects. You only should take care of what you really want to synchronize. If these child objects don't move on their own, you won't have to synchronize their position at all. If they however do, you should only synchronize those objects, that actually have moved (to reduce message size).

    If the root gameobjects transform changes, does that send update message for all of it's children?


    If only the parent object moves and the child objects don't, you just have to synchronize the transform data of the parent object, because they are positioned relatively to their parent object.
  • Thanks @Christian_Simon .

    Regarding the last point, off the bat, would there be any reason why InvalidCastExceptions begin to happen with very large hierarchies? Is it that iterating through the longer lists takes a lot more time to push through the network causing order mismatches on the client end as it's receiving updates?
  • talothman
    talothman
    edited August 2018
    @Christian_Simon ,

    I've found that the main cause of this InvalidCastException is that PhotonStream.currentItem resets to zero if I write a long enough list of items to the stream (> 255). This is of course due to PhotonStream.currentItem being of type byte. When reading from the stream on the client end, I can see that the number of items in the stream is 1513 (PhotonStream.count), all things that get sent on the host side are there but because currentItem is a byte, it resets to 0 and I no longer have access to the remaining objects in the readData array, causing the mismatch in order.

    Any ideas why this upper bound exists? I changed the type of currentItem to int and things are working fine but I'm not certain I should be doing this. Any ideas?
  • Any ideas why this upper bound exists?


    I honestly don't know, but probably the reason is, that you usually don't send that much data and 256 single elements are more than enough.