UdonSharp icon indicating copy to clipboard operation
UdonSharp copied to clipboard

Enum casting is weird (especially for synchronization)

Open JLChnToZ opened this issue 9 months ago • 1 comments

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,
}

JLChnToZ avatar Apr 05 '25 07:04 JLChnToZ

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.

JLChnToZ avatar Apr 05 '25 08:04 JLChnToZ