vrchat-community / UdonSharp

A compiler for compiling C# to Udon assembly
https://udonsharp.docs.vrchat.com
MIT License
463 stars 50 forks source link

When a class have "[UdonSynced,System.NonSerialized] public int[] apple", all sync value of the class don't be synced. #53

Open arumogina opened 1 year ago

arumogina commented 1 year ago

if a class have array value with System.NonSerialized or System.NonSerializedAttribute, all udonSynced value of the class can't synced. if the value is not array, value is synced.

When [HideInInsplector], sync is work.

++enviroment: u# 1.1 VRChat SKD 3.1.2 Workd SDK 3.1.2

++test code I used.

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
using VRC.Udon.Common.Interfaces;

[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class BaseUserData : UdonSharpBehaviour
{
    [UdonSynced] public int test_a = -1;
}
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class EachLocalDataForSync : BaseUserData
{
    [UdonSynced] public int test_b = -1;    
    [UdonSynced,System.NonSerialized] public int[] apple;
    //[UdonSynced,System.NonSerialized] public int apple;
}
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class BaseUserDataList : UdonSharpBehaviour
{
    [SerializeField] BaseUserData[] target_list;

    public BaseUserData[] GetList(){
        return target_list;
    }
}
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class EachLocalDataForSyncList : BaseUserDataList
{

}
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
using TMPro;

[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class Master : UdonSharpBehaviour
{
    [SerializeField] EachLocalDataForSyncList eld_list;
    [SerializeField] TextMeshProUGUI text;
    public void Set(){
        if(!Networking.LocalPlayer.isMaster){   
            General.OutLog("Not Master");
            return;
        }
        EachLocalDataForSync[] elds = (EachLocalDataForSync[])eld_list.GetList();
        int i = 0;
        foreach(var eld in elds){
            eld.test_a = i;
            eld.test_b = i;
            i += 1;
        }
    }

    public void Sync(){
        if(!Networking.LocalPlayer.isMaster){
            General.OutLog("Not Master");
            return;
        }
        EachLocalDataForSync[] elds = (EachLocalDataForSync[])eld_list.GetList();
        foreach(var eld in elds){
            eld.RequestSerialization();
        }
    }

    public void Log(){
        text.text = "Log()" + "\n" + text.text;
        EachLocalDataForSync[] elds = (EachLocalDataForSync[])eld_list.GetList();        
        int i = 0;
        foreach(var eld in elds){
            text.text = "ary_id : " + i.ToString() + "\n" + text.text;
            text.text = "test_a : " + eld.test_a.ToString() + "\n" + text.text;
            text.text = "test_b : " + eld.test_b.ToString() + "\n" + text.text;
             i += 1;
        }
    }
}
techanon commented 1 year ago

There are known issues in Udon itself with arrays not syncing properly when null
(the implicit value when a default is not provided for an array).
Try adding a default array initializer to the field declaration public int[] apple = new int[0];