Last active
September 30, 2024 11:37
Revisions
-
restush revised this gist
Sep 30, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -87,7 +87,7 @@ private void CreateGUI() showAlternatingRowBackgrounds = AlternatingRowBackground.All, reorderable = true, reorderMode = ListViewReorderMode.Animated, makeNoneElement = () => new VisualElement() }; pinnedView.style.unityTextAlign = TextAnchor.MiddleCenter; -
restush revised this gist
Sep 30, 2024 . 1 changed file with 20 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -145,7 +145,26 @@ private void CreateGUI() void Bind(VisualElement v, int index, bool isPinnedList) { var i = index; var item = (HorizontalItemData)default; if(isPinnedList) { // check valid pinnedList index to prevent out of range if(pinnedList.Count > i) { item = pinnedList[i]; } } else { if (dataList.Count > i) { item = dataList[i]; } } if (item == null) return; var sceneButton = v.Q<Button>("SceneButton"); sceneButton.text = item.SceneName; -
restush revised this gist
Aug 24, 2024 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -73,7 +73,6 @@ static void CreateMenu() private void CreateGUI() { Load(); pinnedList = dataList.FindAll(x => x.Pinned); -
restush revised this gist
Aug 24, 2024 . 1 changed file with 14 additions and 13 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -66,12 +66,14 @@ static void CreateMenu() { var window = GetWindow<SceneListEditorWindow>(); window.titleContent = new GUIContent("Scene List & Pins"); window.Focus(); } private void CreateGUI() { Debug.Log("CreateGUI"); Load(); pinnedList = dataList.FindAll(x => x.Pinned); @@ -141,9 +143,9 @@ private void CreateGUI() } } void Bind(VisualElement v, int index, bool isPinnedList) { var i = index; var item = isPinnedList ? pinnedList[i] : dataList[i]; var sceneButton = v.Q<Button>("SceneButton"); sceneButton.text = item.SceneName; @@ -183,8 +185,11 @@ void Bind(VisualElement v, int i, bool isPinnedList) ShowVisualElement(header); } pinnedView.RefreshItem(i); unpinnedView.RefreshItem(i); //pinnedView.Rebuild(); //unpinnedView.Rebuild(); Save(); @@ -199,6 +204,10 @@ void Bind(VisualElement v, int i, bool isPinnedList) private void Load() { // clear to prevent duplicate dataList.Clear(); pinnedList.Clear(); var sceneAssets = FindAssetsOfType<SceneAsset>(); string currentFilePath = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this)); @@ -340,13 +349,5 @@ private T[] FindAssetsOfType<T>() where T : UnityEngine.Object } return list.ToArray(); } } -
restush revised this gist
Aug 23, 2024 . 1 changed file with 13 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -95,9 +95,6 @@ private void CreateGUI() // callback on reorder pinnedView.itemIndexChanged += (oldIndex, newIndex) => { Save(); }; pinnedView.selectionType = SelectionType.None; @@ -112,9 +109,6 @@ private void CreateGUI() , }; unpinnedView.selectionType = SelectionType.None; unpinnedView.style.flexGrow = 1; @@ -320,6 +314,11 @@ private void UnsubscribeToButton(Button button) private void Save() { StateData stateData = new StateData(); for (int i = 0; i < pinnedList.Count; i++) { pinnedList[i].PinnedIndex = i; } stateData.pinnedList = pinnedList; string json = JsonUtility.ToJson(stateData); File.WriteAllText(jsonFilePath, json); @@ -342,4 +341,12 @@ private T[] FindAssetsOfType<T>() where T : UnityEngine.Object return list.ToArray(); } private void OnProjectChange() { dataList.Clear(); pinnedList.Clear(); rootVisualElement.Clear(); CreateGUI(); } } -
restush revised this gist
Aug 23, 2024 . 2 changed files with 214 additions and 193 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,5 @@ /// https://gist.github.com/restush/849b5662dd82b7eb68ee78950e1a8033 using System.Collections.Generic; using System.IO; using System.Linq; @@ -11,13 +12,36 @@ public class SceneListEditorWindow : EditorWindow { private class UserData { public Dictionary<string, System.Action> _callbacks = new(); public void AddCallback(string key, System.Action callback) { if (_callbacks.ContainsKey(key)) _callbacks[key] = callback; else _callbacks.Add(key, callback); } public void RemoveCallback(string key, Button button) { if (_callbacks.ContainsKey(key)) { button.clicked -= _callbacks[key]; _callbacks.Remove(key); } } } [System.Serializable] private class HorizontalItemData { public string SceneName; public string GUID; public bool Pinned; public int PinnedIndex; } private List<HorizontalItemData> dataList = new(); @@ -44,139 +68,21 @@ static void CreateMenu() window.titleContent = new GUIContent("Scene List & Pins"); } private void CreateGUI() { Load(); pinnedList = dataList.FindAll(x => x.Pinned); dataList.RemoveAll(x => x.Pinned); pinnedList = pinnedList.OrderBy(x => x.PinnedIndex).ToList(); pinnedView = new ListView() { itemsSource = pinnedList, makeItem = () => CreateItem(), bindItem = (v, i) => Bind(v, i, true), showAlternatingRowBackgrounds = AlternatingRowBackground.All, reorderable = true, reorderMode = ListViewReorderMode.Animated, @@ -189,8 +95,10 @@ VisualElement CreateItem() // callback on reorder pinnedView.itemIndexChanged += (oldIndex, newIndex) => { pinnedList[newIndex].PinnedIndex = newIndex; pinnedList[oldIndex].PinnedIndex = oldIndex; Save(); }; pinnedView.selectionType = SelectionType.None; @@ -200,55 +108,12 @@ VisualElement CreateItem() itemsSource = dataList, makeItem = () => CreateItem(), bindItem = (v, i) => Bind(v, i, false) , }; unpinnedView.selectionType = SelectionType.None; unpinnedView.style.flexGrow = 1; @@ -275,50 +140,206 @@ VisualElement CreateItem() root.Add(unpinnedView); if (pinnedList.Count == 0) { if (pinnedView != null) HideVisualElement(pinnedView); if (header != null) HideVisualElement(header); } } void Bind(VisualElement v, int i, bool isPinnedList) { var item = isPinnedList ? pinnedList[i] : dataList[i]; var sceneButton = v.Q<Button>("SceneButton"); sceneButton.text = item.SceneName; System.Action onClickScene = () => EditorSceneManager.OpenScene(AssetDatabase.GUIDToAssetPath(item.GUID)); SubscribeToButton(sceneButton, onClickScene); var pinButton = v.Q<Button>("Pin"); item.Pinned = !isPinnedList; pinButton.text = isPinnedList ? "Unpin" : "Pin"; System.Action clicked = () => { Debug.Log("Clicked " + item.SceneName); UnsubscribeToButton(pinButton); item.Pinned = !isPinnedList; if (!isPinnedList) { item.PinnedIndex = pinnedList.Count; pinnedList.Add(item); dataList.Remove(item); } else { pinnedList.Remove(item); dataList.Insert(0, item); } pinnedView.style.minHeight = PinnedMinHeight(); if (!isPinnedList) // if isPinnedList = false, show header and pinned view { ShowVisualElement(pinnedView); ShowVisualElement(header); } pinnedView.Rebuild(); unpinnedView.Rebuild(); Save(); }; SubscribeToButton(pinButton, clicked); var findButton = v.Q<Button>("Find"); System.Action clickedFind = () => EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<SceneAsset>(AssetDatabase.GUIDToAssetPath(item.GUID))); SubscribeToButton(findButton, clickedFind); } private void Load() { var sceneAssets = FindAssetsOfType<SceneAsset>(); string currentFilePath = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this)); string currentDirectory = Path.GetDirectoryName(currentFilePath); jsonFilePath = Path.Combine(currentDirectory, "SceneList-JSON.json"); foreach (var sceneAsset in sceneAssets) { string path = AssetDatabase.GetAssetPath(sceneAsset); dataList.Add(new HorizontalItemData() { SceneName = sceneAsset.name, GUID = AssetDatabase.AssetPathToGUID(path), Pinned = false }); } if (File.Exists(jsonFilePath)) { string json = File.ReadAllText(jsonFilePath); StateData stateData = JsonUtility.FromJson<StateData>(json); // use except to remove pinned scene from dataList if (stateData != null && stateData.pinnedList != null && stateData.pinnedList.Count > 0) { var count = dataList.Count; for (int i = 0; i < count; i++) { for (int j = 0; j < stateData.pinnedList.Count; j++) { if (dataList[i].GUID == stateData.pinnedList[j].GUID) { dataList[i].Pinned = true; dataList[i].PinnedIndex = stateData.pinnedList[j].PinnedIndex; break; } } } } } } private VisualElement CreateItem() { var horizontalItem = new VisualElement() { name = "HorizontalItem" }; var sceneButton = new Button() { name = "SceneButton" }; sceneButton.style.minWidth = 210; sceneButton.style.flexGrow = 1; sceneButton.style.unityTextAlign = TextAnchor.MiddleLeft; var pinButton = new Button() { name = "Pin", text = "Pin" }; var findButton = new Button() { name = "Find", text = "Find" }; horizontalItem.Add(sceneButton); horizontalItem.Add(pinButton); horizontalItem.Add(findButton); horizontalItem.style.flexDirection = FlexDirection.Row; pinButton.style.maxWidth = 70; findButton.style.maxWidth = 70; return horizontalItem; } private int PinnedMinHeight() { if (pinnedList.Count > 0) { if (pinnedView != null) pinnedView.style.marginBottom = 10; if (unpinnedView != null) unpinnedView.style.marginTop = 10; } if (pinnedList.Count == 0) { if (pinnedView != null) HideVisualElement(pinnedView); if (header != null) HideVisualElement(header); } const int maxItem = 10; int heightIncrease = 22; return Mathf.Clamp(pinnedList.Count * heightIncrease, 0, maxItem * heightIncrease); } private void ShowVisualElement(VisualElement visualElement) { visualElement.style.display = DisplayStyle.Flex; visualElement.style.visibility = Visibility.Visible; visualElement.pickingMode = PickingMode.Position; } private void HideVisualElement(VisualElement visualElement) { visualElement.style.display = DisplayStyle.None; visualElement.style.visibility = Visibility.Hidden; visualElement.pickingMode = PickingMode.Ignore; } private void SubscribeToButton(Button button, System.Action clicked) { UnsubscribeToButton(button); if (button.userData == null) button.userData = new UserData(); (button.userData as UserData).AddCallback(button.text, clicked); button.clicked += clicked; } private void UnsubscribeToButton(Button button) { if (button.userData == null) return; (button.userData as UserData).RemoveCallback(button.text, button); } private void Save() { StateData stateData = new StateData(); stateData.pinnedList = pinnedList; string json = JsonUtility.ToJson(stateData); File.WriteAllText(jsonFilePath, json); } private T[] FindAssetsOfType<T>() where T : UnityEngine.Object { string[] guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}"); List<T> list = new List<T>(); foreach (string guid in guids) { string assetPath = AssetDatabase.GUIDToAssetPath(guid); T asset = AssetDatabase.LoadAssetAtPath<T>(assetPath); if (asset != null) { list.Add(asset); } } return list.ToArray(); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,5 @@ <p align="center"> <img src="https://gist.github.com/user-attachments/assets/1467ff9b-d7a5-434d-bba8-80ae1849aa1b" alt="image" style="max-width: 100%; height: auto;"/> </p> ##### How to open: On Unity menu bar -> Tools -> Scene List and Pins -
restush created this gist
Aug 22, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,324 @@ using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.UIElements; public class SceneListEditorWindow : EditorWindow { [System.Serializable] private class HorizontalItemData { public string SceneName; public string GUID; public bool Pinned; public int Index; } private List<HorizontalItemData> dataList = new(); private List<HorizontalItemData> pinnedList = new(); [System.Serializable] private class StateData { public List<HorizontalItemData> pinnedList; } [SerializeField] VisualTreeAsset tree; [SerializeField] VisualTreeAsset treeButton; private ListView pinnedView; private ListView unpinnedView; private string jsonFilePath; private Label header; private Label header2; [MenuItem("Tools/Scene List and Pins")] static void CreateMenu() { var window = GetWindow<SceneListEditorWindow>(); window.titleContent = new GUIContent("Scene List & Pins"); } T[] FindAssetsOfType<T>() where T : UnityEngine.Object { string[] guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}"); List<T> list = new List<T>(); foreach (string guid in guids) { string assetPath = AssetDatabase.GUIDToAssetPath(guid); T asset = AssetDatabase.LoadAssetAtPath<T>(assetPath); if (asset != null) { list.Add(asset); } } return list.ToArray(); } private void CreateGUI() { // find all scenes in the project var sceneAssets = FindAssetsOfType<SceneAsset>(); string currentFilePath = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this)); string currentDirectory = Path.GetDirectoryName(currentFilePath); jsonFilePath = Path.Combine(currentDirectory, "FindMissingEditor-JSON.json"); foreach (var sceneAsset in sceneAssets) { string path = AssetDatabase.GetAssetPath(sceneAsset); dataList.Add(new HorizontalItemData() { SceneName = sceneAsset.name, GUID = AssetDatabase.AssetPathToGUID(path), Pinned = false }); } if (File.Exists(jsonFilePath)) { string json = File.ReadAllText(jsonFilePath); StateData stateData = JsonUtility.FromJson<StateData>(json); // use except to remove pinned scene from dataList if (stateData != null && stateData.pinnedList != null) { var count = dataList.Count; for (int i = 0; i < count; i++) { for (int j = 0; j < stateData.pinnedList.Count; j++) { if (dataList[i].GUID == stateData.pinnedList[j].GUID) { dataList[i].Pinned = true; dataList[i].Index = stateData.pinnedList[j].Index; break; } } } } } pinnedList = dataList.FindAll(x => x.Pinned); dataList.RemoveAll(x => x.Pinned); pinnedList = pinnedList.OrderBy(x => x.Index).ToList(); VisualElement CreateItem() { var horizontalItem = new VisualElement() { name = "HorizontalItem" }; var sceneButton = new Button() { name = "SceneButton" }; sceneButton.style.minWidth = 210; sceneButton.style.flexGrow = 1; sceneButton.style.unityTextAlign = TextAnchor.MiddleLeft; var pinButton = new Button() { name = "Pin", text = "Pin" }; var findButton = new Button() { name = "Find", text = "Find" }; horizontalItem.Add(sceneButton); horizontalItem.Add(pinButton); horizontalItem.Add(findButton); horizontalItem.style.flexDirection = FlexDirection.Row; pinButton.style.maxWidth = 70; findButton.style.maxWidth = 70; return horizontalItem; } pinnedView = new ListView() { itemsSource = pinnedList, makeItem = () => CreateItem(), bindItem = (v, index) => { int i = index; var item = pinnedList[i]; var sceneButton = v.Q<Button>("SceneButton"); sceneButton.text = item.SceneName; if (sceneButton.userData != null) sceneButton.clicked -= sceneButton.userData as System.Action; System.Action onClickScene = () => EditorSceneManager.OpenScene(AssetDatabase.GUIDToAssetPath(item.GUID)); sceneButton.userData = onClickScene; sceneButton.clicked += onClickScene; var pinButton = v.Q<Button>("Pin"); item.Pinned = true; pinButton.text = "Unpin"; System.Action action = () => { if (pinButton.userData != null) pinButton.clicked -= pinButton.userData as System.Action; item.Pinned = false; dataList.Add(item); pinnedList.Remove(item); pinnedView.style.minHeight = PinnedMinHeight(); pinnedView.Rebuild(); unpinnedView.Rebuild(); }; if (pinButton.userData != null) pinButton.clicked -= pinButton.userData as System.Action; pinButton.userData = action; pinButton.clicked += action; var findButton = v.Q<Button>("Find"); findButton.clicked += () => EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<SceneAsset>(AssetDatabase.GUIDToAssetPath(item.GUID))); }, showAlternatingRowBackgrounds = AlternatingRowBackground.All, reorderable = true, reorderMode = ListViewReorderMode.Animated, }; pinnedView.style.unityTextAlign = TextAnchor.MiddleCenter; pinnedView.style.flexGrow = 1; pinnedView.style.minHeight = PinnedMinHeight(); // callback on reorder pinnedView.itemIndexChanged += (oldIndex, newIndex) => { pinnedList[newIndex].Index = newIndex; pinnedList[oldIndex].Index = oldIndex; }; pinnedView.selectionType = SelectionType.None; unpinnedView = new ListView() { itemsSource = dataList, makeItem = () => CreateItem(), bindItem = (v, i) => { var item = dataList[i]; var sceneButton = v.Q<Button>("SceneButton"); sceneButton.text = item.SceneName; if (sceneButton.userData != null) sceneButton.clicked -= sceneButton.userData as System.Action; System.Action onClickScene = () => EditorSceneManager.OpenScene(AssetDatabase.GUIDToAssetPath(item.GUID)); sceneButton.userData = onClickScene; sceneButton.clicked += onClickScene; var pinButton = v.Q<Button>("Pin"); item.Pinned = false; pinButton.text = "Pin"; System.Action action = () => { if (pinButton.userData != null) pinButton.clicked -= pinButton.userData as System.Action; item.Index = pinnedList.Count; pinnedList.Add(item); dataList.Remove(item); pinnedView.style.minHeight = PinnedMinHeight(); // show pinned view pinnedView.style.display = DisplayStyle.Flex; pinnedView.style.visibility = Visibility.Visible; pinnedView.pickingMode = PickingMode.Position; header.style.display = DisplayStyle.Flex; header.style.visibility = Visibility.Visible; header.pickingMode = PickingMode.Position; pinnedView.Rebuild(); unpinnedView.Rebuild(); }; if (pinButton.userData != null) pinButton.clicked -= pinButton.userData as System.Action; pinButton.userData = action; pinButton.clicked += action; var findButton = v.Q<Button>("Find"); findButton.clicked += () => EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<SceneAsset>(AssetDatabase.GUIDToAssetPath(item.GUID))); }, }; unpinnedView.selectionType = SelectionType.None; unpinnedView.style.flexGrow = 1; var root = new VisualElement() { name = "Root" }; rootVisualElement.Add(root); header = new Label("Pinned Scenes") { name = "Header" }; header.style.unityFontStyleAndWeight = FontStyle.Bold; header.style.fontSize = 18; header.style.unityTextAlign = TextAnchor.MiddleCenter; header.style.marginBottom = 2; root.Add(header); root.Add(pinnedView); header2 = new Label("Unpinned Scenes") { name = "Header" }; header2.style.unityFontStyleAndWeight = FontStyle.Bold; header2.style.fontSize = 18; header2.style.unityTextAlign = TextAnchor.MiddleCenter; header2.style.marginBottom = 2; root.Add(header2); root.Add(unpinnedView); int PinnedMinHeight() { if (pinnedList.Count > 0) { if (pinnedView != null) pinnedView.style.marginBottom = 10; if (unpinnedView != null) unpinnedView.style.marginTop = 10; } if (pinnedList.Count == 0) { if (pinnedView != null) { pinnedView.style.display = DisplayStyle.None; pinnedView.style.visibility = Visibility.Hidden; pinnedView.pickingMode = PickingMode.Ignore; } if (header != null) { header.style.display = DisplayStyle.None; header.style.visibility = Visibility.Hidden; header.pickingMode = PickingMode.Ignore; } } const int maxItem = 10; int heightIncrease = 22; return Mathf.Clamp(pinnedList.Count * heightIncrease, 0, maxItem * heightIncrease); } } private void OnDestroy() { StateData stateData = new StateData(); stateData.pinnedList = pinnedList; string json = JsonUtility.ToJson(stateData); File.WriteAllText(jsonFilePath, json); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,5 @@ <p align="center"> <img src="https://gist.github.com/user-attachments/assets/61027782-fd43-42b9-ab88-65d3f8d5a047" alt="image"/> </p> ##### How to open: On Unity menu bar -> Tools -> Scene List and Pins