static internal void HandleChildTransform(NetworkMessage netMsg)
        {
            NetworkInstanceId netId = netMsg.reader.ReadNetworkId();
            uint childIndex         = netMsg.reader.ReadPackedUInt32();

#if UNITY_EDITOR
            //UnityEditor.NetworkDetailStats.IncrementStat(
            //    UnityEditor.NetworkDetailStats.NetworkDirection.Incoming,
            //    MsgType.LocalChildTransform, "16:LocalChildTransform", 1);
#endif

            GameObject foundObj = NetworkServer.FindLocalObject(netId);
            if (foundObj == null)
            {
                if (LogFilter.logError)
                {
                    Debug.LogError("Received NetworkTransformChild data for GameObject that doesn't exist");
                }
                return;
            }
            var children = foundObj.GetComponents <NetworkTransformChild>();
            if (children == null || children.Length == 0)
            {
                if (LogFilter.logError)
                {
                    Debug.LogError("HandleChildTransform no children");
                }
                return;
            }
            if (childIndex >= children.Length)
            {
                if (LogFilter.logError)
                {
                    Debug.LogError("HandleChildTransform childIndex invalid");
                }
                return;
            }

            NetworkTransformChild foundSync = children[childIndex];
            if (foundSync == null)
            {
                if (LogFilter.logError)
                {
                    Debug.LogError("HandleChildTransform null target");
                }
                return;
            }
            if (!foundSync.localPlayerAuthority)
            {
                if (LogFilter.logError)
                {
                    Debug.LogError("HandleChildTransform no localPlayerAuthority");
                }
                return;
            }

            if (!netMsg.conn.clientOwnedObjects.Contains(netId))
            {
                if (LogFilter.logWarn)
                {
                    Debug.LogWarning("NetworkTransformChild netId:" + netId + " is not for a valid player");
                }
                return;
            }

            foundSync.UnserializeModeTransform(netMsg.reader, false);
            foundSync.m_LastClientSyncTime = Time.time;

            if (!foundSync.isClient)
            {
                // dedicated server wont interpolate, so snap.
                foundSync.m_Target.localPosition = foundSync.m_TargetSyncPosition;
                foundSync.m_Target.localRotation = foundSync.m_TargetSyncRotation3D;
            }
        }
        protected void SetSyncVarGameObject(GameObject newGameObject, ref GameObject gameObjectField, ulong dirtyBit, ref NetworkInstanceId netIdField)
        {
            if (m_SyncVarGuard)
            {
                return;
            }

            NetworkInstanceId newGameObjectNetId = new NetworkInstanceId();

            if (newGameObject != null)
            {
                var uv = newGameObject.GetComponent <NetworkIdentity>();
                if (uv != null)
                {
                    newGameObjectNetId = uv.netId;
                    if (newGameObjectNetId.IsEmpty())
                    {
                        if (LogFilter.logWarn)
                        {
                            Debug.LogWarning("SetSyncVarGameObject GameObject " + newGameObject + " has a zero netId. Maybe it is not spawned yet?");
                        }
                    }
                }
            }

            NetworkInstanceId oldGameObjectNetId = new NetworkInstanceId();

            if (gameObjectField != null)
            {
                oldGameObjectNetId = gameObjectField.GetComponent <NetworkIdentity>().netId;
            }

            if (newGameObjectNetId != oldGameObjectNetId)
            {
                if (LogFilter.logDev)
                {
                    Debug.Log("SetSyncVar GameObject " + GetType().Name + " bit [" + dirtyBit + "] netfieldId:" + oldGameObjectNetId + "->" + newGameObjectNetId);
                }
                SetDirtyBit(dirtyBit);
                gameObjectField = newGameObject;
                netIdField      = newGameObjectNetId;
            }
        }