UdonSharp
UdonSharp copied to clipboard
Enum casting is weird (especially for synchronization)
Please refer to following syntax inside OnPreSerialization(), it is syntactically (and logically) correct in C# (since it was just casting the underly primitive type), I was expect the first and second also works in U#, but it didn't, only the third workaround works.
using UnityEngine;
using UdonSharp;
using VRC.SDKBase;
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class Enum2ByteTest : UdonSharpBehaviour
{
[SerializeField] TestEnum someEnum = TestEnum.Two;
[UdonSynced] byte syncdEnumAsByte;
public override void Interact()
{
if (!Networking.IsOwner(gameObject)) Networking.SetOwner(Networking.LocalPlayer, gameObject);
RequestSerialization();
}
public override void OnPreSerialization()
{
// This will cause serialization failed warning and fail to synchronize
syncdEnumAsByte = (byte)someEnum;
// This also fails
syncdEnumAsByte = (byte)(int)someEnum;
// This works
int intEnum = (int)someEnum;
syncdEnumAsByte = (byte)intEnum;
}
}
public enum TestEnum
{
Zero,
One,
Two,
Three,
}
A little detailed on what it compiles into:
For the first and second one:
PUSH, someEnum
PUSH, syncdEnumAsByte
COPY
This don't work since the type mismatch, seems casting logic was ignored by U# compiler.
But for the third one:
PUSH, someEnum
PUSH, __lcl_intEnum_SystemInt32_0
COPY
PUSH, __lcl_intEnum_SystemInt32_0
PUSH, syncdEnumAsByte
EXTERN, "SystemConvert.__ToByte__SystemInt32__SystemByte"
This works, because the U# compiler finally realizes it needs to cast (convert) the value.