public override void OnInspectorGUI() { DrawDocumentationIcon(); serializedObject.Update(); EditorGUILayout.PropertyField(mode, new GUIContent("Mode")); if (!mode.hasMultipleDifferentValues) { if (mode.enumValueIndex == (int)TimelineMode.Local) { if (!serializedObject.isEditingMultipleObjects) { Timeline timeline = (Timeline)serializedObject.targetObject; LocalClock localClock = timeline.GetComponent <LocalClock>(); if (localClock == null || !localClock.enabled) { EditorGUILayout.HelpBox("A local timeline requires a local clock.", MessageType.Error); } } } else if (mode.enumValueIndex == (int)TimelineMode.Global) { TimekeeperEditor.GlobalClockKeyPopup("Global Clock", globalClockKey); if (!globalClockKey.hasMultipleDifferentValues && string.IsNullOrEmpty(globalClockKey.stringValue)) { EditorGUILayout.HelpBox("A global timeline requires a global clock reference.", MessageType.Error); } } else { EditorGUILayout.HelpBox("Unsupported timeline mode.", MessageType.Error); } } if (!serializedObject.isEditingMultipleObjects && Application.isPlaying) { Timeline timeline = (Timeline)serializedObject.targetObject; EditorGUILayout.LabelField("Computed Time Scale", timeline.timeScale.ToString("0.00")); EditorGUILayout.LabelField("Computed Time", timeline.time.ToString("0.00")); } serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { serializedObject.Update(); if (!serializedObject.isEditingMultipleObjects) { LocalClock clock = (LocalClock)serializedObject.targetObject; Timekeeper timekeeper = clock.GetComponent <Timekeeper>(); if (timekeeper != null) { EditorGUILayout.HelpBox("Only global clocks should be attached to the timekeeper.", MessageType.Error); } } base.OnInspectorGUI(); serializedObject.ApplyModifiedProperties(); }
protected virtual Clock FindClock() { if (mode == TimelineMode.Local) { LocalClock localClock = GetComponent <LocalClock>(); if (localClock == null) { throw new ChronosException(string.Format("Missing local clock.")); } return(localClock); } else if (mode == TimelineMode.Global) { GlobalClock oldGlobalClock = _clock as GlobalClock; if (oldGlobalClock != null) { oldGlobalClock.Unregister(this); } if (!Timekeeper.instance.HasClock(globalClockKey)) { throw new ChronosException(string.Format("Missing global clock: '{0}'.", globalClockKey)); } GlobalClock globalClock = Timekeeper.instance.Clock(globalClockKey); globalClock.Register(this); return(globalClock); } else { throw new ChronosException(string.Format("Unknown timeline mode: '{0}'.", mode)); } }
public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(mode, new GUIContent("Mode")); if (!mode.hasMultipleDifferentValues) { if (mode.enumValueIndex == (int)TimelineMode.Local) { if (!serializedObject.isEditingMultipleObjects) { Timeline timeline = (Timeline)serializedObject.targetObject; LocalClock localClock = timeline.GetComponent <LocalClock>(); if (localClock == null || !localClock.enabled) { EditorGUILayout.HelpBox("A local timeline requires a local clock.", MessageType.Error); } } } else if (mode.enumValueIndex == (int)TimelineMode.Global) { EditorGUILayout.PropertyField(globalClockKey, new GUIContent("Global Clock")); if (!globalClockKey.hasMultipleDifferentValues && string.IsNullOrEmpty(globalClockKey.stringValue)) { EditorGUILayout.HelpBox("A global timeline requires a global clock reference.", MessageType.Error); } } else { EditorGUILayout.HelpBox("Unsupported timeline mode.", MessageType.Error); } } EditorGUI.BeginDisabledGroup(Application.isPlaying); { EditorGUILayout.PropertyField(recordTransform, new GUIContent("Record Transform")); EditorGUILayout.PropertyField(recordingDuration, new GUIContent("Recording Duration")); EditorGUILayout.PropertyField(recordingInterval, new GUIContent("Recording Interval")); } EditorGUI.EndDisabledGroup(); float estimate = serializedObject.targetObjects.OfType <Timeline>().Select(t => t.EstimateMemoryUsage()).Sum() / 1024; string summary; if (!recordingDuration.hasMultipleDifferentValues && !recordingInterval.hasMultipleDifferentValues) { summary = string.Format("Rewind for up to {0:0.#} {1} at a {2:0.#} {3} per second precision.\n\nEstimated memory: {4} KiB.", recordingDuration.floatValue, recordingDuration.floatValue >= 2 ? "seconds" : "second", (1 / recordingInterval.floatValue), (1 / recordingInterval.floatValue) >= 2 ? "snapshots" : "snapshot", estimate); } else { summary = string.Format("Estimated memory: {0} KiB.", estimate); } EditorGUILayout.HelpBox(summary, MessageType.Info); if (!serializedObject.isEditingMultipleObjects && Application.isPlaying) { Timeline timeline = (Timeline)serializedObject.targetObject; EditorGUILayout.LabelField("Computed Time Scale", timeline.timeScale.ToString("0.00")); EditorGUILayout.LabelField("Computed Time", timeline.time.ToString("0.00")); } serializedObject.ApplyModifiedProperties(); }
public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(mode, new GUIContent("Mode")); if (!mode.hasMultipleDifferentValues) { if (mode.enumValueIndex == (int)TimelineMode.Local) { if (!serializedObject.isEditingMultipleObjects) { Timeline timeline = (Timeline)serializedObject.targetObject; LocalClock localClock = timeline.GetComponent <LocalClock>(); if (localClock == null || !localClock.enabled) { EditorGUILayout.HelpBox("A local timeline requires a local clock.", MessageType.Error); } } } else if (mode.enumValueIndex == (int)TimelineMode.Global) { EditorGUILayout.PropertyField(globalClockKey, new GUIContent("Global Clock")); if (!globalClockKey.hasMultipleDifferentValues && string.IsNullOrEmpty(globalClockKey.stringValue)) { EditorGUILayout.HelpBox("A global timeline requires a global clock reference.", MessageType.Error); } } else { EditorGUILayout.HelpBox("Unsupported timeline mode.", MessageType.Error); } } bool anyRewindable = serializedObject.targetObjects.OfType <Timeline>().Any(t => t.rewindable); EditorGUI.BeginDisabledGroup(Application.isPlaying); { EditorGUILayout.PropertyField(rewindable, new GUIContent("Rewindable")); if (anyRewindable) { EditorGUILayout.PropertyField(recordingDuration, new GUIContent("Recording Duration")); EditorGUILayout.PropertyField(recordingInterval, new GUIContent("Recording Interval")); } } EditorGUI.EndDisabledGroup(); if (anyRewindable) { float estimate = serializedObject.targetObjects.OfType <Timeline>().Select(t => t.EstimateMemoryUsage()).Sum() / 1024; string summary; if (!recordingDuration.hasMultipleDifferentValues && !recordingInterval.hasMultipleDifferentValues) { summary = string.Format("Rewind for up to {0:0.#} {1} at a {2:0.#} {3} per second precision.\n\nEstimated memory: {4} KiB.", recordingDuration.floatValue, recordingDuration.floatValue >= 2 ? "seconds" : "second", (1 / recordingInterval.floatValue), (1 / recordingInterval.floatValue) >= 2 ? "snapshots" : "snapshot", estimate); } else { summary = string.Format("Estimated memory: {0} KiB.", estimate); } EditorGUILayout.HelpBox(summary, MessageType.Info); } if (!serializedObject.isEditingMultipleObjects) { Timeline timeline = ((Timeline)serializedObject.targetObject); ParticleSystem particleSystem = timeline.GetComponent <ParticleSystem>(); if (particleSystem != null && timeline.rewindable) { if (particleSystem.main.simulationSpace == ParticleSystemSimulationSpace.World) { EditorGUILayout.HelpBox("World simulation is incompatible with rewindable particle systems.", MessageType.Warning); } bool sendCollisionMessage = false; // Unity API doesn't seem to provide a way to check this. if (sendCollisionMessage) { EditorGUILayout.HelpBox("Collision messages are incompatible with rewindable particle systems.", MessageType.Warning); } } } if (!serializedObject.isEditingMultipleObjects && Application.isPlaying) { Timeline timeline = (Timeline)serializedObject.targetObject; EditorGUILayout.LabelField("Computed Time Scale", timeline.timeScale.ToString("0.00")); EditorGUILayout.LabelField("Computed Time", timeline.time.ToString("0.00")); } serializedObject.ApplyModifiedProperties(); }