UnityExplorer/src/UI/Main/ScenePage.cs

437 lines
13 KiB
C#
Raw Normal View History

2020-08-07 22:19:03 +10:00
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
2020-10-08 06:15:42 +11:00
using Explorer.UI.Shared;
using Explorer.CacheObject;
2020-08-07 22:19:03 +10:00
2020-10-08 06:15:42 +11:00
namespace Explorer.UI.Main
2020-08-07 22:19:03 +10:00
{
2020-10-08 06:15:42 +11:00
public class ScenePage : BaseMainMenuPage
2020-08-07 22:19:03 +10:00
{
public static ScenePage Instance;
public override string Name { get => "Scenes"; }
2020-08-07 22:19:03 +10:00
public PageHelper Pages = new PageHelper();
2020-08-07 22:19:03 +10:00
private float m_timeOfLastUpdate = -1f;
private const int PASSIVE_UPDATE_INTERVAL = 1;
2020-09-06 03:19:39 +10:00
private static bool m_getRootObjectsFailed;
private static string m_currentScene = "";
2020-08-07 22:19:03 +10:00
// gameobject list
private Transform m_currentTransform;
2020-10-08 06:15:42 +11:00
private readonly List<CacheObjectBase> m_objectList = new List<CacheObjectBase>();
2020-08-07 22:19:03 +10:00
// search bar
private bool m_searching = false;
private string m_searchInput = "";
2020-10-08 06:15:42 +11:00
private List<CacheObjectBase> m_searchResults = new List<CacheObjectBase>();
2020-08-07 22:19:03 +10:00
public override void Init()
{
Instance = this;
}
public void OnSceneChange()
{
m_currentScene = UnityHelpers.ActiveSceneName;
SetTransformTarget(null);
}
2020-08-07 22:19:03 +10:00
public void SetTransformTarget(Transform t)
{
m_currentTransform = t;
if (m_searching)
CancelSearch();
Update_Impl(true);
}
public void TraverseUp()
{
if (m_currentTransform.parent != null)
{
SetTransformTarget(m_currentTransform.parent);
}
else
{
SetTransformTarget(null);
}
}
public void Search()
{
m_searchResults = SearchSceneObjects(m_searchInput);
m_searching = true;
Pages.ItemCount = m_searchResults.Count;
}
public void CancelSearch()
{
m_searching = false;
if (m_getRootObjectsFailed && !m_currentTransform)
{
GetRootObjectsManual_Impl();
}
}
2020-10-08 06:15:42 +11:00
public List<CacheObjectBase> SearchSceneObjects(string _search)
{
2020-10-08 06:15:42 +11:00
var matches = new List<CacheObjectBase>();
foreach (var obj in Resources.FindObjectsOfTypeAll(ReflectionHelpers.GameObjectType))
{
#if CPP
var go = obj.TryCast<GameObject>();
#else
var go = obj as GameObject;
#endif
if (go.name.ToLower().Contains(_search.ToLower()) && go.scene.name == m_currentScene)
{
2020-10-08 06:15:42 +11:00
matches.Add(CacheFactory.GetCacheObject(go));
2020-08-07 22:19:03 +10:00
}
}
return matches;
2020-08-07 22:19:03 +10:00
}
public override void Update()
{
if (m_searching) return;
if (Time.time - m_timeOfLastUpdate < PASSIVE_UPDATE_INTERVAL) return;
m_timeOfLastUpdate = Time.time;
Update_Impl();
}
private void Update_Impl(bool manual = false)
{
List<Transform> allTransforms = new List<Transform>();
// get current list of all transforms (either scene root or our current transform children)
if (m_currentTransform)
{
for (int i = 0; i < m_currentTransform.childCount; i++)
{
allTransforms.Add(m_currentTransform.GetChild(i));
}
}
else
{
if (!m_getRootObjectsFailed)
{
try
{
for (int i = 0; i < SceneManager.sceneCount; i++)
{
var scene = SceneManager.GetSceneAt(i);
if (scene.name == m_currentScene)
{
allTransforms.AddRange(scene.GetRootGameObjects()
.Select(it => it.transform));
break;
}
}
}
catch
{
ExplorerCore.Log("Exception getting root scene objects, falling back to backup method...");
m_getRootObjectsFailed = true;
allTransforms.AddRange(GetRootObjectsManual_Impl());
}
}
else
{
if (!manual)
{
return;
}
allTransforms.AddRange(GetRootObjectsManual_Impl());
}
}
Pages.ItemCount = allTransforms.Count;
int offset = Pages.CalculateOffsetIndex();
// sort by childcount
allTransforms.Sort((a, b) => b.childCount.CompareTo(a.childCount));
m_objectList.Clear();
for (int i = offset; i < offset + Pages.ItemsPerPage && i < Pages.ItemCount; i++)
{
var child = allTransforms[i];
2020-10-08 06:15:42 +11:00
m_objectList.Add(CacheFactory.GetCacheObject(child));
}
}
private IEnumerable<Transform> GetRootObjectsManual_Impl()
{
try
{
var array = Resources.FindObjectsOfTypeAll(ReflectionHelpers.TransformType);
var list = new List<Transform>();
foreach (var obj in array)
{
#if CPP
var transform = obj.TryCast<Transform>();
#else
var transform = obj as Transform;
#endif
if (transform.parent == null && transform.gameObject.scene.name == m_currentScene)
{
list.Add(transform);
}
}
return list;
}
catch (Exception e)
{
2020-10-08 06:15:42 +11:00
ExplorerCore.Log("Exception getting root scene objects (manual): "
+ e.GetType() + ", " + e.Message + "\r\n"
+ e.StackTrace);
return new Transform[0];
}
}
// --------- GUI Draw Function --------- //
2020-08-07 22:19:03 +10:00
public override void DrawWindow()
{
2020-08-07 22:19:03 +10:00
try
{
DrawHeaderArea();
2020-10-08 06:15:42 +11:00
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
DrawPageButtons();
2020-08-07 22:19:03 +10:00
if (!m_searching)
2020-08-07 22:19:03 +10:00
{
DrawGameObjectList();
}
else
{
DrawSearchResultsList();
2020-08-07 22:19:03 +10:00
}
GUILayout.EndVertical();
}
catch (Exception e)
{
if (!e.Message.Contains("in a group with only"))
{
ExplorerCore.Log(e.ToString());
}
}
}
2020-08-07 22:19:03 +10:00
private void DrawHeaderArea()
{
2020-10-08 06:15:42 +11:00
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
2020-08-07 22:19:03 +10:00
// Current Scene label
GUILayout.Label("Current Scene:", new GUILayoutOption[] { GUILayout.Width(120) });
SceneChangeButtons();
GUILayout.Label("<color=cyan>" + m_currentScene + "</color>", new GUILayoutOption[0]);
GUILayout.EndHorizontal();
// ----- GameObject Search -----
2020-10-08 06:15:42 +11:00
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
GUILayout.Label("<b>Search Scene:</b>", new GUILayoutOption[] { GUILayout.Width(100) });
m_searchInput = GUIUnstrip.TextField(m_searchInput, new GUILayoutOption[0]);
if (GUILayout.Button("Search", new GUILayoutOption[] { GUILayout.Width(80) }))
2020-08-07 22:19:03 +10:00
{
Search();
2020-08-07 22:19:03 +10:00
}
GUILayout.EndHorizontal();
GUIUnstrip.Space(5);
2020-08-07 22:19:03 +10:00
}
private void SceneChangeButtons()
{
var scenes = new List<Scene>();
var names = new List<string>();
for (int i = 0; i < SceneManager.sceneCount; i++)
{
var scene = SceneManager.GetSceneAt(i);
names.Add(scene.name);
scenes.Add(scene);
}
if (scenes.Count > 1)
{
int changeWanted = 0;
if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(30) }))
{
changeWanted = -1;
}
if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(30) }))
{
changeWanted = 1;
}
if (changeWanted != 0)
{
int index = names.IndexOf(m_currentScene);
index += changeWanted;
if (index > scenes.Count - 1)
{
index = 0;
}
else if (index < 0)
{
index = scenes.Count - 1;
}
m_currentScene = scenes[index].name;
}
}
}
private void DrawPageButtons()
{
2020-10-08 06:15:42 +11:00
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
Pages.DrawLimitInputArea();
2020-08-07 22:19:03 +10:00
if (Pages.ItemCount > Pages.ItemsPerPage)
{
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Left, ref this.scroll);
Update_Impl(true);
}
2020-08-07 22:19:03 +10:00
Pages.CurrentPageLabel();
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Right, ref this.scroll);
Update_Impl(true);
}
}
GUILayout.EndHorizontal();
GUI.skin.label.alignment = TextAnchor.UpperLeft;
2020-08-07 22:19:03 +10:00
}
private void DrawGameObjectList()
2020-08-07 22:19:03 +10:00
{
if (m_currentTransform != null)
2020-08-07 22:19:03 +10:00
{
2020-10-08 06:15:42 +11:00
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
if (GUILayout.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
{
TraverseUp();
}
else
{
GUILayout.Label("<color=cyan>" + m_currentTransform.GetGameObjectPath() + "</color>",
new GUILayoutOption[] { GUILayout.Width(MainMenu.MainRect.width - 187f) });
}
2020-10-08 06:15:42 +11:00
Buttons.InspectButton(m_currentTransform);
GUILayout.EndHorizontal();
2020-08-07 22:19:03 +10:00
}
else
{
GUILayout.Label("Scene Root GameObjects:", new GUILayoutOption[0]);
if (m_getRootObjectsFailed)
{
if (GUILayout.Button("Update Root Object List (auto-update failed!)", new GUILayoutOption[0]))
{
Update_Impl(true);
}
}
2020-08-07 22:19:03 +10:00
}
if (m_objectList.Count > 0)
{
for (int i = 0; i < m_objectList.Count; i++)
{
var obj = m_objectList[i];
if (obj == null) continue;
2020-10-08 06:15:42 +11:00
try
{
2020-10-08 06:15:42 +11:00
var go = obj.IValue.Value as GameObject ?? (obj.IValue.Value as Transform)?.gameObject;
2020-08-07 22:19:03 +10:00
2020-10-08 06:15:42 +11:00
if (!go)
{
2020-10-08 06:15:42 +11:00
string label = "<color=red><i>null";
2020-10-08 06:15:42 +11:00
if (go != null)
{
label += " (Destroyed)";
}
label += "</i></color>";
GUILayout.Label(label, new GUILayoutOption[0]);
}
else
{
Buttons.GameObjectButton(go, SetTransformTarget, true, MainMenu.MainRect.width - 170f);
}
}
2020-10-08 06:15:42 +11:00
catch { }
}
}
2020-08-07 22:19:03 +10:00
}
private void DrawSearchResultsList()
2020-08-07 22:19:03 +10:00
{
if (GUILayout.Button("<- Cancel Search", new GUILayoutOption[] { GUILayout.Width(150) }))
{
CancelSearch();
}
2020-08-07 22:19:03 +10:00
GUILayout.Label("Search Results:", new GUILayoutOption[0]);
if (m_searchResults.Count > 0)
2020-08-07 22:19:03 +10:00
{
int offset = Pages.CalculateOffsetIndex();
2020-08-07 22:19:03 +10:00
for (int i = offset; i < offset + Pages.ItemsPerPage && i < m_searchResults.Count; i++)
{
2020-10-08 06:15:42 +11:00
var obj = m_searchResults[i].IValue.Value as GameObject;
2020-10-08 06:15:42 +11:00
if (obj)
{
2020-10-08 06:15:42 +11:00
Buttons.GameObjectButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
}
else
{
GUILayout.Label("<i><color=red>Null or destroyed!</color></i>", new GUILayoutOption[0]);
}
}
}
else
{
GUILayout.Label("<color=red><i>No results found!</i></color>", new GUILayoutOption[0]);
}
2020-08-07 22:19:03 +10:00
}
}
}