示例#1
0
        public override void OnStart()
        {
            /// TEST - this code fixed startup rendering, but not fully tested. Likely needs to stay here.
            ChangeState(new StateChangeInfo(initialState, transform.parent ? transform.parent.GetComponent <Mount>() : null, true));

            base.OnStart();

            respawnStateInfo = new StateChangeInfo(
                respawnState,
                transform.parent ? transform.parent.GetComponent <Mount>() : null,
                transform.localPosition,
                transform.localRotation,
                null, true);

            /// Cache values for mountType serialization. We get the total possible mount options from this objects SyncState
            var mountableToCount = (mountableTo.mask).CountTrueBits(out indexToMountTypeId, MountSettings.mountTypeCount);

            bitsForMountType = mountableToCount.GetBitsForMaxValue();

            for (int i = 0; i < mountableToCount; ++i)
            {
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                if (mountTypeIdToIndex.ContainsKey(indexToMountTypeId[i]))
                {
                    Debug.LogError(name + " " + photonView.OwnerActorNr + " Mount Key Exists: " + indexToMountTypeId[i] + " i:" + i + " count: " + mountableToCount);
                }
#endif

                mountTypeIdToIndex.Add(indexToMountTypeId[i], i);
            }
        }
示例#2
0
 public StateChangeInfo(StateChangeInfo src)
 {
     this.objState  = src.objState;
     this.mount     = src.mount;
     this.offsetPos = src.offsetPos;
     this.offsetRot = src.offsetRot;
     this.velocity  = src.velocity;
     this.force     = src.force;
 }
示例#3
0
        /// <summary>
        /// Call this method to change the state of this object. This state will be synced over the network,
        /// and callbacks will trigger locally and remotely. Typically it is preferred to call QueueStateChange(),
        /// which will defer the ChangeState application until the appropriate timing.
        /// </summary>
        protected virtual void ChangeState(StateChangeInfo stateChangeInfo)
        {
            if (!gameObject)
            {
                Debug.LogWarning(name + " has been destroyed. Will not try to change state.");
                return;
            }

            //if (photonView.IsMine && iSpawnController != null && iSpawnController.SupressStateMask != ~ObjState.Despawned)
            //{
            //    Debug.Log("<color=red>Suppressing State change due to spawn timer</color>");
            //    stateChangeInfo.objState &= iSpawnController.SupressStateMask;
            //}


            //if (GetComponent<SyncPickup>())
            //    Debug.LogError(Time.time + " " + name + " <b>ChangeState " + stateChangeInfo + "</b> par: " + currentMount + " tr: " + transform.position + " rb: " + Rb.position);

            var oldState = currentState.state;
            var oldMount = currentMount;
            var newState = stateChangeInfo.objState;
            var newMount = stateChangeInfo.mount;

            bool respawn;

            /// Assuming first Visible after a despawn is a Respawn - this is here to handle lost teleport packets
            if (autoReset && oldState == ObjState.Despawned && newState != ObjState.Despawned && (newState & ObjState.Anchored) == 0)
            {
                stateChangeInfo = new StateChangeInfo(respawnStateInfo)
                {
                    objState = stateChangeInfo.objState
                };
                respawn = true;
            }
            else
            {
                respawn = false;
            }

            var force = stateChangeInfo.force;

            bool stateChanged = newState != oldState;
            bool mountChanged = oldMount != newMount;

            var prevParent = transform.parent;


            /// Test nothing has changed
            if (!force && !stateChanged && !mountChanged)
            {
                //if (GetComponent<SyncPickup>())
                //    Debug.LogError("NO CHANGE");
                return;
            }


            currentState.state = newState;
            var prevMount = currentMount;

            currentMount = newMount;

            //if (GetComponent<SyncPickup>())
            //    Debug.LogError("<b>ChangeState </b>" + currentState + " par: " + currentMount);

            bool nowMounted         = (newState & ObjState.Mounted) != 0;
            bool mountInfoWasCulled = nowMounted && ReferenceEquals(newMount, null);

            // TODO: Might not be needed.
            /// Handling for attached without a valid Mount - Test for if we have a reference to a Mount, but it is null (Unity destroyed). Sets to hard null and reruns this method.
            if (nowMounted && !mountInfoWasCulled && newMount == null)
            {
                Debug.LogError("Invalid Mount!");
                InvalidMountHandler(newState, newMount, force);
                return;
            }

            if (IsMine)
            {
                if (mountChanged || respawn)
                {
                    //Debug.LogError("TELEPORT");
                    for (int i = 0; i < flagTeleportCallbacks.Count; ++i)
                    {
                        flagTeleportCallbacks[i].FlagTeleport();
                    }
                }
            }

            /// The State is mounted
            /*else*/
            if (mountChanged)
            {
                /// Attaching to a mount
                // If Attached bit is true
                if (nowMounted)
                {
#if PUN_2_OR_NEWER
                    //if (GetComponent<SyncPickup>() /*&& newState == (ObjState)(15)*/)
                    //    Debug.LogError(Time.time + " " + name + " " + newState + " ATTACH " + newMount.name + " ");

                    currentState.mountToViewID = newMount.ViewID;
                    currentState.mountTypeId   = newMount.mountType.id;
#endif
                    transform.parent = newMount.transform;

                    // If anchor bit is true
                    if ((newState & ObjState.AnchoredPosition) != 0)
                    {
                        transform.localPosition = new Vector3();
                        //Debug.LogError("<b>Anchor Pos</b> " + transform.parent.name + " " + transform.localPosition);
                    }

                    // If anchor bit is true
                    if ((newState & ObjState.AnchoredRotation) != 0)
                    {
                        transform.localRotation = new Quaternion();
                        //Debug.Log("<b>Anchor Rot</b>");
                    }
                }

                /// Detaching from a mount
                else
                {
                    //if (GetComponent<SyncPickup>() /*&& newState == (ObjState)(15)*/)
                    //    Debug.Log(Time.time + " " + name + " " + newState + " DETTACH " + (newMount ? newMount.name : " null"));

                    currentState.mountToViewID = null;
                    currentState.mountTypeId   = null;
                    transform.parent           = null;
                }

                // TODO: Add handling for dismounting returning ownership to scene?
                // Ownership changes are deferred, to let the current tick finish processing before changing Owner/Controller.
                if (autoOwnerChange && newMount && !ReferenceEquals(oldMount, newMount))
                {
                    ChangeOwnerToParentMountsOwner();
                }
                Mount.ChangeMounting(this, prevMount, newMount);
            }

            var pos = stateChangeInfo.offsetPos;
            var rot = stateChangeInfo.offsetRot;
            var vel = stateChangeInfo.velocity;

            if (rot.HasValue)
            {
                //if (GetComponent<SyncPickup>())
                //    Debug.Log(Time.time + " " + name + " STATE ROT APPLY " + rot.Value);

                transform.rotation = rot.Value;
            }

            // TODO: Move pos/rot handling to virtual method
            if (pos.HasValue)
            {
                //if (GetComponent<SyncPickup>())
                //    Debug.Log(Time.time + " " + name + " STATE POS APPLY " + pos.Value);

                transform.position = pos.Value;
            }

            if (vel.HasValue)
            {
                var rb = netObj.Rb;
                if (rb)
                {
                    rb.velocity = vel.Value;
                }
                else
                {
                    var rb2d = netObj.Rb2D;

                    if (rb2d)
                    {
                        rb2d.velocity = vel.Value;
                    }
                }
            }

            ///// Apply the vector values
            //this.ApplyVectors(stateChangeInfo, prevParent, onTeleportCallbacks);

            //Debug.Log(Time.time + " " + stateChangeInfo + " mountisactive? " + (currentMount ? currentMount.isActiveAndEnabled.ToString() : "null"));

            if (mountChanged || stateChanged || force)
            {
                //if (GetComponent<SyncPickup>())
                //    Debug.Log(Time.time + " " + name +  " " + photonView.OwnerActorNr + " <b>NEW STATE: " + newState + "</b> ready? " + netObj.AllObjsAreReady);

                /// Send out callbacks
                for (int i = 0; i < onStateChangeCallbacks.Count; ++i)
                {
                    onStateChangeCallbacks[i].OnStateChange(newState, oldState, transform, currentMount, netObjIsReady);
                }
            }
        }