Example #1
0
        /// <summary>
        /// Called by the replay system when the object should be recorded.
        /// </summary>
        /// <param name="state">The state object to serialize the animator into</param>
        public override void OnReplaySerialize(ReplayState state)
        {
            // Check for animator
            if (observedAnimator == null)
            {
                return;
            }

            // Calcualte the number of layers we want to serialize
            int layerCount = (recordAllLayers == true) ? observedAnimator.layerCount : 1;

            //// Write the layer count
            state.Write(layerCount);

            // Serialize all layer info
            for (int i = 0; i < layerCount; i++)
            {
                // Get the current animator state
                AnimatorStateInfo info = observedAnimator.GetCurrentAnimatorStateInfo(i);

                // Get the normalized time
                float normalizedTime = info.normalizedTime;

                // Store the state information
                state.Write(info.fullPathHash);
                state.Write(normalizedTime);
            }
        }
Example #2
0
        /// <summary>
        /// Called by the replay system when the object should return to a previous state.
        /// </summary>
        /// <param name="state">The state object to deserialize the animator from</param>
        public override void OnReplayDeserialize(ReplayState state)
        {
            // Check for animator
            if (observedAnimator == null)
            {
                return;
            }

            // Read the number of layers
            int layerCount = state.Read32();

            // Check if we need to reallocate
            if (layerCount > animatorStates.Length)
            {
                animatorStates = new ReplayAnimatorState[layerCount];
            }

            // Read all layer information
            for (int i = 0; i < layerCount; i++)
            {
                // Update last values
                animatorStates[i].lastHash           = animatorStates[i].targetHash;
                animatorStates[i].lastNormalizedTime = animatorStates[i].targetNormalizedTime;

                // Deserialize animator values
                animatorStates[i].targetHash           = state.Read32();
                animatorStates[i].targetNormalizedTime = state.ReadFloat();
            }

            // Check for paused
            if (ReplayManager.IsPaused == true)
            {
                observedAnimator.speed = 0;
            }
        }
Example #3
0
        /// <summary>
        /// Deserializes all active <see cref="ReplayEvent"/> from the state and dispatches any events to the <see cref="OnReplayEvent(ReplayEvent)"/> handler.
        /// </summary>
        /// <param name="state">The <see cref="ReplayState"/> to read the variable data from</param>
        protected virtual void ReplayDeserializeEvents(ReplayState state)
        {
            // Read the event size
            short size = state.Read16();

            // Read all events
            for (int i = 0; i < size; i++)
            {
                // Create the event
                ReplayEvent evt = new ReplayEvent();

                // Read the event id
                evt.eventID = state.ReadByte();

                // Read the data size
                byte dataSize = state.ReadByte();

                // Read the event data
                evt.eventData = state.ReadState(dataSize);

                try
                {
                    // Trigger the event callback
                    OnReplayEvent(evt);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Deserializes all active <see cref="ReplayVariable"/> from the state.
        /// </summary>
        /// <param name="state">The <see cref="ReplayState"/> to read the variable data from</param>
        protected virtual void ReplayDeserializeVariables(ReplayState state)
        {
            // Get the size
            short size = state.Read16();

            // Read all variables
            for (int i = 0; i < size; i++)
            {
                bool matchedVariable = false;

                // Read the variable name hash
                int variableHash = state.Read32();

                // Check for matching variable
                foreach (ReplayVariable variable in replayVariables)
                {
                    // We have found a matching variable
                    if (variable.Name.GetHashCode() == variableHash)
                    {
                        // Deserialize the variable
                        variable.OnReplayDeserialize(state);
                        matchedVariable = true;

                        break;
                    }
                }

                // We failed to resolve the state - we cannot continue reading because the state contains invalid data
                if (matchedVariable == false)
                {
                    break;
                }
            }
        }
Example #5
0
 /// <summary>
 /// Write the entire contents of a <see cref="ReplayState"/> to this <see cref="ReplayState"/>.
 /// All bytes will be appended.
 /// </summary>
 /// <param name="other">The other state to append</param>
 public void Write(ReplayState other)
 {
     // Copy all bytes
     foreach (byte value in other.bytes)
     {
         Write(value);
     }
 }
Example #6
0
        /// <summary>
        /// Called by the replay system when this <see cref="ReplayObject"/> should deserialize its replay data.
        /// </summary>
        /// <param name="state">The <see cref="ReplayState"/> to deserialize the data from</param>
        public void OnReplayDeserialize(ReplayState state)
        {
            // Always read the prefab name
            state.ReadString();

            // Read all data
            while (state.EndRead == false)
            {
                // Read the id
                ReplayIdentity identity = state.ReadIdentity();

                // Read the size
                short size = state.Read16();

                // Mathc flag
                bool matchedData = false;

                // Check for matched id
                foreach (ReplayBehaviour behaviour in observedComponents)
                {
                    // Check for destroyed components
                    if (behaviour == null)
                    {
                        continue;
                    }

                    // Check for matching sub id
                    if (behaviour.Identity == identity)
                    {
                        // We have matched the data so we can now deserialize
                        behaviourState = state.ReadState(size);

                        // Deserialize the component
                        behaviour.OnReplayDeserialize(behaviourState);

                        // Set matched flags
                        matchedData = true;
                        break;
                    }
                }

                // Check for found data
                if (matchedData == false)
                {
                    // We need to consume the data to maintain the state
                    for (int i = 0; i < size; i++)
                    {
                        // Call read byte multiple times to save allocating an array
                        state.ReadByte();
                    }
                    Debug.LogWarning("Possible replay state corruption for replay object " + gameObject);
                }
            }
        }
        /// <summary>
        /// Called by the relay system when the object should return to a previous state.
        /// </summary>
        /// <param name="state">The state object to deserialize the transform from</param>
        public override void OnReplayDeserialize(ReplayState state)
        {
            // Update the last transform
            OnReplayReset();

            // Read the transform flags
            targetFlags = (ReplayTransformFlags)state.Read16();

            // Check for low precision mode
            if ((targetFlags & ReplayTransformFlags.LowPrecision) == 0)
            {
                // Read the position
                if ((targetFlags & ReplayTransformFlags.Position) != 0)
                {
                    targetPosition = state.ReadVec3();
                }

                // Read the rotation
                if ((targetFlags & ReplayTransformFlags.Rotation) != 0)
                {
                    targetRotation = state.ReadQuat();
                }

                // Read the scale
                if ((targetFlags & ReplayTransformFlags.Scale) != 0)
                {
                    targetScale = state.ReadVec3();
                }
            }
            else
            {
                // Read the position
                if ((targetFlags & ReplayTransformFlags.Position) != 0)
                {
                    targetPosition = state.ReadVec3LowPrecision();
                }

                // Read the rotation
                if ((targetFlags & ReplayTransformFlags.Rotation) != 0)
                {
                    targetRotation = state.ReadQuatLowPrecision();
                }

                // Read the scale
                if ((targetFlags & ReplayTransformFlags.Scale) != 0)
                {
                    targetScale = state.ReadVec3LowPrecision();
                }
            }
        }
Example #8
0
        public override void OnReplaySerialize(ReplayState state)
        {
            // Require particle system
            if (observedParticleSystem == null)
            {
                return;
            }

            // Check for playing particles system - Dont waste data when nothing is happening
            //if (particles.isPlaying == false)
            //    return;

            // Write particle time
            state.Write(observedParticleSystem.time);
        }
Example #9
0
        public override void OnReplayDeserialize(ReplayState state)
        {
            // Require particle system
            if (observedParticleSystem == null)
            {
                return;
            }

            // Save the last time
            lastTime = targetTime;

            // Read the target simulation time
            targetTime = state.ReadFloat();

            observedParticleSystem.Simulate(targetTime - lastTime, true, false);
        }
Example #10
0
        /// <summary>
        /// Push an event to the replay system for recording.
        /// </summary>
        /// <param name="eventID">The event id to uniquley identify the event type</param>
        /// <param name="state">The state data for the event or null if no state data is required</param>
        public void ReplayRecordEvent(byte eventID, ReplayState state = null)
        {
            // Create the replay event
            ReplayEvent evt = new ReplayEvent
            {
                eventID   = eventID,
                eventData = state,
            };

            // Check for null state
            if (evt.eventData == null)
            {
                evt.eventData = new ReplayState();
            }

            // Push to event queue
            replayEvents.Enqueue(evt);
        }
Example #11
0
        /// <summary>
        /// Serializes all active <see cref="ReplayVariable"/> to the state.
        /// </summary>
        /// <param name="state">The <see cref="ReplayState"/> to write the varaible data to</param>
        protected virtual void ReplaySerializeVariables(ReplayState state)
        {
            // Get size
            short size = (short)replayVariables.Length;

            // Write the size to the state
            state.Write(size);

            // Write all variables
            foreach (ReplayVariable variable in replayVariables)
            {
                // Write the hash code of the name so we can identify the data later
                state.Write(variable.Name.GetHashCode());

                // Write the variable to the state
                variable.OnReplaySerialize(state);
            }
        }
Example #12
0
        /// <summary>
        /// Called by the replay system when this <see cref="ReplayObject"/> should serialize its replay data.
        /// </summary>
        /// <param name="state">The <see cref="ReplayState"/> to serialize the data to</param>
        public void OnReplaySerialize(ReplayState state)
        {
            // Check for empty components
            if (observedComponents.Length == 0)
            {
                return;
            }

            // Always write the prefab name
            state.Write(prefabIdentity);

            // Serialize all components
            foreach (ReplayBehaviour behaviour in observedComponents)
            {
                // Check for destroyed components
                if (behaviour == null)
                {
                    continue;
                }

                // Clear the shared buffer
                behaviourState.Clear();

                // Serialzie the behaviour
                behaviour.OnReplaySerialize(behaviourState);

                // Check for no data - dont waste memory and time serializing nothing
                if (behaviourState.Size == 0)
                {
                    continue;
                }

                // Write the meta data
                state.Write(behaviour.Identity);
                state.Write((short)behaviourState.Size);

                state.Write(behaviourState);
            }
        }
Example #13
0
        /// <summary>
        /// Serializes all awaiting <see cref="ReplayEvent"/> to the state.
        /// </summary>
        /// <param name="state">The <see cref="ReplayState"/> to write the varaible data to</param>
        protected virtual void ReplaySerializeEvents(ReplayState state)
        {
            // Get the number of events
            short size = (short)replayEvents.Count;

            // Write the size to the state
            state.Write(size);

            // Write all events
            while (replayEvents.Count > 0)
            {
                // Get the next event
                ReplayEvent evt = replayEvents.Dequeue();

                // Write the event id
                state.Write(evt.eventID);

                // Write the size and event data
                state.Write((byte)evt.eventData.Size);
                state.Write(evt.eventData);
            }
        }
Example #14
0
        /// <summary>
        /// Called by the replay system when all replay state information should be serialized.
        /// </summary>
        /// <param name="state">The <see cref="ReplayState"/> to write the data to</param>
        public virtual void OnReplaySerialize(ReplayState state)
        {
#if UNITY_EDITOR
            // Serialize may be called by the editor in which case we will need to find variables on each call
            if (Application.isPlaying == false)
            {
                ReplayFindVariables();
            }
#endif

            ReplayBehaviourDataFlags flags = ReplayBehaviourDataFlags.None;

            // Generate the data flags so we can read the correct data back
            if (replayEvents.Count > 0)
            {
                flags |= ReplayBehaviourDataFlags.Events;
            }
            if (replayVariables.Length > 0)
            {
                flags |= ReplayBehaviourDataFlags.Variables;
            }

            // Always write the flag byte
            state.Write((byte)flags);

            // Serialize replay events
            if ((flags & ReplayBehaviourDataFlags.Events) != 0)
            {
                // Serialize all events
                ReplaySerializeEvents(state);
            }

            // Serialize all replay variables by default
            if ((flags & ReplayBehaviourDataFlags.Variables) != 0)
            {
                // Serialize all variables
                ReplaySerializeVariables(state);
            }
        }
Example #15
0
        /// <summary>
        /// Called by the replay system when all replay state information should be deserialized.
        /// </summary>
        /// <param name="state">The <see cref="ReplayState"/> to read the data from</param>
        public virtual void OnReplayDeserialize(ReplayState state)
        {
            // Check if we can read
            if (state.EndRead == true)
            {
                return;
            }

            // Get the flag byte
            ReplayBehaviourDataFlags flags = (ReplayBehaviourDataFlags)state.ReadByte();

            // Deserialize events if there are any
            if ((flags & ReplayBehaviourDataFlags.Events) != 0)
            {
                ReplayDeserializeEvents(state);
            }

            // Deserialize variables if there are any
            if ((flags & ReplayBehaviourDataFlags.Variables) != 0)
            {
                ReplayDeserializeVariables(state);
            }
        }
        /// <summary>
        /// Called by the replay system when the object should be recorded.
        /// </summary>
        /// <param name="state">The state object to serialize the transform into</param>
        public override void OnReplaySerialize(ReplayState state)
        {
            // Calcualte the flags
            ReplayTransformFlags flags = 0;

            // Build the flag information
            if (recordPosition != ReplayTransformRecordSpace.None)
            {
                flags |= ReplayTransformFlags.Position;

                if (recordPosition == ReplayTransformRecordSpace.Local)
                {
                    flags |= ReplayTransformFlags.LocalPosition;
                }
            }
            if (recordRotation != ReplayTransformRecordSpace.None)
            {
                flags |= ReplayTransformFlags.Rotation;

                if (recordRotation == ReplayTransformRecordSpace.Local)
                {
                    flags |= ReplayTransformFlags.LocalRotation;
                }
            }
            if (recordScale == true)
            {
                flags |= ReplayTransformFlags.Scale;
            }

            // Check for any flags
            if (flags == 0)
            {
                return;
            }

            // Check for low precision
            if (lowPrecision == true)
            {
                flags |= ReplayTransformFlags.LowPrecision;
            }

            // Write the flags
            state.Write((short)flags);

            // Check for low precision mode
            if (lowPrecision == false)
            {
                // Write the position
                if ((flags & ReplayTransformFlags.Position) != 0)
                {
                    if ((flags & ReplayTransformFlags.LocalPosition) != 0)
                    {
                        state.Write(transform.localPosition);
                    }
                    else
                    {
                        state.Write(transform.position);
                    }
                }

                // Write the rotation
                if ((flags & ReplayTransformFlags.Rotation) != 0)
                {
                    if ((flags & ReplayTransformFlags.LocalRotation) != 0)
                    {
                        state.Write(transform.localRotation);
                    }
                    else
                    {
                        state.Write(transform.rotation);
                    }
                }

                // Write the scale
                if ((flags & ReplayTransformFlags.Scale) != 0)
                {
                    state.Write(transform.localScale);
                }
            }
            else
            {
                // Write the position
                if ((flags & ReplayTransformFlags.Position) != 0)
                {
                    if ((flags & ReplayTransformFlags.LocalPosition) != 0)
                    {
                        state.WriteLowPrecision(transform.localPosition);
                    }
                    else
                    {
                        state.WriteLowPrecision(transform.position);
                    }
                }

                // Write the rotation
                if ((flags & ReplayTransformFlags.Rotation) != 0)
                {
                    if ((flags & ReplayTransformFlags.LocalRotation) != 0)
                    {
                        state.WriteLowPrecision(transform.localRotation);
                    }
                    else
                    {
                        state.WriteLowPrecision(transform.rotation);
                    }
                }

                // Write the scale
                if ((flags & ReplayTransformFlags.Scale) != 0)
                {
                    state.WriteLowPrecision(transform.localScale);
                }
            }
        }
Example #17
0
 /// <summary>
 /// Push an event to the replay system for recording.
 /// </summary>
 /// <param name="eventID">The event id to uniquley identify the event type</param>
 /// <param name="state">The state data for the event or null if no state data is required</param>
 public void ReplayRecordEvent(ReplayEvents eventID, ReplayState state = null)
 {
     // Call through
     ReplayRecordEvent((byte)eventID, state);
 }