A recent update broke some of my older (1+ years) worlds relying on
OnDeserialization()
to sync variables for late joiners.
The variables get set once when the world is created/first person joins and never update again.
A made up example script that enables a random colored cube on creation:
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class RandomColorCube : UdonSharpBehaviour
{
[UdonSynced]
private string Color;
[SerializeField]
public string[] Colors;
private GameObject[] cubes;
void Start()
{
Debug.Log("RandomColorCube: Start()");
Initialize();
if (!Networking.IsOwner(gameObject))
{
return;
}
Color = Colors[Random.Range(0, Colors.Length - 1)];
SetCubeActive();
// this will fix it
// RequestSerialization();
}
private bool initialized = false;
public void Initialize()
{
if (initialized)
{
return;
}
Debug.Log("ColorCube: Initialize()");
var cubeCount = gameObject.transform.childCount;
cubes = new GameObject[cubeCount];
for (var i = 0; i < cubeCount; i++)
{
cubes[i] = gameObject.transform.GetChild(i).gameObject;
}
initialized = true;
}
private void SetCubeActive()
{
foreach (var cube in cubes)
{
var newState = cube.name == Color;
if (newState)
{
Debug.Log("RandomColorCube: color set to " + Color);
}
cube.SetActive(newState);
}
}
public void OnDeserialization()
{
if (Networking.IsOwner(gameObject))
{
Debug.Log("RandomColorCube: OnDeserialization() owner");
return;
}
Debug.Log("RandomColorCube: OnDeserialization()");
SetCubeActive();
}
}
The cube gets initialized on start and sets a random color. But any late joiner no longer get the Color variable synced unless
RequestSerialization()
is also called in
Start()
.
This used to work before.
The documentation states that
OnDeserialization()
is called for every object once on join.
It might need to clarify that it only does that when
RequestSerialization()
has been called at least once.