diff --git a/Assets/ProgrammedMovements/Editor/ProgrammedMovementsSetup.cs b/Assets/ProgrammedMovements/Editor/ProgrammedMovementsSetup.cs deleted file mode 100644 index 6051b73..0000000 --- a/Assets/ProgrammedMovements/Editor/ProgrammedMovementsSetup.cs +++ /dev/null @@ -1,579 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using UnityEditor; -using TMPro; -using UnityEditor.SceneManagement; - -/// -/// Editor menu to build ProgrammedMovements UI hierarchy in the scene. -/// Run once via Tools > ProgrammedMovements > Setup UI Hierarchy. -/// The hierarchy is created in the scene (not at runtime) so you can modify it. -/// -public static class ProgrammedMovementsSetup -{ - [InitializeOnLoadMethod] - static void OnLoad() - { - EditorSceneManager.sceneOpened += (scene, mode) => - { - if (Application.isPlaying) return; - var pmView = GameObject.Find("Views")?.transform?.Find("ProgrammedMovementsView"); - if (pmView == null) return; - var canvas = pmView.Find("ProgrammedMovementsCanvas"); - if (canvas == null) - { - SetupHierarchy(); - EditorSceneManager.MarkSceneDirty(scene); - return; - } - var banner = canvas.Find("TimelineBanner"); - if (banner != null && banner.Find("ConfigView") == null && banner.Find("TracksContainer") != null) - { - MigrateToNewLayout(); - EditorSceneManager.MarkSceneDirty(scene); - } - }; - } - const int TracksCount = 3; - const int TimelineDurationSeconds = 10; - - [MenuItem("Tools/ProgrammedMovements/Setup UI Hierarchy")] - public static void SetupHierarchy() - { - var pmView = GameObject.Find("Views")?.transform?.Find("ProgrammedMovementsView"); - if (pmView == null) - { - Debug.LogError("[ProgrammedMovementsSetup] Views/ProgrammedMovementsView not found."); - return; - } - - var existing = pmView.Find("ProgrammedMovementsCanvas"); - if (existing != null) - { - Debug.Log("[ProgrammedMovementsSetup] Hierarchy already exists. Use Tools > ProgrammedMovements > Force Rebuild UI to replace."); - return; - } - DoSetup(pmView); - } - - [MenuItem("Tools/ProgrammedMovements/Force Rebuild UI")] - public static void ForceRebuildHierarchy() - { - var pmView = GameObject.Find("Views")?.transform?.Find("ProgrammedMovementsView"); - if (pmView == null) - { - Debug.LogError("[ProgrammedMovementsSetup] Views/ProgrammedMovementsView not found."); - return; - } - var existing = pmView.Find("ProgrammedMovementsCanvas"); - if (existing != null) - { - Object.DestroyImmediate(existing.gameObject); - } - DoSetup(pmView); - } - - [MenuItem("Tools/ProgrammedMovements/Migrate to New Layout (add Config panel)")] - public static void MigrateToNewLayout() - { - var pmView = GameObject.Find("Views")?.transform?.Find("ProgrammedMovementsView"); - if (pmView == null) - { - Debug.LogError("[ProgrammedMovementsSetup] Views/ProgrammedMovementsView not found."); - return; - } - var canvas = pmView.Find("ProgrammedMovementsCanvas"); - if (canvas == null) - { - Debug.Log("[ProgrammedMovementsSetup] No canvas found. Run Setup UI Hierarchy first."); - return; - } - var banner = canvas.Find("TimelineBanner"); - if (banner == null) - { - Debug.LogError("[ProgrammedMovementsSetup] TimelineBanner not found."); - return; - } - if (banner.Find("ConfigView") != null) - { - Debug.Log("[ProgrammedMovementsSetup] Already has ConfigView. No migration needed."); - return; - } - var bannerRect = banner.GetComponent(); - if (bannerRect == null) - { - Debug.LogError("[ProgrammedMovementsSetup] TimelineBanner has no RectTransform."); - return; - } - - Transform timeLabels = banner.Find("TimeLabels"); - Transform verticalLines = banner.Find("VerticalLines"); - Transform tracksContainer = banner.Find("TracksContainer"); - var timelineViewExisting = banner.Find("TimelineView"); - if (timeLabels == null && timelineViewExisting != null) - { - timeLabels = timelineViewExisting.Find("TimeLabels"); - verticalLines = timelineViewExisting.Find("VerticalLines"); - tracksContainer = timelineViewExisting.Find("TracksContainer"); - } - if (timeLabels == null || verticalLines == null || tracksContainer == null) - { - Debug.LogError("[ProgrammedMovementsSetup] Old structure not found. Use Force Rebuild UI."); - return; - } - - GameObject timelineViewGO; - if (timelineViewExisting != null) - { - timelineViewGO = timelineViewExisting.gameObject; - } - else - { - timelineViewGO = new GameObject("TimelineView"); - Undo.RegisterCreatedObjectUndo(timelineViewGO, "Migrate PM"); - timelineViewGO.transform.SetParent(banner, false); - var tr = timelineViewGO.AddComponent(); - tr.anchorMin = Vector2.zero; - tr.anchorMax = Vector2.one; - tr.offsetMin = Vector2.zero; - tr.offsetMax = Vector2.zero; - Undo.SetTransformParent(timeLabels, timelineViewGO.transform, "Migrate PM"); - Undo.SetTransformParent(verticalLines, timelineViewGO.transform, "Migrate PM"); - Undo.SetTransformParent(tracksContainer, timelineViewGO.transform, "Migrate PM"); - } - - var configViewGO = new GameObject("ConfigView"); - Undo.RegisterCreatedObjectUndo(configViewGO, "Migrate PM"); - configViewGO.transform.SetParent(banner, false); - configViewGO.SetActive(false); - var configViewRect = configViewGO.AddComponent(); - configViewRect.anchorMin = Vector2.zero; - configViewRect.anchorMax = Vector2.one; - configViewRect.offsetMin = Vector2.zero; - configViewRect.offsetMax = Vector2.zero; - - var configContent = new GameObject("ConfigContent"); - configContent.transform.SetParent(configViewRect, false); - var configContentRect = configContent.AddComponent(); - configContentRect.anchorMin = Vector2.zero; - configContentRect.anchorMax = Vector2.one; - configContentRect.offsetMin = new Vector2(12, 8); - configContentRect.offsetMax = new Vector2(-12, -8); - - var configVertical = configContent.AddComponent(); - configVertical.spacing = 8; - configVertical.padding = new RectOffset(8, 8, 8, 8); - configVertical.childAlignment = TextAnchor.MiddleLeft; - configVertical.childControlWidth = true; - configVertical.childControlHeight = true; - configVertical.childForceExpandWidth = true; - configVertical.childForceExpandHeight = false; - - var row1 = CreateConfigRow1(configContent.transform); - var row2 = CreateConfigRow2(configContent.transform); - - var tracksRect = tracksContainer.GetComponent(); - if (tracksRect == null) - { - Debug.LogError("[ProgrammedMovementsSetup] TracksContainer has no RectTransform."); - return; - } - for (int t = 0; t < TracksCount; t++) - { - if (t >= tracksRect.childCount) break; - var track = tracksRect.GetChild(t); - if (track == null) continue; - var blocks = track.Find("Blocks"); - if (blocks != null) - { - if (blocks.GetComponent() == null) - { - var img = blocks.gameObject.AddComponent(); - img.color = new Color(0, 0, 0, 0); - } - if (blocks.GetComponent() == null) - blocks.gameObject.AddComponent(); - } - } - - EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); - Debug.Log("[ProgrammedMovementsSetup] Migrated to new layout. Save the scene. Enter Play mode to see Config panel when adding/editing blocks."); - } - - static void DoSetup(Transform pmView) - { - var canvasGO = new GameObject("ProgrammedMovementsCanvas"); - Undo.RegisterCreatedObjectUndo(canvasGO, "Create PM Canvas"); - canvasGO.transform.SetParent(pmView, false); - - var canvasRect = canvasGO.AddComponent(); - canvasRect.anchorMin = Vector2.zero; - canvasRect.anchorMax = Vector2.one; - canvasRect.offsetMin = Vector2.zero; - canvasRect.offsetMax = Vector2.zero; - - canvasGO.AddComponent().renderMode = RenderMode.ScreenSpaceOverlay; - canvasGO.GetComponent().sortingOrder = 2; - var scaler = canvasGO.AddComponent(); - scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; - scaler.referenceResolution = new Vector2(800, 600); - canvasGO.AddComponent(); - - float bannerHeight = 100f; - float runButtonHeight = 36f; - - var runGO = CreateButton(canvasRect, "Run", 16); - runGO.name = "RunButton"; - var runRect = runGO.GetComponent(); - runRect.anchorMin = new Vector2(0, 0); - runRect.anchorMax = new Vector2(0, 0); - runRect.pivot = new Vector2(0, 0); - runRect.anchoredPosition = new Vector2(12, bannerHeight + 8); - runRect.sizeDelta = new Vector2(80, runButtonHeight); - - var bannerGO = new GameObject("TimelineBanner"); - Undo.RegisterCreatedObjectUndo(bannerGO, "Create PM Banner"); - bannerGO.transform.SetParent(canvasRect, false); - var bannerRect = bannerGO.AddComponent(); - bannerRect.anchorMin = new Vector2(0, 0); - bannerRect.anchorMax = new Vector2(1, 0); - bannerRect.pivot = new Vector2(0.5f, 0); - bannerRect.anchoredPosition = Vector2.zero; - bannerRect.sizeDelta = new Vector2(0, bannerHeight); - bannerGO.AddComponent().color = new Color(0.12f, 0.12f, 0.14f, 0.95f); - - var timelineViewGO = new GameObject("TimelineView"); - timelineViewGO.transform.SetParent(bannerRect, false); - var timelineViewRect = timelineViewGO.AddComponent(); - timelineViewRect.anchorMin = Vector2.zero; - timelineViewRect.anchorMax = Vector2.one; - timelineViewRect.offsetMin = Vector2.zero; - timelineViewRect.offsetMax = Vector2.zero; - - var configViewGO = new GameObject("ConfigView"); - configViewGO.transform.SetParent(bannerRect, false); - configViewGO.SetActive(false); - var configViewRect = configViewGO.AddComponent(); - configViewRect.anchorMin = Vector2.zero; - configViewRect.anchorMax = Vector2.one; - configViewRect.offsetMin = Vector2.zero; - configViewRect.offsetMax = Vector2.zero; - - var configContent = new GameObject("ConfigContent"); - configContent.transform.SetParent(configViewRect, false); - var configContentRect = configContent.AddComponent(); - configContentRect.anchorMin = Vector2.zero; - configContentRect.anchorMax = Vector2.one; - configContentRect.offsetMin = new Vector2(12, 8); - configContentRect.offsetMax = new Vector2(-12, -8); - - var configVertical = configContent.AddComponent(); - configVertical.spacing = 8; - configVertical.padding = new RectOffset(8, 8, 8, 8); - configVertical.childAlignment = TextAnchor.MiddleLeft; - configVertical.childControlWidth = true; - configVertical.childControlHeight = true; - configVertical.childForceExpandWidth = true; - configVertical.childForceExpandHeight = false; - - CreateConfigRow1(configContent.transform); - CreateConfigRow2(configContent.transform); - - var timeLabelsGO = new GameObject("TimeLabels"); - timeLabelsGO.transform.SetParent(timelineViewRect, false); - var timeLabelsRect = timeLabelsGO.AddComponent(); - timeLabelsRect.anchorMin = new Vector2(0, 1); - timeLabelsRect.anchorMax = new Vector2(1, 1); - timeLabelsRect.pivot = new Vector2(0.5f, 1); - timeLabelsRect.anchoredPosition = new Vector2(0, -8); - timeLabelsRect.sizeDelta = new Vector2(0, 20); - - for (int s = 0; s <= TimelineDurationSeconds; s++) - { - float x = (float)s / TimelineDurationSeconds; - var label = CreateText(timeLabelsRect.transform, $"{s}s", 12); - label.name = $"Label{s}s"; - var lr = label.GetComponent(); - lr.anchorMin = new Vector2(x, 0); - lr.anchorMax = new Vector2(x, 1); - lr.pivot = new Vector2(0.5f, 0.5f); - lr.anchoredPosition = Vector2.zero; - lr.sizeDelta = new Vector2(28, 0); - } - var linesGO = new GameObject("VerticalLines"); - linesGO.transform.SetParent(timelineViewRect, false); - var linesRect = linesGO.AddComponent(); - linesRect.anchorMin = new Vector2(0, 0); - linesRect.anchorMax = new Vector2(1, 1); - linesRect.offsetMin = new Vector2(4, 4); - linesRect.offsetMax = new Vector2(-4, -32); - for (int s = 0; s <= TimelineDurationSeconds; s++) - { - float x = (float)s / TimelineDurationSeconds; - var line = new GameObject($"Line{s}"); - line.transform.SetParent(linesRect, false); - var lineImg = line.AddComponent(); - lineImg.color = new Color(0.35f, 0.35f, 0.4f, 0.7f); - var lineRect = line.GetComponent(); - lineRect.anchorMin = new Vector2(x, 0); - lineRect.anchorMax = new Vector2(x, 1); - lineRect.pivot = new Vector2(0.5f, 0); - lineRect.anchoredPosition = Vector2.zero; - lineRect.sizeDelta = new Vector2(2, 0); - } - - var tracksGO = new GameObject("TracksContainer"); - tracksGO.transform.SetParent(timelineViewRect, false); - var tracksRect = tracksGO.AddComponent(); - tracksRect.anchorMin = new Vector2(0, 0); - tracksRect.anchorMax = new Vector2(1, 1); - tracksRect.offsetMin = new Vector2(4, 4); - tracksRect.offsetMax = new Vector2(-4, -32); - - for (int t = 0; t < TracksCount; t++) - { - var trackGO = new GameObject($"Track{t}"); - trackGO.transform.SetParent(tracksRect, false); - var tr = trackGO.AddComponent(); - tr.anchorMin = new Vector2(0, (float)(TracksCount - 1 - t) / TracksCount); - tr.anchorMax = new Vector2(1, (float)(TracksCount - t) / TracksCount); - tr.offsetMin = new Vector2(2, 2); - tr.offsetMax = new Vector2(-2, -2); - - var trackBg = trackGO.AddComponent(); - trackBg.color = new Color(0.18f, 0.18f, 0.2f, 0.9f); - - var blocksGO = new GameObject("Blocks"); - blocksGO.transform.SetParent(tr, false); - var blocksRect = blocksGO.AddComponent(); - blocksRect.anchorMin = Vector2.zero; - blocksRect.anchorMax = Vector2.one; - blocksRect.offsetMin = Vector2.zero; - blocksRect.offsetMax = Vector2.zero; // Full width so block coords (0-1) align with timeline seconds - blocksGO.AddComponent().color = new Color(0, 0, 0, 0); - blocksGO.AddComponent(); - - var addBtn = CreateButton(tr, "+"); - addBtn.name = "AddButton"; - var addRect = addBtn.GetComponent(); - addRect.anchorMin = new Vector2(1, 0); - addRect.anchorMax = new Vector2(1, 1); - addRect.pivot = new Vector2(1, 0.5f); - addRect.anchoredPosition = new Vector2(-4, 0); - addRect.sizeDelta = new Vector2(28, 0); - } - - var controller = pmView.GetComponentInChildren(true); - if (controller != null) - { - controller.timelineRoot = bannerRect; - controller.runButton = runGO.GetComponent