[ClientRpc] // @ remote client
        public void RpcClientChangeNamedAvatar(int humanoidId, string avatarPrefabName)
        {
            if (debug <= HumanoidNetworking.Debug.Info)
            {
                Debug.Log(netId.Value + ": RpcChangeAvatar " + humanoidId + "to: " + avatarPrefabName);
            }

            HumanoidControl humanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (humanoid == null)
            {
                if (debug <= HumanoidNetworking.Debug.Warning)
                {
                    Debug.LogWarning(netId.Value + ": Could not find humanoid: " + humanoidId);
                }
                return;
            }

            GameObject remoteAvatar = (GameObject)Resources.Load(avatarPrefabName);

            if (remoteAvatar == null)
            {
                if (debug <= HumanoidNetworking.Debug.Error)
                {
                    Debug.LogError("Could not load remote avatar " + avatarPrefabName + ". Is it located in a Resources folder?");
                }
                return;
            }
            humanoid.LocalChangeAvatar(remoteAvatar);
        }
        public void OnPhotonPlayerConnected(PhotonPlayer player)
        {
#endif
            List <HumanoidControl> humanoids = HumanoidNetworking.FindLocalHumanoids();
            if (humanoids.Count <= 0)
            {
                return;
            }

            foreach (HumanoidControl humanoid in humanoids)
            {
                if (debug <= HumanoidNetworking.Debug.Info)
                {
                    Debug.Log(humanoid.nwId + ": (Re)Send StartHumanoid " + humanoid.humanoidId);
                }

                // Notify new player about my humanoid
#if hPHOTON2
                photonView.RPC("RpcStartHumanoid", RpcTarget.Others, humanoid.nwId, humanoid.humanoidId, humanoid.gameObject.name, humanoid.remoteAvatar.name, humanoid.transform.position, humanoid.transform.rotation, humanoid.physics);
#else
                photonView.RPC("RpcStartHumanoid", PhotonTargets.Others, humanoid.nwId, humanoid.humanoidId, humanoid.gameObject.name, humanoid.remoteAvatar.name, humanoid.transform.position, humanoid.transform.rotation, humanoid.physics);
#endif
                if (humanoid.leftHandTarget.grabbedObject != null)
                {
                    humanoid.humanoidNetworking.Grab(humanoid.leftHandTarget, humanoid.leftHandTarget.grabbedObject, false);
                }
                if (humanoid.rightHandTarget.grabbedObject != null)
                {
                    humanoid.humanoidNetworking.Grab(humanoid.rightHandTarget, humanoid.rightHandTarget.grabbedObject, false);
                }
            }
        }
 private void ForwardTarget(NetworkReader sReader, NetworkWriter sWriter, byte targetMask, HumanoidControl.TargetId targetId)
 {
     if (HumanoidNetworking.IsTargetActive(targetMask, targetId))
     {
         ForwardTransform(sReader, sWriter);
     }
 }
        public void RpcLetGo(int humanoidId, bool isLeft)
        {
            if (debug <= HumanoidNetworking.Debug.Info)
            {
                PhotonLog("RpcLetGo");
            }

            HumanoidControl humanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (humanoid == null)
            {
                if (debug <= HumanoidNetworking.Debug.Warning)
                {
                    PhotonLogWarning("Could not find humanoid: " + humanoidId);
                }
                return;
            }

            HandTarget handTarget = isLeft ? humanoid.leftHandTarget : humanoid.rightHandTarget;

            if (handTarget != null)
            {
                HandInteraction.LocalLetGo(handTarget);
            }
        }
        public void RpcGrab(int humanoidId, int objViewID, bool isLeft, bool rangeCheck)
        {
            PhotonView objView = PhotonView.Find(objViewID);
            GameObject obj     = objView.gameObject;

            if (debug <= HumanoidNetworking.Debug.Info)
            {
                PhotonLog("RpcGrab " + obj);
            }

            if (obj == null)
            {
                return;
            }

            HumanoidControl humanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (humanoid == null)
            {
                if (debug <= HumanoidNetworking.Debug.Warning)
                {
                    PhotonLogWarning("Could not find humanoid: " + humanoidId);
                }
                return;
            }

            HandTarget handTarget = isLeft ? humanoid.leftHandTarget : humanoid.rightHandTarget;

            if (handTarget != null)
            {
                HandInteraction.LocalGrab(handTarget, obj, rangeCheck);
            }
        }
        private void ReceiveAvatarPose(PhotonStream reader)
        {
            this.reader = reader;

            int humanoidsCount = ReceiveInt();

            for (int i = 0; i < humanoidsCount; i++)
            {
                int nwId = ReceiveInt();
#if hPHOTON2
                if (nwId != photonView.ViewID)
                {
                    return;
                }
#else
                if (nwId != photonView.viewID)
                {
                    return;
                }
#endif
                int humanoidId = ReceiveInt();

                HumanoidControl humanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);
                if (humanoid == null)
                {
                    if (debug <= HumanoidNetworking.Debug.Warning)
                    {
                        Debug.LogWarning(nwId + ": Could not find humanoid: " + humanoidId);
                    }
                    return;
                }

                this.ReceiveAvatarPose(humanoid, ref lastPoseTime, ref lastReceiveTime, ref lastReceivedPosition);
            }
        }
        public void OnPhotonInstantiate(PhotonMessageInfo info)
        {
#if hPHOTON2
            if (photonView.IsMine)
            {
#else
            if (photonView.isMine)
            {
#endif
                isLocal = true;
                name    = "HumanoidPun(Local)";

                humanoids = HumanoidNetworking.FindLocalHumanoids();
                if (debug <= HumanoidNetworking.Debug.Info)
                {
                    PhotonLog("Found " + humanoids.Count + " Humanoids");
                }

                if (humanoids.Count <= 0)
                {
                    return;
                }

                foreach (HumanoidControl humanoid in humanoids)
                {
#if hPHOTON2
                    humanoid.nwId = photonView.ViewID;
#else
                    humanoid.nwId = photonView.viewID;
#endif
                    humanoid.humanoidNetworking = this;

                    if (debug <= HumanoidNetworking.Debug.Info)
                    {
                        Debug.Log(humanoid.nwId + ": Send Start Humanoid " + humanoid.humanoidId);
                    }

#if hPHOTON2
                    photonView.RPC("RpcStartHumanoid", RpcTarget.Others, humanoid.nwId, humanoid.humanoidId, humanoid.gameObject.name, humanoid.remoteAvatar.name, humanoid.transform.position, humanoid.transform.rotation, humanoid.physics);
#else
                    photonView.RPC("RpcStartHumanoid", PhotonTargets.Others, humanoid.nwId, humanoid.humanoidId, humanoid.gameObject.name, humanoid.remoteAvatar.name, humanoid.transform.position, humanoid.transform.rotation, humanoid.physics);
#endif
                }

                NetworkingSpawner spawner = FindObjectOfType <NetworkingSpawner>();
                if (spawner != null)
                {
                    spawner.OnNetworkingStarted();
                }
            }
        }
        public void RpcDestroyHumanoid(int nwId, int humanoidId)
        {
            HumanoidControl remoteHumanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (remoteHumanoid == null)
            {
                // Unknown remote humanoid
                return;
            }

            if (remoteHumanoid.gameObject != null)
            {
                Destroy(remoteHumanoid.gameObject);
            }
        }
        public void ForwardAvatarPose(NetworkReader sReader, NetworkWriter sWriter)
        {
            int nwId = sReader.ReadInt32();

            sWriter.Write(nwId); // NwId
            int humanoidId = sReader.ReadInt32();

            sWriter.Write(humanoidId);           // HumanoidId

            sWriter.Write(sReader.ReadSingle()); // Pose Time

            byte targetMask = sReader.ReadByte();

            sWriter.Write(targetMask);

            if (debug <= HumanoidNetworking.Debug.Debug)
            {
                Debug.Log(nwId + ": Forward Pose Humanoid = " + humanoidId + ", targetMask = " + targetMask);
            }

            ForwardTransform(sReader, sWriter); // humanoid.transform is always sent

            ForwardTargets(sReader, sWriter, targetMask);

            if (HumanoidNetworking.IsTargetActive(targetMask, HumanoidControl.TargetId.LeftHand))
            {
                bool leftHandIncluded = sReader.ReadBoolean();
                sWriter.Write(leftHandIncluded);
                if (leftHandIncluded)
                {
                    ForwardAvatarHandPose(sReader, sWriter);
                }
            }

            if (HumanoidNetworking.IsTargetActive(targetMask, HumanoidControl.TargetId.RightHand))
            {
                bool rightHandIncluded = sReader.ReadBoolean();
                sWriter.Write(rightHandIncluded);
                if (rightHandIncluded)
                {
                    ForwardAvatarHandPose(sReader, sWriter);
                }
            }
        }
        public override void OnStartLocalPlayer()
        {
            isLocal = true;
            name    = "HumanoidUnet(Local)";

            humanoids = HumanoidNetworking.FindLocalHumanoids();
            if (debug <= HumanoidNetworking.Debug.Info)
            {
                Debug.Log((int)netId.Value + ": Found " + humanoids.Count + " Humanoids");
            }

            if (humanoids.Count <= 0)
            {
                CmdServerStartNoHumanoid((int)netId.Value);
                return;
            }

            foreach (HumanoidControl humanoid in humanoids)
            {
                humanoid.nwId = (int)netId.Value;
                humanoid.humanoidNetworking = this;

                if (debug <= HumanoidNetworking.Debug.Info)
                {
                    Debug.Log(humanoid.nwId + ": Send Start Humanoid " + humanoid.humanoidId);
                }

                CmdServerStartHumanoid(
                    humanoid.nwId,
                    humanoid.humanoidId,
                    humanoid.gameObject.name,
                    humanoid.remoteAvatar.name,
                    humanoid.transform.position, humanoid.transform.rotation,
                    humanoid.physics);
            }
            NetworkingSpawner spawner = FindObjectOfType <NetworkingSpawner>();

            if (spawner != null)
            {
                spawner.OnNetworkingStarted();
            }
        }
        private void RpcClientDestroyHumanoid(int nwId, int humanoidId)
        {
            if (isLocalPlayer && !createLocalRemotes)
            {
                return;
            }

            HumanoidControl remoteHumanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (remoteHumanoid == null)
            {
                // Unknown remote humanoid
                return;
            }

            if (remoteHumanoid.gameObject != null)
            {
                Destroy(remoteHumanoid.gameObject);
            }
        }
        public void ReceiveAvatarPose(NetworkMessage msg, int humanoidId)
        {
            if (isLocalPlayer && !createLocalRemotes)
            {
                return;
            }

            HumanoidControl humanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (humanoid == null)
            {
                if (debug <= HumanoidNetworking.Debug.Warning)
                {
                    Debug.LogWarning(netId.Value + ": Could not find humanoid: " + humanoidId);
                }
                return;
            }

            reader = msg.reader;
            this.ReceiveAvatarPose(humanoid, ref lastPoseTime, ref lastReceiveTime, ref lastReceivedPosition);
        }
        [ClientRpc] // @ remote client
        public void RpcClientLetGo(int nwId, int humanoidId, bool leftHanded)
        {
            if (debug <= HumanoidNetworking.Debug.Info)
            {
                Debug.Log(netId + ": RpcLetGo " + humanoidId);
            }

            HumanoidControl humanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (humanoid == null)
            {
                if (debug <= HumanoidNetworking.Debug.Warning)
                {
                    Debug.LogWarning(netId.Value + ": Could not find humanoid: " + humanoidId);
                }
                return;
            }

            HandTarget handTarget = leftHanded ? humanoid.leftHandTarget : humanoid.rightHandTarget;

            HandInteraction.LocalLetGo(handTarget);
        }
        [ClientRpc] // @ remote client
        public void RpcClientGrab(int nwId, int humanoidId, GameObject obj, bool leftHanded, bool rangeCheck)
        {
            if (debug <= HumanoidNetworking.Debug.Info)
            {
                Debug.Log(nwId + ": RpcGrab " + obj);
            }

            HumanoidControl humanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (humanoid == null)
            {
                if (debug <= HumanoidNetworking.Debug.Warning)
                {
                    Debug.LogWarning(netId.Value + ": Could not find humanoid: " + humanoidId);
                }
                return;
            }

            HandTarget handTarget = leftHanded ? humanoid.leftHandTarget : humanoid.rightHandTarget;

            HandInteraction.LocalGrab(handTarget, obj, rangeCheck);
        }
        public void RpcStartHumanoid(
            int nwId, int humanoidId,
            string name, string avatarPrefabName,
            Vector3 position, Quaternion rotation,
            bool physics)
        {
#if hPHOTON2
            if (nwId != photonView.ViewID)
#else
            if (nwId != photonView.viewID)
#endif
            { return; }

            HumanoidControl remoteHumanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);
            if (remoteHumanoid != null)
            {
                // This remote humanoid already exists
                return;
            }

            humanoids.Add(HumanoidNetworking.StartHumanoid(nwId, humanoidId, name, avatarPrefabName, position, rotation, physics));
        }
        [ClientRpc] // @ remote client
        private void RpcClientStartHumanoid(
            int nwId,
            int humanoidId,
            string name,
            string avatarPrefabName,
            Vector3 position, Quaternion rotation,
            bool physics
            )
        {
            if (isLocalPlayer && !createLocalRemotes)
            {
                return;
            }

            HumanoidControl remoteHumanoid = HumanoidNetworking.FindRemoteHumanoid(humanoids, humanoidId);

            if (remoteHumanoid != null)
            {
                // This remote humanoid already exists
                return;
            }

            humanoids.Add(HumanoidNetworking.StartHumanoid(nwId, humanoidId, name, avatarPrefabName, position, rotation, physics));
        }
 public void Awake()
 {
     DontDestroyOnLoad(this);
     HumanoidNetworking.Start(debug, syncFingerSwing);
 }