using System; using System.Collections.Generic; using Rukhanka.Toolbox; using Rukhanka.WaybackMachine; using Unity.Assertions; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Mathematics; using UnityEditor; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace Rukhanka.Editor { public partial class WaybackMachineWindow: EditorWindow { [SerializeField] private VisualTreeAsset windowAsset = default; [SerializeField] private VisualTreeAsset leftPaneAsset = default; [SerializeField] private VisualTreeAsset rightPaneAsset = default; [SerializeField] private VisualTreeAsset stateInfoAsset = default; [SerializeField] private VisualTreeAsset eventInfoAsset = default; [SerializeField] private VisualTreeAsset animInfoAsset = default; TwoPaneSplitView splitView; MinMaxSlider minMaxSlider; TimelineHeader timelineHeader; TimelineContent timelineContent; NativeReference timelinePortal; VisualElement recordBtn; ToolbarBreadcrumbs entityPath; ToolbarButton entityPathWorld, entityPathEntity; ToolbarButton globalSettingsButton; ToolbarButton previewBtn; Label memoryStat; ToolbarButton saveBtn; VisualElement leftPane, rightPane; Label statesHeader; VisualElement statesBarBodyVE; Button stateSettingsButton; Label animationsHeader; VisualElement animBarBodyVE; Button animationSettingsButton; Label eventsHeader; VisualElement eventsBarBodyVE; Button eventSettingsButton; List stateInfoWidgets = new (); List eventInfoWidgets = new (); List animInfoWidgets = new (); int selectedWorldIndex = -1; Entity selectedEntity = Entity.Null; Action playModeChangeFn; NativeReference recordedData; EntityQuery recordSingletonEq, playbackSingletonEq, animationDatabaseSingletonEq; int prevKnobFrame = 1000000; WaybackMachineSettings settings; public const string iconPath = "Packages/com.rukhanka.animation/Rukhanka.Editor/Editor Default Resources/Icons/RukhankaWaybackMachine@16.png"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [MenuItem("Window/Rukhanka Animation/Animation Wayback Machine")] public static void ShowExample() { var wnd = GetWindow(); var icon = AssetDatabase.LoadAssetAtPath(iconPath, typeof(Texture)) as Texture; wnd.titleContent = new GUIContent("Rukhanka Wayback Machine", icon); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SetupIconImage(Button button, Background img) { #if !UNITY_2023_2_OR_NEWER var icon = button.Q(); if(icon == null) button.Add(icon = new Image() {name = "LegacyIcon" }); icon.image = img.texture; #else button.iconImage = img; #endif } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public unsafe void CreateGUI() { playModeChangeFn = (playModeStateChange) => { PlayModeStateChanged(this); }; EditorApplication.playModeStateChanged += playModeChangeFn; settings = WaybackMachineSettings.MakeDefault(); recordedData = new (Allocator.Persistent); recordedData.GetUnsafePtr()->Construct(); timelinePortal = new (Allocator.Persistent); timelinePortal.GetUnsafePtr()->Construct(); // Each editor window contains a root VisualElement object var root = rootVisualElement; var doc = windowAsset.Instantiate(); root.Add(doc); splitView = new TwoPaneSplitView(0, 250, TwoPaneSplitViewOrientation.Horizontal); splitView.RegisterCallback(OnGeometryChange); root.Add(splitView); leftPane = leftPaneAsset.Instantiate(); rightPane = rightPaneAsset.Instantiate(); splitView.Add(leftPane); splitView.Add(rightPane); var tlh = rightPane.Q("timeline"); timelineHeader = new TimelineHeader(); timelineHeader.timelinePortal = timelinePortal; tlh.Add(timelineHeader); var gearIconBackground = new Background() { texture = (Texture2D)EditorGUIUtility.IconContent("_Popup").image }; animBarBodyVE = leftPane.Q("animbody"); animationsHeader = leftPane.Q