mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-18 09:07:51 +08:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
9a059c1056 | |||
ffb6cad8c2 | |||
d0a4863139 | |||
bb8837d58c | |||
a236b272c1 | |||
18de1eaf1c | |||
b1264c6912 | |||
9836566e55 |
13
README.md
13
README.md
@ -14,10 +14,9 @@
|
|||||||
<img src="https://img.shields.io/github/downloads/sinai-dev/CppExplorer/total.svg" />
|
<img src="https://img.shields.io/github/downloads/sinai-dev/CppExplorer/total.svg" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
### Known issue
|
### Known issues
|
||||||
Due to limitations with [Il2CppAssemblyUnhollower](https://github.com/knah/Il2CppAssemblyUnhollower)'s Unstripping, CppExplorer may encounter a `MissingMethodException` when trying to use certain UnityEngine methods.
|
* CppExplorer may experience a `MissingMethodException` when trying to use certain UnityEngine methods. If you experience this, please open an issue and I will do my best to fix it.
|
||||||
|
* Scrolling with mouse wheel in the CppExplorer menu may not work on all games at the moment.
|
||||||
Since version [1.5.4](https://github.com/sinai-dev/CppExplorer/releases/tag/1.5.4), CppExplorer manually unstrips most of these methods itself. If you encounter more methods which failed unstripping, please let me know by opening an issue and I will do my best to fix it.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Scene hierarchy explorer
|
* Scene hierarchy explorer
|
||||||
@ -45,7 +44,7 @@ Requires [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) to be ins
|
|||||||
* A simple menu which allows you to traverse the Transform heirarchy of the scene.
|
* A simple menu which allows you to traverse the Transform heirarchy of the scene.
|
||||||
* Click on a GameObject to set it as the current path, or <b>Inspect</b> it to send it to an Inspector Window.
|
* Click on a GameObject to set it as the current path, or <b>Inspect</b> it to send it to an Inspector Window.
|
||||||
|
|
||||||
[](https://i.imgur.com/2b0q0jL.png)
|
[](https://i.imgur.com/BzTOCvp.png)
|
||||||
|
|
||||||
### Inspectors
|
### Inspectors
|
||||||
|
|
||||||
@ -60,7 +59,7 @@ CppExplorer has two main inspector modes: <b>GameObject Inspector</b>, and <b>Re
|
|||||||
* Allows you to see the children and components on a GameObject.
|
* Allows you to see the children and components on a GameObject.
|
||||||
* Can use some basic GameObject Controls such as translating and rotating the object, destroy it, clone it, etc.
|
* Can use some basic GameObject Controls such as translating and rotating the object, destroy it, clone it, etc.
|
||||||
|
|
||||||
[](https://i.imgur.com/JTxqlx4.png)
|
[](https://i.imgur.com/DiDvl0Q.png)
|
||||||
|
|
||||||
### Reflection Inspector
|
### Reflection Inspector
|
||||||
|
|
||||||
@ -68,7 +67,7 @@ CppExplorer has two main inspector modes: <b>GameObject Inspector</b>, and <b>Re
|
|||||||
* Allows you to inspect Properties, Fields and basic Methods, as well as set primitive values and evaluate primitive methods.
|
* Allows you to inspect Properties, Fields and basic Methods, as well as set primitive values and evaluate primitive methods.
|
||||||
* Can search and filter members for the ones you are interested in.
|
* Can search and filter members for the ones you are interested in.
|
||||||
|
|
||||||
[](https://i.imgur.com/iq92m0l.png)
|
[](https://i.imgur.com/Pq127XD.png)
|
||||||
|
|
||||||
### Object Search
|
### Object Search
|
||||||
|
|
||||||
|
@ -137,6 +137,22 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
holder = new CacheEnum();
|
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))
|
else if (ReflectionHelpers.IsArray(valueType) || ReflectionHelpers.IsList(valueType))
|
||||||
{
|
{
|
||||||
holder = new CacheList();
|
holder = new CacheList();
|
||||||
|
87
src/CachedObjects/Struct/CacheColor.cs
Normal file
87
src/CachedObjects/Struct/CacheColor.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Explorer
|
||||||
|
{
|
||||||
|
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=yellow>Color</color>: {((Color)Value).ToString()}", 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(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("G:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
g = GUILayout.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("B:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
b = GUILayout.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("A:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
a = GUILayout.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
// draw set value button
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
SetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public class CachePrimitive : CacheObjectBase
|
public class CachePrimitive : CacheObjectBase
|
||||||
{
|
{
|
||||||
public enum PrimitiveTypes
|
public enum Types
|
||||||
{
|
{
|
||||||
Bool,
|
Bool,
|
||||||
Double,
|
Double,
|
||||||
@ -20,20 +20,9 @@ namespace Explorer
|
|||||||
|
|
||||||
private string m_valueToString;
|
private string m_valueToString;
|
||||||
|
|
||||||
public PrimitiveTypes PrimitiveType;
|
public Types PrimitiveType;
|
||||||
|
|
||||||
public MethodInfo ParseMethod
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (m_parseMethod == null)
|
|
||||||
{
|
|
||||||
m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) });
|
|
||||||
}
|
|
||||||
return m_parseMethod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) }));
|
||||||
private MethodInfo m_parseMethod;
|
private MethodInfo m_parseMethod;
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
@ -41,58 +30,39 @@ namespace Explorer
|
|||||||
if (Value == null)
|
if (Value == null)
|
||||||
{
|
{
|
||||||
// this must mean it is a string. No other primitive type should be nullable.
|
// this must mean it is a string. No other primitive type should be nullable.
|
||||||
PrimitiveType = PrimitiveTypes.String;
|
PrimitiveType = Types.String;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_valueToString = Value.ToString();
|
m_valueToString = Value.ToString();
|
||||||
var type = Value.GetType();
|
|
||||||
|
|
||||||
|
var type = Value.GetType();
|
||||||
if (type == typeof(bool))
|
if (type == typeof(bool))
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.Bool;
|
PrimitiveType = Types.Bool;
|
||||||
}
|
}
|
||||||
else if (type == typeof(double))
|
else if (type == typeof(double))
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.Double;
|
PrimitiveType = Types.Double;
|
||||||
}
|
}
|
||||||
else if (type == typeof(float))
|
else if (type == typeof(float))
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.Float;
|
PrimitiveType = Types.Float;
|
||||||
}
|
|
||||||
else if (IsInteger(type))
|
|
||||||
{
|
|
||||||
PrimitiveType = PrimitiveTypes.Int;
|
|
||||||
}
|
}
|
||||||
else if (type == typeof(char))
|
else if (type == typeof(char))
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.Char;
|
PrimitiveType = Types.Char;
|
||||||
|
}
|
||||||
|
else if (typeof(int).IsAssignableFrom(type))
|
||||||
|
{
|
||||||
|
PrimitiveType = Types.Int;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.String;
|
PrimitiveType = Types.String;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsInteger(Type type)
|
|
||||||
{
|
|
||||||
// For our purposes, all types of int can be treated the same, including IntPtr.
|
|
||||||
return _integerTypes.Contains(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly HashSet<Type> _integerTypes = new HashSet<Type>
|
|
||||||
{
|
|
||||||
typeof(int),
|
|
||||||
typeof(uint),
|
|
||||||
typeof(short),
|
|
||||||
typeof(ushort),
|
|
||||||
typeof(long),
|
|
||||||
typeof(ulong),
|
|
||||||
typeof(byte),
|
|
||||||
typeof(sbyte),
|
|
||||||
typeof(IntPtr)
|
|
||||||
};
|
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
@ -102,11 +72,10 @@ namespace Explorer
|
|||||||
|
|
||||||
public override void DrawValue(Rect window, float width)
|
public override void DrawValue(Rect window, float width)
|
||||||
{
|
{
|
||||||
if (PrimitiveType == PrimitiveTypes.Bool)
|
if (PrimitiveType == Types.Bool)
|
||||||
{
|
{
|
||||||
var b = (bool)Value;
|
var b = (bool)Value;
|
||||||
var color = $"<color={(b ? "lime>" : "red>")}";
|
var label = $"<color={(b ? "lime" : "red")}>{b}</color>";
|
||||||
var label = $"{color}{b}</color>";
|
|
||||||
|
|
||||||
if (CanWrite)
|
if (CanWrite)
|
||||||
{
|
{
|
||||||
@ -150,7 +119,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetValueFromInput(string value)
|
public void SetValueFromInput(string valueString)
|
||||||
{
|
{
|
||||||
if (MemInfo == null)
|
if (MemInfo == null)
|
||||||
{
|
{
|
||||||
@ -158,16 +127,15 @@ namespace Explorer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PrimitiveType == PrimitiveTypes.String)
|
if (PrimitiveType == Types.String)
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = valueString;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var val = ParseMethod.Invoke(null, new object[] { value });
|
Value = ParseMethod.Invoke(null, new object[] { valueString });
|
||||||
Value = val;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
78
src/CachedObjects/Struct/CacheQuaternion.cs
Normal file
78
src/CachedObjects/Struct/CacheQuaternion.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
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 string x = "0";
|
||||||
|
private string y = "0";
|
||||||
|
private string z = "0";
|
||||||
|
|
||||||
|
public override void UpdateValue()
|
||||||
|
{
|
||||||
|
base.UpdateValue();
|
||||||
|
|
||||||
|
var euler = ((Quaternion)Value).eulerAngles;
|
||||||
|
|
||||||
|
x = euler.x.ToString();
|
||||||
|
y = euler.y.ToString();
|
||||||
|
z = euler.z.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawValue(Rect window, float width)
|
||||||
|
{
|
||||||
|
GUILayout.Label($"<color=yellow>Quaternion</color>: {((Quaternion)Value).eulerAngles.ToString()}", 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(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
z = GUILayout.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
// draw set value button
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
src/CachedObjects/Struct/CacheRect.cs
Normal file
87
src/CachedObjects/Struct/CacheRect.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Explorer
|
||||||
|
{
|
||||||
|
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($"<color=yellow>Rect</color>: {((Rect)Value).ToString()}", 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(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
w = GUILayout.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("H:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
h = GUILayout.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
// draw set value button
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
142
src/CachedObjects/Struct/CacheVector.cs
Normal file
142
src/CachedObjects/Struct/CacheVector.cs
Normal file
@ -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($"<color=yellow>Vector{VectorSize}</color>: {(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(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
|
||||||
|
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(120) });
|
||||||
|
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(120) });
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw set value button
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Space(whitespace);
|
||||||
|
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ namespace Explorer
|
|||||||
public class CppExplorer : MelonMod
|
public class CppExplorer : MelonMod
|
||||||
{
|
{
|
||||||
public const string GUID = "com.sinai.cppexplorer";
|
public const string GUID = "com.sinai.cppexplorer";
|
||||||
public const string VERSION = "1.5.5";
|
public const string VERSION = "1.5.7";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
|
|
||||||
public const string NAME = "CppExplorer"
|
public const string NAME = "CppExplorer"
|
||||||
|
@ -120,17 +120,21 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="CachedObjects\CacheDictionary.cs" />
|
<Compile Include="CachedObjects\Struct\CacheColor.cs" />
|
||||||
<Compile Include="CachedObjects\CacheEnum.cs" />
|
<Compile Include="CachedObjects\Object\CacheDictionary.cs" />
|
||||||
<Compile Include="CachedObjects\CacheGameObject.cs" />
|
<Compile Include="CachedObjects\Struct\CacheEnum.cs" />
|
||||||
<Compile Include="CachedObjects\CacheList.cs" />
|
<Compile Include="CachedObjects\Object\CacheGameObject.cs" />
|
||||||
<Compile Include="CachedObjects\CachePrimitive.cs" />
|
<Compile Include="CachedObjects\Object\CacheList.cs" />
|
||||||
<Compile Include="CachedObjects\CacheOther.cs" />
|
<Compile Include="CachedObjects\Struct\CachePrimitive.cs" />
|
||||||
<Compile Include="CachedObjects\CacheMethod.cs" />
|
<Compile Include="CachedObjects\Other\CacheOther.cs" />
|
||||||
|
<Compile Include="CachedObjects\Other\CacheMethod.cs" />
|
||||||
|
<Compile Include="CachedObjects\Struct\CacheQuaternion.cs" />
|
||||||
|
<Compile Include="CachedObjects\Struct\CacheVector.cs" />
|
||||||
|
<Compile Include="CachedObjects\Struct\CacheRect.cs" />
|
||||||
<Compile Include="CppExplorer.cs" />
|
<Compile Include="CppExplorer.cs" />
|
||||||
<Compile Include="Extensions\ReflectionExtensions.cs" />
|
<Compile Include="Extensions\ReflectionExtensions.cs" />
|
||||||
<Compile Include="Unstripping\GUIUnstrip.cs" />
|
<Compile Include="UnstripFixes\GUIUnstrip.cs" />
|
||||||
<Compile Include="Unstripping\ScrollViewStateUnstrip.cs" />
|
<Compile Include="UnstripFixes\ScrollViewStateUnstrip.cs" />
|
||||||
<Compile Include="Extensions\UnityExtensions.cs" />
|
<Compile Include="Extensions\UnityExtensions.cs" />
|
||||||
<Compile Include="Helpers\PageHelper.cs" />
|
<Compile Include="Helpers\PageHelper.cs" />
|
||||||
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
||||||
@ -138,8 +142,8 @@
|
|||||||
<Compile Include="Helpers\UnityHelpers.cs" />
|
<Compile Include="Helpers\UnityHelpers.cs" />
|
||||||
<Compile Include="MainMenu\InspectUnderMouse.cs" />
|
<Compile Include="MainMenu\InspectUnderMouse.cs" />
|
||||||
<Compile Include="CachedObjects\CacheObjectBase.cs" />
|
<Compile Include="CachedObjects\CacheObjectBase.cs" />
|
||||||
<Compile Include="Unstripping\SliderHandlerUnstrip.cs" />
|
<Compile Include="UnstripFixes\SliderHandlerUnstrip.cs" />
|
||||||
<Compile Include="Unstripping\UnstripExtensions.cs" />
|
<Compile Include="UnstripFixes\UnstripExtensions.cs" />
|
||||||
<Compile Include="Windows\ResizeDrag.cs" />
|
<Compile Include="Windows\ResizeDrag.cs" />
|
||||||
<Compile Include="Windows\TabViewWindow.cs" />
|
<Compile Include="Windows\TabViewWindow.cs" />
|
||||||
<Compile Include="Windows\UIWindow.cs" />
|
<Compile Include="Windows\UIWindow.cs" />
|
||||||
|
@ -14,7 +14,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public class ConsolePage : WindowPage
|
public class ConsolePage : WindowPage
|
||||||
{
|
{
|
||||||
public override string Name { get => "C# Console"; set => base.Name = value; }
|
public override string Name { get => "C# Console"; }
|
||||||
|
|
||||||
private ScriptEvaluator _evaluator;
|
private ScriptEvaluator _evaluator;
|
||||||
private readonly StringBuilder _sb = new StringBuilder();
|
private readonly StringBuilder _sb = new StringBuilder();
|
||||||
|
@ -12,19 +12,22 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public static ScenePage Instance;
|
public static ScenePage Instance;
|
||||||
|
|
||||||
public override string Name { get => "Scene Explorer"; set => base.Name = value; }
|
public override string Name { get => "Scene Explorer"; }
|
||||||
|
|
||||||
public PageHelper Pages = new PageHelper();
|
public PageHelper Pages = new PageHelper();
|
||||||
|
|
||||||
private float m_timeOfLastUpdate = -1f;
|
private float m_timeOfLastUpdate = -1f;
|
||||||
|
private const int PASSIVE_UPDATE_INTERVAL = 1;
|
||||||
|
|
||||||
|
private static bool m_getRootObjectsFailed;
|
||||||
|
|
||||||
// ----- Holders for GUI elements ----- //
|
// ----- Holders for GUI elements ----- //
|
||||||
|
|
||||||
private string m_currentScene = "";
|
private static string m_currentScene = "";
|
||||||
|
|
||||||
// gameobject list
|
// gameobject list
|
||||||
private Transform m_currentTransform;
|
private Transform m_currentTransform;
|
||||||
private List<GameObjectCache> m_objectList = new List<GameObjectCache>();
|
private readonly List<GameObjectCache> m_objectList = new List<GameObjectCache>();
|
||||||
|
|
||||||
// search bar
|
// search bar
|
||||||
private bool m_searching = false;
|
private bool m_searching = false;
|
||||||
@ -44,64 +47,6 @@ namespace Explorer
|
|||||||
SetTransformTarget(null);
|
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<GameObjectCache>();
|
|
||||||
|
|
||||||
var 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
|
|
||||||
{
|
|
||||||
var scene = SceneManager.GetSceneByName(m_currentScene);
|
|
||||||
|
|
||||||
var list = new Il2CppSystem.Collections.Generic.List<GameObject>
|
|
||||||
{
|
|
||||||
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)
|
public void SetTransformTarget(Transform t)
|
||||||
{
|
{
|
||||||
m_currentTransform = t;
|
m_currentTransform = t;
|
||||||
@ -109,8 +54,7 @@ namespace Explorer
|
|||||||
if (m_searching)
|
if (m_searching)
|
||||||
CancelSearch();
|
CancelSearch();
|
||||||
|
|
||||||
m_timeOfLastUpdate = -1f;
|
Update_Impl(true);
|
||||||
Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TraverseUp()
|
public void TraverseUp()
|
||||||
@ -135,23 +79,118 @@ namespace Explorer
|
|||||||
public void CancelSearch()
|
public void CancelSearch()
|
||||||
{
|
{
|
||||||
m_searching = false;
|
m_searching = false;
|
||||||
|
|
||||||
|
if (m_getRootObjectsFailed && !m_currentTransform)
|
||||||
|
{
|
||||||
|
GetRootObjectsManual_Impl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GameObjectCache> SearchSceneObjects(string _search)
|
public List<GameObjectCache> SearchSceneObjects(string _search)
|
||||||
{
|
{
|
||||||
var matches = new List<GameObjectCache>();
|
var matches = new List<GameObjectCache>();
|
||||||
|
|
||||||
foreach (var obj in Resources.FindObjectsOfTypeAll<GameObject>())
|
foreach (var obj in Resources.FindObjectsOfTypeAll(ReflectionHelpers.GameObjectType))
|
||||||
{
|
{
|
||||||
if (obj.name.ToLower().Contains(_search.ToLower()) && obj.scene.name == m_currentScene)
|
var go = obj.TryCast<GameObject>();
|
||||||
|
if (go.name.ToLower().Contains(_search.ToLower()) && go.scene.name == m_currentScene)
|
||||||
{
|
{
|
||||||
matches.Add(new GameObjectCache(obj));
|
matches.Add(new GameObjectCache(go));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return matches;
|
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(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 (!manual && m_getRootObjectsFailed) return;
|
||||||
|
|
||||||
|
if (!manual)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var scene = SceneManager.GetSceneByName(m_currentScene);
|
||||||
|
|
||||||
|
allTransforms.AddRange(scene.GetRootGameObjects()
|
||||||
|
.Select(it => it.transform));
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
m_getRootObjectsFailed = true;
|
||||||
|
allTransforms.AddRange(GetRootObjectsManual_Impl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
m_objectList.Add(new GameObjectCache(child.gameObject));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<Transform> GetRootObjectsManual_Impl()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var array = Resources.FindObjectsOfTypeAll(ReflectionHelpers.TransformType);
|
||||||
|
|
||||||
|
var list = new List<Transform>();
|
||||||
|
foreach (var obj in array)
|
||||||
|
{
|
||||||
|
var transform = obj.TryCast<Transform>();
|
||||||
|
if (transform.parent == null && transform.gameObject.scene.name == m_currentScene)
|
||||||
|
{
|
||||||
|
list.Add(transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MelonLogger.Log("Exception getting root scene objects (manual): "
|
||||||
|
+ e.GetType() + ", " + e.Message + "\r\n"
|
||||||
|
+ e.StackTrace);
|
||||||
|
return new Transform[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --------- GUI Draw Function --------- //
|
// --------- GUI Draw Function --------- //
|
||||||
|
|
||||||
public override void DrawWindow()
|
public override void DrawWindow()
|
||||||
@ -251,8 +290,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
Pages.TurnPage(Turn.Left, ref this.scroll);
|
Pages.TurnPage(Turn.Left, ref this.scroll);
|
||||||
|
|
||||||
m_timeOfLastUpdate = -1f;
|
Update_Impl(true);
|
||||||
Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pages.CurrentPageLabel();
|
Pages.CurrentPageLabel();
|
||||||
@ -261,8 +299,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
Pages.TurnPage(Turn.Right, ref this.scroll);
|
Pages.TurnPage(Turn.Right, ref this.scroll);
|
||||||
|
|
||||||
m_timeOfLastUpdate = -1f;
|
Update_Impl(true);
|
||||||
Update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,12 +329,24 @@ namespace Explorer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUILayout.Label("Scene Root GameObjects:", null);
|
GUILayout.Label("Scene Root GameObjects:", null);
|
||||||
|
|
||||||
|
if (m_getRootObjectsFailed)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("Update Root Object List (auto-update failed!)", null))
|
||||||
|
{
|
||||||
|
Update_Impl(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_objectList.Count > 0)
|
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)
|
if (!obj.RefGameObject)
|
||||||
{
|
{
|
||||||
string label = "<color=red><i>null";
|
string label = "<color=red><i>null";
|
||||||
|
@ -13,7 +13,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public static SearchPage Instance;
|
public static SearchPage Instance;
|
||||||
|
|
||||||
public override string Name { get => "Object Search"; set => base.Name = value; }
|
public override string Name { get => "Object Search"; }
|
||||||
|
|
||||||
private string m_searchInput = "";
|
private string m_searchInput = "";
|
||||||
private string m_typeInput = "";
|
private string m_typeInput = "";
|
||||||
@ -318,7 +318,8 @@ namespace Explorer
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchType == ReflectionHelpers.ComponentType && ReflectionHelpers.TransformType.IsAssignableFrom(obj.GetIl2CppType()))
|
if (searchType.FullName == ReflectionHelpers.ComponentType.FullName
|
||||||
|
&& ReflectionHelpers.TransformType.IsAssignableFrom(obj.GetIl2CppType()))
|
||||||
{
|
{
|
||||||
// Transforms shouldn't really be counted as Components, skip them.
|
// Transforms shouldn't really be counted as Components, skip them.
|
||||||
// They're more akin to GameObjects.
|
// They're more akin to GameObjects.
|
||||||
|
@ -9,7 +9,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public abstract class WindowPage
|
public abstract class WindowPage
|
||||||
{
|
{
|
||||||
public virtual string Name { get; set; }
|
public virtual string Name { get; }
|
||||||
|
|
||||||
public Vector2 scroll = Vector2.zero;
|
public Vector2 scroll = Vector2.zero;
|
||||||
|
|
||||||
|
@ -13,13 +13,6 @@ using Harmony;
|
|||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
// This is a copy+paste of UnityEngine source code, fixed for Il2Cpp.
|
|
||||||
// Taken from dnSpy output using Unity 2018.4.20.
|
|
||||||
|
|
||||||
// Subject to Unity's License and ToS.
|
|
||||||
// https://unity3d.com/legal/terms-of-service
|
|
||||||
// https://unity3d.com/legal/terms-of-service/software
|
|
||||||
|
|
||||||
public class GUIUnstrip
|
public class GUIUnstrip
|
||||||
{
|
{
|
||||||
public static int s_ScrollControlId;
|
public static int s_ScrollControlId;
|
||||||
@ -41,9 +34,6 @@ namespace Explorer
|
|||||||
|
|
||||||
// ======= public methods ======= //
|
// ======= public methods ======= //
|
||||||
|
|
||||||
// Fix for GUILayoutUtility.GetLastRect().
|
|
||||||
// Calls UnstripExtensions.GetLastUnstripped().
|
|
||||||
|
|
||||||
public static Rect GetLastRect()
|
public static Rect GetLastRect()
|
||||||
{
|
{
|
||||||
EventType type = Event.current.type;
|
EventType type = Event.current.type;
|
||||||
@ -59,8 +49,6 @@ namespace Explorer
|
|||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple unstrips for HorizontalScrollbar and VerticalScrollbar, they just call the Scroller unstrip.
|
|
||||||
|
|
||||||
public static float HorizontalScrollbar(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style)
|
public static float HorizontalScrollbar(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style)
|
||||||
{
|
{
|
||||||
return Scroller_Impl(position, value, size, leftValue, rightValue, style,
|
return Scroller_Impl(position, value, size, leftValue, rightValue, style,
|
||||||
@ -80,7 +68,6 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fix for BeginScrollView.
|
// Fix for BeginScrollView.
|
||||||
// Uses several manually unstripped methods.
|
|
||||||
|
|
||||||
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
||||||
{
|
{
|
||||||
@ -98,7 +85,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try manual unstripping implementation.
|
// Try manual implementation.
|
||||||
if (!ManualUnstripFailed)
|
if (!ManualUnstripFailed)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -107,7 +94,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
MelonLogger.Log("Exception on GUIUnstrip.BeginScrollView_Impl: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace);
|
MelonLogger.Log("Exception on GUIUnstrip.BeginScrollView_ImplLayout: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace);
|
||||||
|
|
||||||
ManualUnstripFailed = true;
|
ManualUnstripFailed = true;
|
||||||
return scroll;
|
return scroll;
|
||||||
@ -136,8 +123,6 @@ namespace Explorer
|
|||||||
|
|
||||||
// ======= private methods ======= //
|
// ======= private methods ======= //
|
||||||
|
|
||||||
// Actual unstrip of GUILayout.BeginScrollView()
|
|
||||||
|
|
||||||
private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical,
|
private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical,
|
||||||
GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options)
|
GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options)
|
||||||
{
|
{
|
||||||
@ -171,8 +156,6 @@ namespace Explorer
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual unstrip of GUI.BeginScrollView()
|
|
||||||
|
|
||||||
private static Vector2 BeginScrollView_Impl(Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal,
|
private static Vector2 BeginScrollView_Impl(Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal,
|
||||||
bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background)
|
bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background)
|
||||||
{
|
{
|
||||||
@ -204,7 +187,7 @@ namespace Explorer
|
|||||||
|
|
||||||
ScrollStack.Push(scrollViewState);
|
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;
|
EventType type = Event.current.type;
|
||||||
if (type != EventType.Layout)
|
if (type != EventType.Layout)
|
||||||
{
|
{
|
||||||
@ -296,8 +279,6 @@ namespace Explorer
|
|||||||
return scrollPosition;
|
return scrollPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual unstrip of GUI.EndScrollView()
|
|
||||||
|
|
||||||
private static void EndScrollView_Impl(bool handleScrollWheel)
|
private static void EndScrollView_Impl(bool handleScrollWheel)
|
||||||
{
|
{
|
||||||
GUIUtility.CheckOnGUI();
|
GUIUtility.CheckOnGUI();
|
||||||
@ -336,8 +317,6 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual unstrip of GUI.Scroller
|
|
||||||
|
|
||||||
private static float Scroller_Impl(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb, GUIStyle leftButton, GUIStyle rightButton, bool horiz)
|
private static float Scroller_Impl(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb, GUIStyle leftButton, GUIStyle rightButton, bool horiz)
|
||||||
{
|
{
|
||||||
GUIUtility.CheckOnGUI();
|
GUIUtility.CheckOnGUI();
|
||||||
@ -384,8 +363,6 @@ namespace Explorer
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual unstrip of GUI.Slider
|
|
||||||
|
|
||||||
public static float Slider(Rect position, float value, float size, float start, float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id)
|
public static float Slider(Rect position, float value, float size, float start, float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id)
|
||||||
{
|
{
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
@ -396,8 +373,6 @@ namespace Explorer
|
|||||||
return sliderHandler.Handle();
|
return sliderHandler.Handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual unstrip of GUI.ScrollerRepeatButton
|
|
||||||
|
|
||||||
private static bool ScrollerRepeatButton_Impl(int scrollerID, Rect rect, GUIStyle style)
|
private static bool ScrollerRepeatButton_Impl(int scrollerID, Rect rect, GUIStyle style)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
@ -9,13 +9,6 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
// This is a copy+paste of UnityEngine source code, fixed for Il2Cpp.
|
|
||||||
// Taken from dnSpy output using Unity 2018.4.20.
|
|
||||||
|
|
||||||
// Subject to Unity's License and ToS.
|
|
||||||
// https://unity3d.com/legal/terms-of-service
|
|
||||||
// https://unity3d.com/legal/terms-of-service/software
|
|
||||||
|
|
||||||
public class ScrollViewStateUnstrip
|
public class ScrollViewStateUnstrip
|
||||||
{
|
{
|
||||||
public Rect position;
|
public Rect position;
|
||||||
@ -24,9 +17,6 @@ namespace Explorer
|
|||||||
public Vector2 scrollPosition;
|
public Vector2 scrollPosition;
|
||||||
public bool apply;
|
public bool apply;
|
||||||
|
|
||||||
// The code below is not unstripped.
|
|
||||||
// This is a custom dictionary to allow for the manual implementation.
|
|
||||||
|
|
||||||
public static Dictionary<IntPtr, ScrollViewStateUnstrip> Dict = new Dictionary<IntPtr, ScrollViewStateUnstrip>();
|
public static Dictionary<IntPtr, ScrollViewStateUnstrip> Dict = new Dictionary<IntPtr, ScrollViewStateUnstrip>();
|
||||||
|
|
||||||
public static ScrollViewStateUnstrip FromPointer(IntPtr ptr)
|
public static ScrollViewStateUnstrip FromPointer(IntPtr ptr)
|
@ -8,13 +8,6 @@ using UnhollowerRuntimeLib;
|
|||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
// This is a copy+paste of UnityEngine source code, fixed for Il2Cpp.
|
|
||||||
// Taken from dnSpy output using Unity 2018.4.20.
|
|
||||||
|
|
||||||
// Subject to Unity's License and ToS.
|
|
||||||
// https://unity3d.com/legal/terms-of-service
|
|
||||||
// https://unity3d.com/legal/terms-of-service/software
|
|
||||||
|
|
||||||
public struct SliderHandlerUnstrip
|
public struct SliderHandlerUnstrip
|
||||||
{
|
{
|
||||||
private readonly Rect position;
|
private readonly Rect position;
|
27
src/UnstripFixes/UnstripExtensions.cs
Normal file
27
src/UnstripFixes/UnstripExtensions.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Explorer
|
||||||
|
{
|
||||||
|
public static class UnstripExtensions
|
||||||
|
{
|
||||||
|
public static Rect GetLastUnstripped(this GUILayoutGroup group)
|
||||||
|
{
|
||||||
|
Rect result;
|
||||||
|
if (group.m_Cursor > 0 && group.m_Cursor <= group.entries.Count)
|
||||||
|
{
|
||||||
|
GUILayoutEntry guilayoutEntry = group.entries[group.m_Cursor - 1];
|
||||||
|
result = guilayoutEntry.rect;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = GUILayoutEntry.kDummyRect;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,51 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
|
||||||
{
|
|
||||||
// This is a copy+paste of UnityEngine source code, fixed for Il2Cpp.
|
|
||||||
// Taken from dnSpy output using Unity 2018.4.20.
|
|
||||||
|
|
||||||
// Subject to Unity's License and ToS.
|
|
||||||
// https://unity3d.com/legal/terms-of-service
|
|
||||||
// https://unity3d.com/legal/terms-of-service/software
|
|
||||||
|
|
||||||
public static class UnstripExtensions
|
|
||||||
{
|
|
||||||
// This is a manual unstrip of GUILayoutGroup.GetLast().
|
|
||||||
// I'm using it as an Extension because it's easier this way.
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,9 +29,17 @@ namespace Explorer
|
|||||||
private Vector2 m_compScroll = Vector2.zero;
|
private Vector2 m_compScroll = Vector2.zero;
|
||||||
private PageHelper CompPages = new PageHelper();
|
private PageHelper CompPages = new PageHelper();
|
||||||
|
|
||||||
|
private readonly Vector3[] m_cachedInput = new Vector3[3];
|
||||||
private float m_translateAmount = 0.3f;
|
private float m_translateAmount = 0.3f;
|
||||||
private float m_rotateAmount = 50f;
|
private float m_rotateAmount = 50f;
|
||||||
private float m_scaleAmount = 0.1f;
|
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<Component> m_cachedDestroyList = new List<Component>();
|
private readonly List<Component> m_cachedDestroyList = new List<Component>();
|
||||||
//private string m_addComponentInput = "";
|
//private string m_addComponentInput = "";
|
||||||
@ -73,12 +81,29 @@ namespace Explorer
|
|||||||
|
|
||||||
m_name = m_object.name;
|
m_name = m_object.name;
|
||||||
m_scene = string.IsNullOrEmpty(m_object.scene.name)
|
m_scene = string.IsNullOrEmpty(m_object.scene.name)
|
||||||
? "None"
|
? "None (Asset/Resource)"
|
||||||
: m_object.scene.name;
|
: m_object.scene.name;
|
||||||
|
|
||||||
|
CacheTransformValues();
|
||||||
|
|
||||||
Update();
|
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()
|
public override void Update()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -88,28 +113,37 @@ namespace Explorer
|
|||||||
throw new Exception("Object is null!");
|
throw new Exception("Object is null!");
|
||||||
}
|
}
|
||||||
|
|
||||||
var list = new List<Transform>();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update child objects
|
||||||
|
var childList = new List<Transform>();
|
||||||
for (int i = 0; i < m_object.transform.childCount; i++)
|
for (int i = 0; i < m_object.transform.childCount; i++)
|
||||||
{
|
{
|
||||||
list.Add(m_object.transform.GetChild(i));
|
childList.Add(m_object.transform.GetChild(i));
|
||||||
}
|
}
|
||||||
list.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
childList.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
||||||
m_children = list.ToArray();
|
m_children = childList.ToArray();
|
||||||
|
|
||||||
ChildPages.ItemCount = m_children.Length;
|
ChildPages.ItemCount = m_children.Length;
|
||||||
|
|
||||||
var list2 = new List<Component>();
|
// update components
|
||||||
foreach (var comp in m_object.GetComponents(ReflectionHelpers.ComponentType))
|
var compList = new Il2CppSystem.Collections.Generic.List<Component>();
|
||||||
{
|
m_object.GetComponentsInternal(ReflectionHelpers.ComponentType, true, false, true, false, compList);
|
||||||
var ilType = comp.GetIl2CppType();
|
|
||||||
if (ilType == ReflectionHelpers.TransformType)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
list2.Add(comp);
|
m_components = compList.ToArray();
|
||||||
}
|
|
||||||
m_components = list2.ToArray();
|
|
||||||
|
|
||||||
CompPages.ItemCount = m_components.Length;
|
CompPages.ItemCount = m_components.Length;
|
||||||
}
|
}
|
||||||
@ -412,6 +446,16 @@ namespace Explorer
|
|||||||
m_object.hideFlags |= HideFlags.DontUnloadUnusedAsset;
|
m_object.hideFlags |= HideFlags.DontUnloadUnusedAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lbl = m_freeze ? "<color=lime>Unfreeze</color>" : "<color=orange>Freeze Pos/Rot</color>";
|
||||||
|
if (GUILayout.Button(lbl, new GUILayoutOption[] { GUILayout.Width(110) }))
|
||||||
|
{
|
||||||
|
m_freeze = !m_freeze;
|
||||||
|
if (m_freeze)
|
||||||
|
{
|
||||||
|
UpdateFreeze();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
|
|
||||||
@ -436,10 +480,52 @@ namespace Explorer
|
|||||||
|
|
||||||
GUILayout.BeginVertical(GUI.skin.box, null);
|
GUILayout.BeginVertical(GUI.skin.box, null);
|
||||||
|
|
||||||
var t = m_object.transform;
|
m_cachedInput[0] = TranslateControl(TranslateType.Position, ref m_translateAmount, false);
|
||||||
TranslateControl(t, TranslateType.Position, ref m_translateAmount, false);
|
m_cachedInput[1] = TranslateControl(TranslateType.Rotation, ref m_rotateAmount, true);
|
||||||
TranslateControl(t, TranslateType.Rotation, ref m_rotateAmount, true);
|
m_cachedInput[2] = TranslateControl(TranslateType.Scale, ref m_scaleAmount, false);
|
||||||
TranslateControl(t, TranslateType.Scale, ref m_scaleAmount, false);
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
if (GUILayout.Button("<color=lime>Apply to Transform</color>", 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("<color=lime>Update from Transform</color>", 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, "<color=" + (b ? "lime" : "red") + ">Use local transform values?</color>", null);
|
||||||
|
if (b != m_localContext)
|
||||||
|
{
|
||||||
|
m_localContext = b;
|
||||||
|
CacheTransformValues();
|
||||||
|
if (m_freeze)
|
||||||
|
{
|
||||||
|
UpdateFreeze();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GUILayout.EndVertical();
|
GUILayout.EndVertical();
|
||||||
|
|
||||||
@ -453,6 +539,30 @@ namespace Explorer
|
|||||||
GUILayout.EndVertical();
|
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 = "<color=";
|
||||||
|
lbl += value ? "lime" : "red";
|
||||||
|
lbl += $">{message}</color>";
|
||||||
|
|
||||||
|
value = GUILayout.Toggle(value, lbl, null);
|
||||||
|
}
|
||||||
|
|
||||||
public enum TranslateType
|
public enum TranslateType
|
||||||
{
|
{
|
||||||
Position,
|
Position,
|
||||||
@ -460,50 +570,55 @@ namespace Explorer
|
|||||||
Scale
|
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.BeginHorizontal(null);
|
||||||
GUILayout.Label("<color=cyan><b>" + mode + "</b></color>:", new GUILayoutOption[] { GUILayout.Width(65) });
|
GUILayout.Label($"<color=cyan><b>{(m_localContext ? "Local " : "")}{mode}</b></color>:",
|
||||||
|
new GUILayoutOption[] { GUILayout.Width(m_localContext ? 110 : 65) });
|
||||||
|
|
||||||
Vector3 vector = Vector3.zero;
|
var transform = m_object.transform;
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case TranslateType.Position: vector = transform.localPosition; break;
|
case TranslateType.Position:
|
||||||
case TranslateType.Rotation: vector = transform.localRotation.eulerAngles; break;
|
var pos = m_localContext ? transform.localPosition : transform.position;
|
||||||
case TranslateType.Scale: vector = transform.localScale; break;
|
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();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
Vector3 input = m_cachedInput[(int)mode];
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
||||||
|
|
||||||
GUILayout.Label("<color=cyan>X:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
|
GUILayout.Label("<color=cyan>X:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
|
||||||
PlusMinusFloat(ref vector.x, amount, multByTime);
|
PlusMinusFloat(ref input.x, amount, multByTime);
|
||||||
|
|
||||||
GUILayout.Label("<color=cyan>Y:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
|
GUILayout.Label("<color=cyan>Y:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
|
||||||
PlusMinusFloat(ref vector.y, amount, multByTime);
|
PlusMinusFloat(ref input.y, amount, multByTime);
|
||||||
|
|
||||||
GUILayout.Label("<color=cyan>Z:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
|
GUILayout.Label("<color=cyan>Z:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
|
||||||
PlusMinusFloat(ref vector.z, amount, multByTime);
|
PlusMinusFloat(ref input.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
GUILayout.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) });
|
GUILayout.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
var input = amount.ToString("F3");
|
var amountInput = amount.ToString("F3");
|
||||||
input = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(40) });
|
amountInput = GUILayout.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) });
|
||||||
if (float.TryParse(input, out float f))
|
if (float.TryParse(amountInput, out float f))
|
||||||
{
|
{
|
||||||
amount = f;
|
amount = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlusMinusFloat(ref float f, float amount, bool multByTime)
|
private void PlusMinusFloat(ref float f, float amount, bool multByTime)
|
||||||
@ -523,7 +638,5 @@ namespace Explorer
|
|||||||
f += multByTime ? amount * Time.deltaTime : amount;
|
f += multByTime ? amount * Time.deltaTime : amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Init() { }
|
public override void Init() { }
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
while (TargetTabID >= WindowManager.Windows.Count)
|
while (TargetTabID >= WindowManager.Windows.Count)
|
||||||
|
@ -109,7 +109,7 @@ namespace Explorer
|
|||||||
|
|
||||||
if (!equals && iObj is Il2CppSystem.Object iCurrent && window.Target is Il2CppSystem.Object iTarget)
|
if (!equals && iObj is Il2CppSystem.Object iCurrent && window.Target is Il2CppSystem.Object iTarget)
|
||||||
{
|
{
|
||||||
if (iCurrent.GetIl2CppType() != iTarget.GetIl2CppType())
|
if (iCurrent.GetIl2CppType().FullName != iTarget.GetIl2CppType().FullName)
|
||||||
{
|
{
|
||||||
if (iCurrent is Transform transform)
|
if (iCurrent is Transform transform)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user