示例#1
0
        /// <summary>
        /// Attempts to restore any replay objects that were spawned or despawned during this snapshot.
        /// </summary>
        public void RestoreReplayObjects(ReplayScene scene, ReplayInitialDataBuffer initialStateBuffer)
        {
            // Get all active scene objects
            List <ReplayObject> activeReplayObjects = scene.ActiveReplayObjects;

            // Find all active replay objects
            foreach (ReplayObject obj in activeReplayObjects)
            {
                // Check if the object is no longer in the scene
                if (states.ContainsKey(obj.ReplayIdentity) == false)
                {
                    // Check for a prefab
                    if (obj.IsPrefab == false)
                    {
                        continue;
                    }

                    // We need to destroy the replay object
                    sharedDestroyQueue.Enqueue(obj);
                }
            }

            // Destroy all waiting objects
            while (sharedDestroyQueue.Count > 0)
            {
                ReplayManager.ReplayDestroy(sharedDestroyQueue.Dequeue().gameObject);
            }

            // Process all snapshot state data to check if we need to add any scene objects
            foreach (KeyValuePair <ReplayIdentity, ReplayState> replayObject in states)
            {
                bool found = false;

                // Check if the desiered object is active in the scene
                foreach (ReplayObject obj in activeReplayObjects)
                {
                    // Check for matching identity
                    if (obj.ReplayIdentity == replayObject.Key)
                    {
                        // The object is in the scene - do nothing
                        found = true;
                        break;
                    }
                }

                // We need to spawn the object
                if (found == false)
                {
                    // Get the replay state for the object because it contains the prefab information we need
                    ReplayState state = replayObject.Value;

                    // Reset the state for reading
                    state.PrepareForRead();

                    // Read the name of the prefab that we need to spawn
                    string name = state.ReadString();

                    // Try to find the matching prefab in our replay manager
                    GameObject prefab = ReplayManager.FindReplayPrefab(name);

                    // Check if the prefab was found
                    if (prefab == null)
                    {
                        // Check for no prefab name
                        if (string.IsNullOrEmpty(name) == true)
                        {
                            // Name information is unknown
                            name = "Unkwnown Replay Object (" + replayObject.Key + ")";

                            // Display scene object warning
                            Debug.LogWarning(string.Format("Failed to recreate replay scene object '{0}'. The object could not be found within the current scene and it is not a registered replay prefab. You may need to reload the scene before playback to ensure that all recorded objects are present.", name));
                        }
                        else
                        {
                            // Display prefab object warning
                            Debug.LogWarning(string.Format("Failed to recreate replay prefab '{0}'. No such prefab is registered.", name));
                        }
                        continue;
                    }

                    // Restore initial data
                    ReplayInitialData initialData = new ReplayInitialData();

                    // Check for valid state buffer
                    if (initialStateBuffer != null && initialStateBuffer.HasInitialReplayObjectData(replayObject.Key) == true)
                    {
                        // Restore the objects state data
                        initialData = initialStateBuffer.RestoreInitialReplayObjectData(replayObject.Key, timeStamp);//  RestoreInitialReplayObjectData(replayObject.Key);
                    }

                    Vector3    position = Vector3.zero;
                    Quaternion rotation = Quaternion.identity;
                    Vector3    scale    = Vector3.one;

                    // Update transform values
                    if ((initialData.InitialFlags & ReplayInitialDataFlags.Position) != 0)
                    {
                        position = initialData.position;
                    }
                    if ((initialData.InitialFlags & ReplayInitialDataFlags.Rotation) != 0)
                    {
                        rotation = initialData.rotation;
                    }
                    if ((initialData.InitialFlags & ReplayInitialDataFlags.Scale) != 0)
                    {
                        scale = initialData.scale;
                    }

                    // Call the instantiate method
                    GameObject result = ReplayManager.ReplayInstantiate(prefab, position, rotation);

                    if (result == null)
                    {
                        Debug.LogWarning(string.Format("Replay instanitate failed for prefab '{0}'. Some replay objects may be missing", name));
                        continue;
                    }

                    // Be sure to apply initial scale also
                    result.transform.localScale = scale;

                    // try to find the replay object script
                    ReplayObject obj = result.GetComponent <ReplayObject>();

                    // Check if we have the component
                    if (obj != null)
                    {
                        // Give the replay object its serialized identity so that we can send replay data to it
                        obj.ReplayIdentity = replayObject.Key;

                        // Map observed component identities
                        if (initialData.observedComponentIdentities != null)
                        {
                            int index = 0;

                            foreach (ReplayBehaviour behaviour in obj.ObservedComponents)
                            {
                                if (initialData.observedComponentIdentities.Length > index)
                                {
                                    behaviour.Identity = initialData.observedComponentIdentities[index];
                                }
                                index++;
                            }
                        }

                        // Register the created object
                        newReplayObjectsThisFrame.Add(new ReplayCreatedObject
                        {
                            replayObject      = obj,
                            replayInitialData = initialData,
                        });

                        // Trigger spawned event
                        ReplayBehaviour.Events.CallReplaySpawnedEvents(obj, position, rotation);
                    }
                }
            }


            // Re-parent replay objects
            foreach (ReplayCreatedObject created in newReplayObjectsThisFrame)
            {
                // Check for a parent identity
                if (created.replayInitialData.parentIdentity != null)
                {
                    bool foundTargetParent = false;

                    // We need to find the references parent
                    foreach (ReplayObject obj in scene.ActiveReplayObjects)
                    {
                        if (obj.ReplayIdentity == created.replayInitialData.parentIdentity)
                        {
                            // Parent the objects
                            created.replayObject.transform.SetParent(obj.transform, false);

                            // Set the flag
                            foundTargetParent = true;
                            break;
                        }
                    }

                    // Check if we failed to find the parent object
                    if (foundTargetParent == false)
                    {
                        // The target parent object is missing
                        Debug.LogWarning(string.Format("Newly created replay object '{0}' references identity '{1}' as a transform parent but the object could not be found in the current scene. Has the target parent been deleted this frame?", created.replayObject.name, created.replayInitialData.parentIdentity));
                    }
                }
            }

            // Clear ll tracked replay objects this frame
            newReplayObjectsThisFrame.Clear();
        }