예제 #1
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;
 }
예제 #2
0
        public override void OnAwake()
        {
            base.OnAwake();

            syncTransform = GetComponent <SyncTransform>();

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

            transform.GetNestedComponentsInChildren(onStateChangeCallbacks);
            transform.GetComponents(onTeleportCallbacks);

            mountsLookup = netObj.GetComponent <MountsLookup>();
        }
예제 #3
0
        /// <summary>
        /// Apply the vectors (offset, pos, rot, velocity) in StateChangeInfo to the syncState object. Returns true if teleport is required for change.
        /// </summary>
        public static void ApplyVectors(this SyncState syncState, StateChangeInfo stateChangeInfo, Transform prevParent, List <IOnTeleport> callbacks)
        {
            Transform transform = syncState.transform;

            /// For respawns just the pos/rot values are NET relative to he old parent.
            //if (stateChangeInfo.respawn)
            //{
            //	var mount = stateChangeInfo.mount;
            //	var localPos = stateChangeInfo.offsetPos;
            //	var localRot = stateChangeInfo.offsetRot;

            //	int cnt = callbacks.Count;
            //	for (int i = 0; i < cnt; i++)
            //		callbacks[i].OnTeleport();

            //	transform.parent = (mount) ? mount.transform : null;

            //	if (localPos.HasValue)
            //		transform.localPosition = localPos.Value;
            //	if (localRot.HasValue)
            //		transform.localEulerAngles = localRot.Value;

            //	return;
            //}
            //else
            //{
            //if (stateChangeInfo.offsetPos.HasValue)
            //{
            //	{
            //		var parRot = prevParent ? prevParent.rotation : transform.rotation;
            //		/// TODO: offset and vel likely should be part of the ChangeState itself
            //		/// Apply offset before changing state
            //		var localOffset = stateChangeInfo.offsetPos;

            //		//Debug.Log(Time.time + " " + transform.name + " Dequeue " + transform.position + " " + transform.position + prevParent.rotation * localOffset);
            //		//transform.position = transform.position + prevParent.rotation * localOffset.Value;

            //		Vector3? pos = localOffset.HasValue ? (transform.position + parRot * localOffset.Value) : (Vector3?)null;
            //		Vector3? rot = stateChangeInfo.offsetRot;

            //		//int cnt = callbacks.Count;
            //		//for (int i = 0; i < cnt; i++)
            //		//	callbacks[i].OnTeleport();

            //		transform.parent = null;
            //		if (pos.HasValue)
            //			transform.position = pos.Value;
            //		if (rot.HasValue)
            //			transform.eulerAngles = rot.Value;
            //	}
            //}
            //}

            if (stateChangeInfo.velocity.HasValue)
            {
                var rb = syncState.Rb;
                if (rb)
                {
                    if (!rb.isKinematic)
                    {
                        rb.velocity = ((prevParent) ? prevParent.rotation : rb.rotation) * stateChangeInfo.velocity.Value;
                    }
                }
                else
                {
                    var rb2d = syncState.Rb2d;
                    if (rb2d)
                    {
                        if (!rb2d.isKinematic)
                        {
                            rb2d.velocity = stateChangeInfo.velocity.Value;
                        }
                    }
                }
            }
        }
예제 #4
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 (IsMine)
            //	//if (GetComponent<SyncVitals>())
            //	{
            //		if (stateChangeInfo.objState == ObjState.Visible)
            //			Debug.Log(Time.time + " " + stateChangeInfo);
            //		else
            //			Debug.Log(Time.time + " <b>" + stateChangeInfo + "</b>");
            //	}

            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)
            {
                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)
            {
                return;
            }

            bool nowAttached = (newState & ObjState.Attached) != 0;

            /// Handling for attached without a valid Mount
            if (nowAttached && !newMount)
            {
                //Debug.LogError(name + " Attached with a null mount! " + newState);
                InvalidMountHandler(newState, newMount, force);
                return;
            }

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

            /// The State is attached
            /*else*/
            if (mountChanged)
            {
                /// Attaching to a mount
                // If Attached bit is true
                if (nowAttached)
                {
                    //Debug.Log(Time.time + " " + name + " ATTACH " + newMount.name + " ");
                    currentState.attachedToNetId       = newMount.NetObjId;
                    currentState.attachedToMountTypeId = newMount.mountType.id;

                    transform.parent = newMount.transform;

                    bool nowMounted = (newState & ObjState.Mounted) != 0;

                    // If Mounted bit is true
                    if (nowMounted)
                    {
                        //Debug.Log(name + " Hard Mounting Origin");
                        transform.localPosition = new Vector3();
                        transform.localRotation = new Quaternion();
                    }
                }

                /// Detaching from a mount
                else
                {
                    //Debug.Log(Time.time + " " + name + " DEATTACH ");

                    currentState.attachedToNetId       = null;
                    currentState.attachedToMountTypeId = null;
                    transform.parent = null;
                }

                Mount.ChangeMounting(this, newMount);
            }

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

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

                transform.localEulerAngles = rot.Value;
            }

            if (pos.HasValue)
            {
                if (respawn)
                {
                    transform.localPosition = pos.Value;
                }
                else
                {
                    var parRot = prevParent ? prevParent.rotation : transform.rotation;
                    transform.position = transform.position + parRot * pos.Value;
                }
            }

            if (vel.HasValue)
            {
                var rb = syncState.Rb;
                if (rb)
                {
                    if (!rb.isKinematic)
                    {
                        rb.velocity = ((prevParent) ? prevParent.rotation : rb.rotation) * vel.Value;
                    }
                }
                else
                {
                    var rb2d = syncState.Rb2d;
                    if (rb2d)
                    {
                        if (!rb2d.isKinematic)
                        {
                            rb2d.velocity = stateChangeInfo.velocity.Value;
                        }
                    }
                }
            }

            currentState.state = newState;
            currentMount       = newMount;


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

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