public override void Read(ref T targetObject, IValueStorage sourceObject)
        {
            UdonBehaviour sourceBehaviour = (UdonBehaviour)sourceObject.Value;

            if (sourceBehaviour == null)
            {
                targetObject = null;
                return;
            }

            if (USBSerializationContext.currentPolicy == null)
            {
                throw new NullReferenceException("Serialization policy cannot be null");
            }

            targetObject = (T)UdonSharpEditorUtility.GetProxyBehaviour(sourceBehaviour, ProxySerializationPolicy.NoSerialization);

            if (USBSerializationContext.currentDepth >= USBSerializationContext.currentPolicy.MaxSerializationDepth)
            {
                return;
            }

            if (USBSerializationContext.serializedBehaviourSet.Contains(targetObject))
            {
                return;
            }

            USBSerializationContext.serializedBehaviourSet.Add(targetObject);
            USBSerializationContext.currentDepth++;

            try
            {
                UdonSharpBehaviourFormatterEmitter.GetFormatter <T>().Read(ref targetObject, sourceObject);
            }
            finally
            {
                USBSerializationContext.currentDepth--;

                if (USBSerializationContext.currentDepth <= 0)
                {
                    Debug.Assert(USBSerializationContext.currentDepth == 0, "Serialization depth cannot be negative");

                    USBSerializationContext.serializedBehaviourSet.Clear();
                }
            }
        }
        public override void Read(ref UdonSharpBehaviour targetObject, IValueStorage sourceObject)
        {
            UdonBehaviour sourceBehaviour = (UdonBehaviour)sourceObject.Value;

            if (sourceBehaviour == null)
            {
                if (!UsbSerializationContext.CollectDependencies)
                {
                    targetObject = null;
                }

                return;
            }

            lock (UsbSerializationContext.UsbLock)
            {
                if (UsbSerializationContext.CurrentPolicy == null)
                {
                    throw new NullReferenceException("Serialization policy cannot be null");
                }

                if (UsbSerializationContext.CollectDependencies)
                {
                    UsbSerializationContext.Dependencies.Add(sourceBehaviour);
                }

                targetObject = UdonSharpEditorUtility.GetProxyBehaviour(sourceBehaviour);

                if (UsbSerializationContext.CurrentDepth >= UsbSerializationContext.CurrentPolicy.MaxSerializationDepth)
                {
                    return;
                }

                if (UsbSerializationContext.SerializedBehaviourSet.Contains(targetObject))
                {
                    return;
                }

                UsbSerializationContext.SerializedBehaviourSet.Add(targetObject);
                UsbSerializationContext.CurrentDepth++;

                try
                {
                    Type       behaviourType = UdonSharpProgramAsset.GetBehaviourClass(sourceBehaviour);
                    IFormatter formatter     = UdonSharpBehaviourFormatterEmitter.GetFormatter(behaviourType);

                    object targetSysObj = targetObject;
                    formatter.Read(ref targetSysObj, sourceObject);

                    if (!UsbSerializationContext.CollectDependencies)
                    {
                        targetObject = (UdonSharpBehaviour)targetSysObj;
                    }
                }
                finally
                {
                    UsbSerializationContext.CurrentDepth--;

                    if (UsbSerializationContext.CurrentDepth <= 0)
                    {
                        Debug.Assert(UsbSerializationContext.CurrentDepth == 0,
                                     "Serialization depth cannot be negative");

                        UsbSerializationContext.SerializedBehaviourSet.Clear();
                    }
                }
            }
        }