diff --git a/src/CachedObjects/CacheObjectBase.cs b/src/CachedObjects/CacheObjectBase.cs
index 81bba82..4bd06c5 100644
--- a/src/CachedObjects/CacheObjectBase.cs
+++ b/src/CachedObjects/CacheObjectBase.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
+using Explorer.CachedObjects;
using MelonLoader;
using UnhollowerBaseLib;
using UnityEngine;
@@ -137,6 +138,22 @@ namespace Explorer
{
holder = new CacheEnum();
}
+ else if (valueType == typeof(Vector2) || valueType == typeof(Vector3) || valueType == typeof(Vector4))
+ {
+ holder = new CacheVector();
+ }
+ else if (valueType == typeof(Quaternion))
+ {
+ holder = new CacheQuaternion();
+ }
+ else if (valueType == typeof(Color))
+ {
+ holder = new CacheColor();
+ }
+ else if (valueType == typeof(Rect))
+ {
+ holder = new CacheRect();
+ }
else if (ReflectionHelpers.IsArray(valueType) || ReflectionHelpers.IsList(valueType))
{
holder = new CacheList();
diff --git a/src/CachedObjects/CacheDictionary.cs b/src/CachedObjects/Object/CacheDictionary.cs
similarity index 100%
rename from src/CachedObjects/CacheDictionary.cs
rename to src/CachedObjects/Object/CacheDictionary.cs
diff --git a/src/CachedObjects/CacheGameObject.cs b/src/CachedObjects/Object/CacheGameObject.cs
similarity index 100%
rename from src/CachedObjects/CacheGameObject.cs
rename to src/CachedObjects/Object/CacheGameObject.cs
diff --git a/src/CachedObjects/CacheList.cs b/src/CachedObjects/Object/CacheList.cs
similarity index 100%
rename from src/CachedObjects/CacheList.cs
rename to src/CachedObjects/Object/CacheList.cs
diff --git a/src/CachedObjects/CacheMethod.cs b/src/CachedObjects/Other/CacheMethod.cs
similarity index 100%
rename from src/CachedObjects/CacheMethod.cs
rename to src/CachedObjects/Other/CacheMethod.cs
diff --git a/src/CachedObjects/CacheOther.cs b/src/CachedObjects/Other/CacheOther.cs
similarity index 100%
rename from src/CachedObjects/CacheOther.cs
rename to src/CachedObjects/Other/CacheOther.cs
diff --git a/src/CachedObjects/Struct/CacheColor.cs b/src/CachedObjects/Struct/CacheColor.cs
new file mode 100644
index 0000000..a11add8
--- /dev/null
+++ b/src/CachedObjects/Struct/CacheColor.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+
+namespace Explorer.CachedObjects
+{
+ public class CacheColor : CacheObjectBase
+ {
+ private string r = "0";
+ private string g = "0";
+ private string b = "0";
+ private string a = "0";
+
+ public override void UpdateValue()
+ {
+ base.UpdateValue();
+
+ var color = (Color)Value;
+
+ r = color.r.ToString();
+ g = color.g.ToString();
+ b = color.b.ToString();
+ a = color.a.ToString();
+ }
+
+ public override void DrawValue(Rect window, float width)
+ {
+ GUILayout.Label($"Color: {(Color)Value}", null);
+
+ if (CanWrite)
+ {
+ GUILayout.EndHorizontal();
+ var whitespace = window.width - width - 90;
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("R:", new GUILayoutOption[] { GUILayout.Width(30) });
+ r = GUILayout.TextField(r, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("G:", new GUILayoutOption[] { GUILayout.Width(30) });
+ g = GUILayout.TextField(g, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("B:", new GUILayoutOption[] { GUILayout.Width(30) });
+ b = GUILayout.TextField(b, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("A:", new GUILayoutOption[] { GUILayout.Width(30) });
+ a = GUILayout.TextField(a, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ // draw set value button
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ if (GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(130) }))
+ {
+ SetValueFromInput();
+ }
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ }
+ }
+
+ private void SetValueFromInput()
+ {
+ if (float.TryParse(r, out float fR)
+ && float.TryParse(g, out float fG)
+ && float.TryParse(b, out float fB)
+ && float.TryParse(a, out float fA))
+ {
+ Value = new Color(fR, fB, fG, fA);
+ }
+ }
+ }
+}
diff --git a/src/CachedObjects/CacheEnum.cs b/src/CachedObjects/Struct/CacheEnum.cs
similarity index 100%
rename from src/CachedObjects/CacheEnum.cs
rename to src/CachedObjects/Struct/CacheEnum.cs
diff --git a/src/CachedObjects/CachePrimitive.cs b/src/CachedObjects/Struct/CachePrimitive.cs
similarity index 100%
rename from src/CachedObjects/CachePrimitive.cs
rename to src/CachedObjects/Struct/CachePrimitive.cs
diff --git a/src/CachedObjects/Struct/CacheQuaternion.cs b/src/CachedObjects/Struct/CacheQuaternion.cs
new file mode 100644
index 0000000..ff4a3c7
--- /dev/null
+++ b/src/CachedObjects/Struct/CacheQuaternion.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+
+namespace Explorer
+{
+ public class CacheQuaternion : CacheObjectBase
+ {
+ private Vector3 EulerAngle = Vector3.zero;
+
+ private string x = "0";
+ private string y = "0";
+ private string z = "0";
+
+ public override void UpdateValue()
+ {
+ base.UpdateValue();
+
+ EulerAngle = ((Quaternion)Value).eulerAngles;
+
+ x = EulerAngle.x.ToString();
+ y = EulerAngle.y.ToString();
+ z = EulerAngle.z.ToString();
+ }
+
+ public override void DrawValue(Rect window, float width)
+ {
+ GUILayout.Label($"Quaternion: {((Quaternion)Value).eulerAngles}", null);
+
+ if (CanWrite)
+ {
+ GUILayout.EndHorizontal();
+ var whitespace = window.width - width - 90;
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
+ x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
+ y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
+ z = GUILayout.TextField(z, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ // draw set value button
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ if (GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(130) }))
+ {
+ SetValueFromInput();
+ }
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ }
+ }
+
+ private void SetValueFromInput()
+ {
+ if (float.TryParse(x, out float fX)
+ && float.TryParse(y, out float fY)
+ && float.TryParse(z, out float fZ))
+ {
+ Value = Quaternion.Euler(new Vector3(fX, fY, fZ));
+ SetValue();
+ }
+ }
+ }
+}
diff --git a/src/CachedObjects/Struct/CacheRect.cs b/src/CachedObjects/Struct/CacheRect.cs
new file mode 100644
index 0000000..8538cc4
--- /dev/null
+++ b/src/CachedObjects/Struct/CacheRect.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+
+namespace Explorer.CachedObjects
+{
+ public class CacheRect : CacheObjectBase
+ {
+ private string x = "0";
+ private string y = "0";
+ private string w = "0";
+ private string h = "0";
+
+ public override void UpdateValue()
+ {
+ base.UpdateValue();
+
+ var rect = (Rect)Value;
+
+ x = rect.x.ToString();
+ y = rect.y.ToString();
+ w = rect.width.ToString();
+ h = rect.height.ToString();
+ }
+
+ public override void DrawValue(Rect window, float width)
+ {
+ GUILayout.Label($"Rect: {(Rect)Value}", null);
+
+ if (CanWrite)
+ {
+ GUILayout.EndHorizontal();
+ var whitespace = window.width - width - 90;
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
+ x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
+ y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
+ w = GUILayout.TextField(w, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("H:", new GUILayoutOption[] { GUILayout.Width(30) });
+ h = GUILayout.TextField(h, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ // draw set value button
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ if (GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(130) }))
+ {
+ SetValueFromInput();
+ }
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ }
+ }
+
+ private void SetValueFromInput()
+ {
+ if (float.TryParse(x, out float fX)
+ && float.TryParse(y, out float fY)
+ && float.TryParse(w, out float fW)
+ && float.TryParse(h, out float fH))
+ {
+ Value = new Rect(fX, fY, fW, fH);
+ SetValue();
+ }
+ }
+ }
+}
diff --git a/src/CachedObjects/Struct/CacheVector.cs b/src/CachedObjects/Struct/CacheVector.cs
new file mode 100644
index 0000000..d275ce5
--- /dev/null
+++ b/src/CachedObjects/Struct/CacheVector.cs
@@ -0,0 +1,142 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Reflection;
+using UnityEngine;
+
+namespace Explorer
+{
+ public class CacheVector : CacheObjectBase
+ {
+ public int VectorSize = 2;
+
+ private string x = "0";
+ private string y = "0";
+ private string z = "0";
+ private string w = "0";
+
+ private MethodInfo m_toStringMethod;
+
+ public override void Init()
+ {
+ if (Value is Vector2)
+ {
+ VectorSize = 2;
+ }
+ else if (Value is Vector3)
+ {
+ VectorSize = 3;
+ }
+ else
+ {
+ VectorSize = 4;
+ }
+
+ m_toStringMethod = Value.GetType().GetMethod("ToString", new Type[0]);
+ }
+
+ public override void UpdateValue()
+ {
+ base.UpdateValue();
+
+ if (Value is Vector2 vec2)
+ {
+ x = vec2.x.ToString();
+ y = vec2.y.ToString();
+ }
+ else if (Value is Vector3 vec3)
+ {
+ x = vec3.x.ToString();
+ y = vec3.y.ToString();
+ z = vec3.z.ToString();
+ }
+ else if (Value is Vector4 vec4)
+ {
+ x = vec4.x.ToString();
+ y = vec4.y.ToString();
+ z = vec4.z.ToString();
+ w = vec4.w.ToString();
+ }
+ }
+
+ public override void DrawValue(Rect window, float width)
+ {
+ GUILayout.Label($"Vector{VectorSize}: {(string)m_toStringMethod.Invoke(Value, new object[0])}", null);
+
+ if (CanWrite)
+ {
+ GUILayout.EndHorizontal();
+ var whitespace = window.width - width - 90;
+
+ // always draw x and y
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
+ x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
+ y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+
+ if (VectorSize > 2)
+ {
+ // draw z
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
+ z = GUILayout.TextField(z, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+ }
+ if (VectorSize > 3)
+ {
+ // draw w
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
+ w = GUILayout.TextField(w, new GUILayoutOption[] { GUILayout.Width(70) });
+ GUILayout.EndHorizontal();
+ }
+
+ // draw set value button
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(whitespace);
+ if (GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(130) }))
+ {
+ SetValueFromInput();
+ }
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ }
+ }
+
+ private void SetValueFromInput()
+ {
+ if (float.TryParse(x, out float fX)
+ && float.TryParse(y, out float fY)
+ && float.TryParse(z, out float fZ)
+ && float.TryParse(w, out float fW))
+ {
+ object vector = null;
+
+ switch (VectorSize)
+ {
+ case 2: vector = new Vector2(fX, fY); break;
+ case 3: vector = new Vector3(fX, fY, fZ); break;
+ case 4: vector = new Vector4(fX, fY, fZ, fW); break;
+ }
+
+ if (vector != null)
+ {
+ Value = vector;
+ SetValue();
+ }
+ }
+ }
+ }
+}
diff --git a/src/CppExplorer.cs b/src/CppExplorer.cs
index 02c1e18..0c534b7 100644
--- a/src/CppExplorer.cs
+++ b/src/CppExplorer.cs
@@ -12,7 +12,7 @@ namespace Explorer
public class CppExplorer : MelonMod
{
public const string GUID = "com.sinai.cppexplorer";
- public const string VERSION = "1.5.5";
+ public const string VERSION = "1.5.6";
public const string AUTHOR = "Sinai";
public const string NAME = "CppExplorer"
diff --git a/src/CppExplorer.csproj b/src/CppExplorer.csproj
index 5b2705e..f10917d 100644
--- a/src/CppExplorer.csproj
+++ b/src/CppExplorer.csproj
@@ -120,13 +120,17 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/MainMenu/Pages/ScenePage.cs b/src/MainMenu/Pages/ScenePage.cs
index 35f340b..38f734e 100644
--- a/src/MainMenu/Pages/ScenePage.cs
+++ b/src/MainMenu/Pages/ScenePage.cs
@@ -17,14 +17,17 @@ namespace Explorer
public PageHelper Pages = new PageHelper();
private float m_timeOfLastUpdate = -1f;
+ private static int PASSIVE_UPDATE_INTERVAL = 1;
- // ----- Holders for GUI elements ----- //
+ private static bool m_getRootObjectsFailed = false;
- private string m_currentScene = "";
+ // ----- Holders for GUI elements ----- //
+
+ private static string m_currentScene = "";
// gameobject list
private Transform m_currentTransform;
- private List m_objectList = new List();
+ private readonly List m_objectList = new List();
// search bar
private bool m_searching = false;
@@ -44,64 +47,6 @@ namespace Explorer
SetTransformTarget(null);
}
- //public void CheckOffset(ref int offset, int childCount)
- //{
- // if (offset >= childCount)
- // {
- // offset = 0;
- // m_pageOffset = 0;
- // }
- //}
-
- public override void Update()
- {
- if (m_searching) return;
-
- if (Time.time - m_timeOfLastUpdate < 1f) return;
- m_timeOfLastUpdate = Time.time;
-
- m_objectList = new List();
-
- var allTransforms = new List();
-
- // 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
- {
- var scene = SceneManager.GetSceneByName(m_currentScene);
-
- var list = new Il2CppSystem.Collections.Generic.List
- {
- Capacity = scene.rootCount
- };
- Scene.GetRootGameObjectsInternal(scene.handle, list);
-
- foreach (var obj in list)
- {
- allTransforms.Add(obj.transform);
- }
- }
-
- Pages.ItemCount = allTransforms.Count;
-
- int offset = Pages.CalculateOffsetIndex();
-
- // sort by childcount
- allTransforms.Sort((a, b) => b.childCount.CompareTo(a.childCount));
-
- for (int i = offset; i < offset + Pages.ItemsPerPage && i < Pages.ItemCount; i++)
- {
- var child = allTransforms[i];
- m_objectList.Add(new GameObjectCache(child.gameObject));
- }
- }
-
public void SetTransformTarget(Transform t)
{
m_currentTransform = t;
@@ -109,8 +54,7 @@ namespace Explorer
if (m_searching)
CancelSearch();
- m_timeOfLastUpdate = -1f;
- Update();
+ Update_Impl();
}
public void TraverseUp()
@@ -135,6 +79,11 @@ namespace Explorer
public void CancelSearch()
{
m_searching = false;
+
+ if (m_getRootObjectsFailed && !m_currentTransform)
+ {
+ GetRootObjectsManual_Impl();
+ }
}
public List SearchSceneObjects(string _search)
@@ -152,6 +101,80 @@ namespace Explorer
return matches;
}
+ 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()
+ {
+ var allTransforms = new List();
+
+ // 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
+ {
+ var list = SceneManager.GetActiveScene().GetRootGameObjects().ToArray();
+
+ foreach (var obj in list)
+ {
+ allTransforms.Add(obj.transform);
+ }
+ }
+ catch
+ {
+ m_getRootObjectsFailed = true;
+ PASSIVE_UPDATE_INTERVAL = 2;
+
+ allTransforms = GetRootObjectsManual_Impl();
+ }
+ }
+ else
+ {
+ allTransforms = 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];
+ m_objectList.Add(new GameObjectCache(child.gameObject));
+ }
+ }
+
+ private List GetRootObjectsManual_Impl()
+ {
+ var allTransforms = Resources.FindObjectsOfTypeAll()
+ .Where(x => x.parent == null && x.gameObject.scene.name == m_currentScene)
+ .ToList();
+
+ return allTransforms;
+ }
+
// --------- GUI Draw Function --------- //
public override void DrawWindow()
@@ -251,8 +274,7 @@ namespace Explorer
{
Pages.TurnPage(Turn.Left, ref this.scroll);
- m_timeOfLastUpdate = -1f;
- Update();
+ Update_Impl();
}
Pages.CurrentPageLabel();
@@ -261,8 +283,7 @@ namespace Explorer
{
Pages.TurnPage(Turn.Right, ref this.scroll);
- m_timeOfLastUpdate = -1f;
- Update();
+ Update_Impl();
}
}
@@ -296,8 +317,12 @@ namespace Explorer
if (m_objectList.Count > 0)
{
- foreach (var obj in m_objectList)
+ for (int i = 0; i < m_objectList.Count; i++)
{
+ var obj = m_objectList[i];
+
+ if (obj == null) continue;
+
if (!obj.RefGameObject)
{
string label = "null";
diff --git a/src/UnstripFixes/GUIUnstrip.cs b/src/UnstripFixes/GUIUnstrip.cs
index 886b6de..95f94ea 100644
--- a/src/UnstripFixes/GUIUnstrip.cs
+++ b/src/UnstripFixes/GUIUnstrip.cs
@@ -187,7 +187,7 @@ namespace Explorer
ScrollStack.Push(scrollViewState);
- Rect screenRect = new Rect(position);
+ Rect screenRect = new Rect(position.x, position.y, position.width, position.height);
EventType type = Event.current.type;
if (type != EventType.Layout)
{
diff --git a/src/UnstripFixes/UnstripExtensions.cs b/src/UnstripFixes/UnstripExtensions.cs
index a8b36ea..818b0e9 100644
--- a/src/UnstripFixes/UnstripExtensions.cs
+++ b/src/UnstripFixes/UnstripExtensions.cs
@@ -12,27 +12,13 @@ namespace Explorer
public static Rect GetLastUnstripped(this GUILayoutGroup group)
{
Rect result;
- if (group.m_Cursor == 0)
- {
- Debug.LogError("You cannot call GetLast immediately after beginning a group.");
- result = GUILayoutEntry.kDummyRect;
- }
- else if (group.m_Cursor <= group.entries.Count)
+ if (group.m_Cursor > 0 && group.m_Cursor <= group.entries.Count)
{
GUILayoutEntry guilayoutEntry = group.entries[group.m_Cursor - 1];
result = guilayoutEntry.rect;
}
else
{
- Debug.LogError(string.Concat(new object[]
- {
- "Getting control ",
- group.m_Cursor,
- "'s position in a group with only ",
- group.entries.Count,
- " controls when doing ",
- Event.current.type
- }));
result = GUILayoutEntry.kDummyRect;
}
return result;
diff --git a/src/Windows/GameObjectWindow.cs b/src/Windows/GameObjectWindow.cs
index 973170d..14d8d02 100644
--- a/src/Windows/GameObjectWindow.cs
+++ b/src/Windows/GameObjectWindow.cs
@@ -29,9 +29,17 @@ namespace Explorer
private Vector2 m_compScroll = Vector2.zero;
private PageHelper CompPages = new PageHelper();
+ private readonly Vector3[] m_cachedInput = new Vector3[3];
private float m_translateAmount = 0.3f;
private float m_rotateAmount = 50f;
private float m_scaleAmount = 0.1f;
+ private bool m_freeze;
+ private Vector3 m_frozenPosition;
+ private Quaternion m_frozenRotation;
+ private Vector3 m_frozenScale;
+ private bool m_autoApplyTransform;
+ private bool m_autoUpdateTransform;
+ private bool m_localContext;
private readonly List m_cachedDestroyList = new List();
//private string m_addComponentInput = "";
@@ -73,12 +81,29 @@ namespace Explorer
m_name = m_object.name;
m_scene = string.IsNullOrEmpty(m_object.scene.name)
- ? "None"
+ ? "None (Asset/Resource)"
: m_object.scene.name;
+ CacheTransformValues();
+
Update();
}
+ private void CacheTransformValues()
+ {
+ if (m_localContext)
+ {
+ m_cachedInput[0] = m_object.transform.localPosition;
+ m_cachedInput[1] = m_object.transform.localEulerAngles;
+ }
+ else
+ {
+ m_cachedInput[0] = m_object.transform.position;
+ m_cachedInput[1] = m_object.transform.eulerAngles;
+ }
+ m_cachedInput[2] = m_object.transform.localScale;
+ }
+
public override void Update()
{
try
@@ -88,6 +113,21 @@ namespace Explorer
throw new Exception("Object is null!");
}
+ if (m_freeze)
+ {
+ if (m_localContext)
+ {
+ m_object.transform.localPosition = m_frozenPosition;
+ m_object.transform.localRotation = m_frozenRotation;
+ }
+ else
+ {
+ m_object.transform.position = m_frozenPosition;
+ m_object.transform.rotation = m_frozenRotation;
+ }
+ m_object.transform.localScale = m_frozenScale;
+ }
+
var list = new List();
for (int i = 0; i < m_object.transform.childCount; i++)
{
@@ -412,6 +452,16 @@ namespace Explorer
m_object.hideFlags |= HideFlags.DontUnloadUnusedAsset;
}
+ var lbl = m_freeze ? "Unfreeze" : "Freeze Pos/Rot";
+ if (GUILayout.Button(lbl, new GUILayoutOption[] { GUILayout.Width(110) }))
+ {
+ m_freeze = !m_freeze;
+ if (m_freeze)
+ {
+ UpdateFreeze();
+ }
+ }
+
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
@@ -436,10 +486,52 @@ namespace Explorer
GUILayout.BeginVertical(GUI.skin.box, null);
- var t = m_object.transform;
- TranslateControl(t, TranslateType.Position, ref m_translateAmount, false);
- TranslateControl(t, TranslateType.Rotation, ref m_rotateAmount, true);
- TranslateControl(t, TranslateType.Scale, ref m_scaleAmount, false);
+ m_cachedInput[0] = TranslateControl(TranslateType.Position, ref m_translateAmount, false);
+ m_cachedInput[1] = TranslateControl(TranslateType.Rotation, ref m_rotateAmount, true);
+ m_cachedInput[2] = TranslateControl(TranslateType.Scale, ref m_scaleAmount, false);
+
+ GUILayout.BeginHorizontal(null);
+ if (GUILayout.Button("Apply to Transform", null) || m_autoApplyTransform)
+ {
+ if (m_localContext)
+ {
+ m_object.transform.localPosition = m_cachedInput[0];
+ m_object.transform.localEulerAngles = m_cachedInput[1];
+ }
+ else
+ {
+ m_object.transform.position = m_cachedInput[0];
+ m_object.transform.eulerAngles = m_cachedInput[1];
+ }
+ m_object.transform.localScale = m_cachedInput[2];
+
+ if (m_freeze)
+ {
+ UpdateFreeze();
+ }
+ }
+ if (GUILayout.Button("Update from Transform", null) || m_autoUpdateTransform)
+ {
+ CacheTransformValues();
+ }
+ GUILayout.EndHorizontal();
+
+ GUILayout.BeginHorizontal(null);
+ BoolToggle(ref m_autoApplyTransform, "Auto-apply to Transform?");
+ BoolToggle(ref m_autoUpdateTransform, "Auto-update from transform?");
+ GUILayout.EndHorizontal();
+
+ bool b = m_localContext;
+ b = GUILayout.Toggle(b, "Use local transform values?", null);
+ if (b != m_localContext)
+ {
+ m_localContext = b;
+ CacheTransformValues();
+ if (m_freeze)
+ {
+ UpdateFreeze();
+ }
+ }
GUILayout.EndVertical();
@@ -453,6 +545,30 @@ namespace Explorer
GUILayout.EndVertical();
}
+ private void UpdateFreeze()
+ {
+ if (m_localContext)
+ {
+ m_frozenPosition = m_object.transform.localPosition;
+ m_frozenRotation = m_object.transform.localRotation;
+ }
+ else
+ {
+ m_frozenPosition = m_object.transform.position;
+ m_frozenRotation = m_object.transform.rotation;
+ }
+ m_frozenScale = m_object.transform.localScale;
+ }
+
+ private void BoolToggle(ref bool value, string message)
+ {
+ string lbl = "{message}";
+
+ value = GUILayout.Toggle(value, lbl, null);
+ }
+
public enum TranslateType
{
Position,
@@ -460,50 +576,55 @@ namespace Explorer
Scale
}
- private void TranslateControl(Transform transform, TranslateType mode, ref float amount, bool multByTime)
+ private Vector3 TranslateControl(TranslateType mode, ref float amount, bool multByTime)
{
GUILayout.BeginHorizontal(null);
- GUILayout.Label("" + mode + ":", new GUILayoutOption[] { GUILayout.Width(65) });
+ GUILayout.Label($"{(m_localContext ? "Local " : "")} {mode}:",
+ new GUILayoutOption[] { GUILayout.Width(m_localContext ? 110 : 65) });
- Vector3 vector = Vector3.zero;
+ var transform = m_object.transform;
switch (mode)
{
- case TranslateType.Position: vector = transform.localPosition; break;
- case TranslateType.Rotation: vector = transform.localRotation.eulerAngles; break;
- case TranslateType.Scale: vector = transform.localScale; break;
+ case TranslateType.Position:
+ var pos = m_localContext ? transform.localPosition : transform.position;
+ GUILayout.Label(pos.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
+ break;
+ case TranslateType.Rotation:
+ var rot = m_localContext ? transform.localEulerAngles : transform.eulerAngles;
+ GUILayout.Label(rot.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
+ break;
+ case TranslateType.Scale:
+ GUILayout.Label(transform.localScale.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
+ break;
}
- GUILayout.Label(vector.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.EndHorizontal();
+ Vector3 input = m_cachedInput[(int)mode];
+
GUILayout.BeginHorizontal(null);
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(20) });
- PlusMinusFloat(ref vector.x, amount, multByTime);
+ PlusMinusFloat(ref input.x, amount, multByTime);
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(20) });
- PlusMinusFloat(ref vector.y, amount, multByTime);
+ PlusMinusFloat(ref input.y, amount, multByTime);
GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(20) });
- PlusMinusFloat(ref vector.z, amount, multByTime);
-
- switch (mode)
- {
- case TranslateType.Position: transform.localPosition = vector; break;
- case TranslateType.Rotation: transform.localRotation = Quaternion.Euler(vector); break;
- case TranslateType.Scale: transform.localScale = vector; break;
- }
+ PlusMinusFloat(ref input.z, amount, multByTime);
GUILayout.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) });
- var input = amount.ToString("F3");
- input = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(40) });
- if (float.TryParse(input, out float f))
+ var amountInput = amount.ToString("F3");
+ amountInput = GUILayout.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) });
+ if (float.TryParse(amountInput, out float f))
{
amount = f;
}
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUILayout.EndHorizontal();
+
+ return input;
}
private void PlusMinusFloat(ref float f, float amount, bool multByTime)
@@ -523,7 +644,5 @@ namespace Explorer
f += multByTime ? amount * Time.deltaTime : amount;
}
}
-
-
}
}