mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-22 16:42:38 +08:00
Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
3b71b40843 | |||
1292affe6d | |||
6614762fe8 | |||
d81d6d034b | |||
5dfe3bbf0c | |||
dc81451ce5 | |||
d7ab0a23c6 | |||
1a01c740e2 | |||
040fb1f11a | |||
e44ff9e207 | |||
b5c69fc1ea | |||
4fdb2aacd8 | |||
48e688cb75 | |||
647b0d353d | |||
2b715f3dbe | |||
938a991594 | |||
f00134b283 | |||
3b6b9768fb | |||
5fbfa1b7aa | |||
7d26965c12 | |||
862523399a | |||
0afccadc64 | |||
0e37e8030c | |||
621a9cd72e | |||
56be5414f9 | |||
b8c4be473f | |||
b6966f8836 | |||
ad8c5293a0 | |||
a7165c849c | |||
79f2514109 | |||
4e76eca73a | |||
2f0876466c | |||
fdefc3d567 | |||
64193ff1b0 | |||
a90292f47f | |||
d0bccae50c | |||
bdf08f014f | |||
df8522963e | |||
f6d0acab7b | |||
d4fbc89158 | |||
9e49f09a79 | |||
b9a3ab7439 | |||
03661cdd0b | |||
10f2b7e849 | |||
4602f07c34 |
Binary file not shown.
Binary file not shown.
@ -18,6 +18,8 @@ using UniverseLib.UI;
|
||||
using UniverseLib;
|
||||
using UniverseLib.UI.Models;
|
||||
using UniverseLib.Utility;
|
||||
using HarmonyLib;
|
||||
using UniverseLib.Runtime;
|
||||
|
||||
namespace UnityExplorer.CSConsole
|
||||
{
|
||||
@ -60,6 +62,8 @@ namespace UnityExplorer.CSConsole
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
InitEventSystemPropertyHandlers();
|
||||
|
||||
// Make sure console is supported on this platform
|
||||
try
|
||||
{
|
||||
@ -383,30 +387,81 @@ namespace UnityExplorer.CSConsole
|
||||
RuntimeHelper.StartCoroutine(SetCaretCoroutine(caretPosition));
|
||||
}
|
||||
|
||||
internal static PropertyInfo SelectionGuardProperty => selectionGuardPropInfo ?? GetSelectionGuardPropInfo();
|
||||
|
||||
private static PropertyInfo GetSelectionGuardPropInfo()
|
||||
static void InitEventSystemPropertyHandlers()
|
||||
{
|
||||
selectionGuardPropInfo = typeof(EventSystem).GetProperty("m_SelectionGuard");
|
||||
if (selectionGuardPropInfo == null)
|
||||
selectionGuardPropInfo = typeof(EventSystem).GetProperty("m_selectionGuard");
|
||||
return selectionGuardPropInfo;
|
||||
try
|
||||
{
|
||||
foreach (var member in typeof(EventSystem).GetMembers(AccessTools.all))
|
||||
{
|
||||
if (member.Name == "m_CurrentSelected")
|
||||
{
|
||||
Type backingType;
|
||||
if (member.MemberType == MemberTypes.Property)
|
||||
backingType = (member as PropertyInfo).PropertyType;
|
||||
else
|
||||
backingType = (member as FieldInfo).FieldType;
|
||||
|
||||
usingEventSystemDictionaryMembers = ReflectionUtility.IsDictionary(backingType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Exception checking EventSystem property backing type: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private static PropertyInfo selectionGuardPropInfo;
|
||||
static bool usingEventSystemDictionaryMembers;
|
||||
|
||||
static readonly AmbiguousMemberHandler<EventSystem, GameObject> m_CurrentSelected_Handler_Normal
|
||||
= new(true, true, "m_CurrentSelected", "m_currentSelected");
|
||||
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, GameObject>> m_CurrentSelected_Handler_Dictionary
|
||||
= new(true, true, "m_CurrentSelected", "m_currentSelected");
|
||||
|
||||
static readonly AmbiguousMemberHandler<EventSystem, bool> m_SelectionGuard_Handler_Normal
|
||||
= new(true, true, "m_SelectionGuard", "m_selectionGuard");
|
||||
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, bool>> m_SelectionGuard_Handler_Dictionary
|
||||
= new(true, true, "m_SelectionGuard", "m_selectionGuard");
|
||||
|
||||
static void SetCurrentSelectedGameObject(EventSystem instance, GameObject value)
|
||||
{
|
||||
instance.SetSelectedGameObject(value);
|
||||
|
||||
if (usingEventSystemDictionaryMembers)
|
||||
m_CurrentSelected_Handler_Dictionary.GetValue(instance)[0] = value;
|
||||
else
|
||||
m_CurrentSelected_Handler_Normal.SetValue(instance, value);
|
||||
}
|
||||
|
||||
static void SetSelectionGuard(EventSystem instance, bool value)
|
||||
{
|
||||
if (usingEventSystemDictionaryMembers)
|
||||
m_SelectionGuard_Handler_Dictionary.GetValue(instance)[0] = value;
|
||||
else
|
||||
m_SelectionGuard_Handler_Normal.SetValue(instance, value);
|
||||
}
|
||||
|
||||
private static IEnumerator SetCaretCoroutine(int caretPosition)
|
||||
{
|
||||
var color = Input.Component.selectionColor;
|
||||
color.a = 0f;
|
||||
Input.Component.selectionColor = color;
|
||||
try { EventSystem.current.SetSelectedGameObject(null, null); } catch { }
|
||||
yield return null;
|
||||
|
||||
try { SelectionGuardProperty.SetValue(EventSystem.current, false, null); } catch { }
|
||||
try { EventSystem.current.SetSelectedGameObject(Input.UIRoot, null); } catch { }
|
||||
try { SetCurrentSelectedGameObject(CursorUnlocker.CurrentEventSystem, null); }
|
||||
catch (Exception ex) { ExplorerCore.Log($"Failed removing selected object: {ex}"); }
|
||||
|
||||
yield return null; // ~~~~~~~ YIELD FRAME ~~~~~~~~~
|
||||
|
||||
try { SetSelectionGuard(CursorUnlocker.CurrentEventSystem, false); }
|
||||
catch (Exception ex) { ExplorerCore.Log($"Failed setting selection guard: {ex}"); }
|
||||
|
||||
try { SetCurrentSelectedGameObject(CursorUnlocker.CurrentEventSystem, Input.GameObject); }
|
||||
catch (Exception ex) { ExplorerCore.Log($"Failed setting selected gameobject: {ex}"); }
|
||||
|
||||
yield return null; // ~~~~~~~ YIELD FRAME ~~~~~~~~~
|
||||
|
||||
Input.Component.Select();
|
||||
yield return null;
|
||||
|
||||
Input.Component.caretPosition = caretPosition;
|
||||
Input.Component.selectionFocusPosition = caretPosition;
|
||||
@ -665,7 +720,8 @@ var x = 5;
|
||||
* Log(obj); - prints a message to the console log
|
||||
* Inspect(obj); - inspect the object with the Inspector
|
||||
* Inspect(someType); - inspect a Type with static reflection
|
||||
* Start(enumerator); - starts the IEnumerator as a Coroutine
|
||||
* Start(enumerator); - Coroutine, starts the IEnumerator as a Coroutine, and returns the Coroutine.
|
||||
* Stop(coroutine); - stop the Coroutine ONLY if it was started with Start(ienumerator).
|
||||
* Copy(obj); - copies the object to the UnityExplorer Clipboard
|
||||
* Paste(); - System.Object, the contents of the Clipboard.
|
||||
* GetUsing(); - prints the current using directives to the console log
|
||||
|
@ -51,13 +51,8 @@ namespace UnityExplorer.CSConsole
|
||||
ReferenceAssembly(asm);
|
||||
}
|
||||
|
||||
private static CompilerContext context;
|
||||
|
||||
private static CompilerContext BuildContext(TextWriter tw)
|
||||
{
|
||||
if (context != null)
|
||||
return context;
|
||||
|
||||
_reportPrinter = new StreamReportPrinter(tw);
|
||||
|
||||
var settings = new CompilerSettings
|
||||
@ -70,7 +65,7 @@ namespace UnityExplorer.CSConsole
|
||||
EnhancedWarnings = false
|
||||
};
|
||||
|
||||
return context = new CompilerContext(settings, _reportPrinter);
|
||||
return new CompilerContext(settings, _reportPrinter);
|
||||
}
|
||||
|
||||
private static void ImportAppdomainAssemblies(Action<Assembly> import)
|
||||
|
@ -29,9 +29,12 @@ namespace UnityExplorer.CSConsole
|
||||
public static void Inspect(Type type)
|
||||
=> InspectorManager.Inspect(type);
|
||||
|
||||
public static void Start(IEnumerator ienumerator)
|
||||
public static Coroutine Start(IEnumerator ienumerator)
|
||||
=> RuntimeHelper.StartCoroutine(ienumerator);
|
||||
|
||||
public static void Stop(Coroutine coro)
|
||||
=> RuntimeHelper.StopCoroutine(coro);
|
||||
|
||||
public static void Copy(object obj)
|
||||
=> ClipboardPanel.Copy(obj);
|
||||
|
||||
|
83
src/CacheObject/CacheConstructor.cs
Normal file
83
src/CacheObject/CacheConstructor.cs
Normal file
@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityExplorer.Inspectors;
|
||||
using UniverseLib.Utility;
|
||||
|
||||
namespace UnityExplorer.CacheObject
|
||||
{
|
||||
public class CacheConstructor : CacheMember
|
||||
{
|
||||
public ConstructorInfo CtorInfo { get; }
|
||||
readonly Type typeForStructConstructor;
|
||||
|
||||
public override Type DeclaringType => typeForStructConstructor ?? CtorInfo.DeclaringType;
|
||||
public override bool IsStatic => true;
|
||||
public override bool ShouldAutoEvaluate => false;
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public CacheConstructor(ConstructorInfo ci)
|
||||
{
|
||||
this.CtorInfo = ci;
|
||||
}
|
||||
|
||||
public CacheConstructor(Type typeForStructConstructor)
|
||||
{
|
||||
this.typeForStructConstructor = typeForStructConstructor;
|
||||
}
|
||||
|
||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
// if is parameterless struct ctor
|
||||
if (typeForStructConstructor != null)
|
||||
{
|
||||
this.Owner = inspector;
|
||||
|
||||
// eg. Vector3.Vector3()
|
||||
this.NameLabelText = SignatureHighlighter.Parse(typeForStructConstructor, false);
|
||||
NameLabelText += $".{NameLabelText}()";
|
||||
|
||||
this.NameForFiltering = SignatureHighlighter.RemoveHighlighting(NameLabelText);
|
||||
this.NameLabelTextRaw = NameForFiltering;
|
||||
return;
|
||||
}
|
||||
|
||||
base.SetInspectorOwner(inspector, member);
|
||||
|
||||
Arguments = CtorInfo.GetParameters();
|
||||
if (CtorInfo.DeclaringType.IsGenericTypeDefinition)
|
||||
GenericArguments = CtorInfo.DeclaringType.GetGenericArguments();
|
||||
}
|
||||
|
||||
protected override object TryEvaluate()
|
||||
{
|
||||
try
|
||||
{
|
||||
Type returnType = DeclaringType;
|
||||
|
||||
if (returnType.IsGenericTypeDefinition)
|
||||
returnType = DeclaringType.MakeGenericType(Evaluator.TryParseGenericArguments());
|
||||
|
||||
object ret;
|
||||
if (HasArguments)
|
||||
ret = Activator.CreateInstance(returnType, Evaluator.TryParseArguments());
|
||||
else
|
||||
ret = Activator.CreateInstance(returnType, ArgumentUtility.EmptyArgs);
|
||||
|
||||
HadException = false;
|
||||
LastException = null;
|
||||
return ret;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HadException = true;
|
||||
LastException = ex;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void TrySetValue(object value) => throw new NotImplementedException("You can't set a constructor");
|
||||
}
|
||||
}
|
@ -17,6 +17,11 @@ namespace UnityExplorer.CacheObject
|
||||
|
||||
public override bool ShouldAutoEvaluate => true;
|
||||
|
||||
public CacheField(FieldInfo fi)
|
||||
{
|
||||
this.FieldInfo = fi;
|
||||
}
|
||||
|
||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
base.SetInspectorOwner(inspector, member);
|
||||
|
@ -14,6 +14,8 @@ using UniverseLib.UI;
|
||||
using UnityExplorer.UI.Widgets;
|
||||
using UniverseLib.Utility;
|
||||
using UniverseLib.UI.ObjectPool;
|
||||
using System.Collections;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace UnityExplorer.CacheObject
|
||||
{
|
||||
@ -21,7 +23,7 @@ namespace UnityExplorer.CacheObject
|
||||
{
|
||||
public abstract Type DeclaringType { get; }
|
||||
public string NameForFiltering { get; protected set; }
|
||||
public object DeclaringInstance => IsStatic ? null : (m_declaringInstance ?? (m_declaringInstance = Owner.Target.TryCast(DeclaringType)));
|
||||
public object DeclaringInstance => IsStatic ? null : (m_declaringInstance ??= Owner.Target.TryCast(DeclaringType));
|
||||
private object m_declaringInstance;
|
||||
|
||||
public abstract bool IsStatic { get; }
|
||||
@ -34,10 +36,14 @@ namespace UnityExplorer.CacheObject
|
||||
public virtual void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
this.Owner = inspector;
|
||||
this.NameLabelText = this is CacheMethod
|
||||
? SignatureHighlighter.HighlightMethod(member as MethodInfo)
|
||||
: SignatureHighlighter.Parse(member.DeclaringType, false, member);
|
||||
this.NameForFiltering = $"{member.DeclaringType.Name}.{member.Name}";
|
||||
this.NameLabelText = this switch
|
||||
{
|
||||
CacheMethod => SignatureHighlighter.HighlightMethod(member as MethodInfo),
|
||||
CacheConstructor => SignatureHighlighter.HighlightConstructor(member as ConstructorInfo),
|
||||
_ => SignatureHighlighter.Parse(member.DeclaringType, false, member),
|
||||
};
|
||||
|
||||
this.NameForFiltering = SignatureHighlighter.RemoveHighlighting(NameLabelText);
|
||||
this.NameLabelTextRaw = NameForFiltering;
|
||||
}
|
||||
|
||||
@ -94,8 +100,8 @@ namespace UnityExplorer.CacheObject
|
||||
base.SetValueState(cell, args);
|
||||
}
|
||||
|
||||
private static readonly Color evalEnabledColor = new Color(0.15f, 0.25f, 0.15f);
|
||||
private static readonly Color evalDisabledColor = new Color(0.15f, 0.15f, 0.15f);
|
||||
private static readonly Color evalEnabledColor = new(0.15f, 0.25f, 0.15f);
|
||||
private static readonly Color evalDisabledColor = new(0.15f, 0.15f, 0.15f);
|
||||
|
||||
protected override bool TryAutoEvaluateIfUnitialized(CacheObjectCell objectcell)
|
||||
{
|
||||
@ -164,76 +170,75 @@ namespace UnityExplorer.CacheObject
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Cache Member Util
|
||||
|
||||
//public static bool CanParseArgs(ParameterInfo[] parameters)
|
||||
//{
|
||||
// foreach (var param in parameters)
|
||||
// {
|
||||
// var pType = param.ParameterType;
|
||||
//
|
||||
// if (pType.IsByRef && pType.HasElementType)
|
||||
// pType = pType.GetElementType();
|
||||
//
|
||||
// if (pType != null && ParseUtility.CanParse(pType))
|
||||
// continue;
|
||||
// else
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
|
||||
public static List<CacheMember> GetCacheMembers(object inspectorTarget, Type _type, ReflectionInspector _inspector)
|
||||
public static List<CacheMember> GetCacheMembers(object inspectorTarget, Type type, ReflectionInspector inspector)
|
||||
{
|
||||
var list = new List<CacheMember>();
|
||||
var cachedSigs = new HashSet<string>();
|
||||
//var list = new List<CacheMember>();
|
||||
HashSet<string> cachedSigs = new();
|
||||
List<CacheMember> props = new();
|
||||
List<CacheMember> fields = new();
|
||||
List<CacheMember> ctors = new();
|
||||
List<CacheMember> methods = new();
|
||||
|
||||
var types = ReflectionUtility.GetAllBaseTypes(_type);
|
||||
var types = ReflectionUtility.GetAllBaseTypes(type);
|
||||
|
||||
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
|
||||
if (!_inspector.StaticOnly)
|
||||
if (!inspector.StaticOnly)
|
||||
flags |= BindingFlags.Instance;
|
||||
|
||||
var infos = new List<MemberInfo>();
|
||||
if (!type.IsAbstract)
|
||||
{
|
||||
// Get non-static constructors of the main type.
|
||||
// There's no reason to get the static cctor, it will be invoked when we inspect the class.
|
||||
// Also no point getting ctors on inherited types.
|
||||
foreach (var ctor in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
|
||||
TryCacheMember(ctor, ctors, cachedSigs, type, inspector);
|
||||
|
||||
// structs always have a parameterless constructor
|
||||
if (type.IsValueType)
|
||||
{
|
||||
CacheConstructor cached = new(type);
|
||||
cached.SetFallbackType(type);
|
||||
cached.SetInspectorOwner(inspector, null);
|
||||
ctors.Add(cached);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var declaringType in types)
|
||||
{
|
||||
var target = inspectorTarget;
|
||||
if (!_inspector.StaticOnly)
|
||||
if (!inspector.StaticOnly)
|
||||
target = target.TryCast(declaringType);
|
||||
|
||||
infos.Clear();
|
||||
infos.AddRange(declaringType.GetProperties(flags));
|
||||
infos.AddRange(declaringType.GetFields(flags));
|
||||
infos.AddRange(declaringType.GetMethods(flags));
|
||||
foreach (var prop in declaringType.GetProperties(flags))
|
||||
if (prop.DeclaringType == declaringType)
|
||||
TryCacheMember(prop, props, cachedSigs, declaringType, inspector);
|
||||
|
||||
foreach (var field in declaringType.GetFields(flags))
|
||||
if (field.DeclaringType == declaringType)
|
||||
TryCacheMember(field, fields, cachedSigs, declaringType, inspector);
|
||||
|
||||
foreach (var method in declaringType.GetMethods(flags))
|
||||
if (method.DeclaringType == declaringType)
|
||||
TryCacheMember(method, methods, cachedSigs, declaringType, inspector);
|
||||
|
||||
foreach (var member in infos)
|
||||
{
|
||||
if (member.DeclaringType != declaringType)
|
||||
continue;
|
||||
TryCacheMember(member, list, cachedSigs, declaringType, _inspector);
|
||||
}
|
||||
}
|
||||
|
||||
var typeList = types.ToList();
|
||||
|
||||
var sorted = new List<CacheMember>();
|
||||
sorted.AddRange(list.Where(it => it is CacheProperty)
|
||||
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
sorted.AddRange(list.Where(it => it is CacheField)
|
||||
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
sorted.AddRange(list.Where(it => it is CacheMethod)
|
||||
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
|
||||
sorted.AddRange(props.OrderBy(it => Array.IndexOf(types, it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
sorted.AddRange(fields.OrderBy(it => Array.IndexOf(types, it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
sorted.AddRange(ctors.OrderBy(it => Array.IndexOf(types, it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
sorted.AddRange(methods.OrderBy(it => Array.IndexOf(types, it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
return sorted;
|
||||
}
|
||||
|
||||
private static void TryCacheMember(MemberInfo member, List<CacheMember> list, HashSet<string> cachedSigs,
|
||||
Type declaringType, ReflectionInspector _inspector, bool ignorePropertyMethodInfos = true)
|
||||
private static void TryCacheMember(MemberInfo member, IList list, HashSet<string> cachedSigs,
|
||||
Type declaringType, ReflectionInspector inspector, bool ignorePropertyMethodInfos = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -242,12 +247,23 @@ namespace UnityExplorer.CacheObject
|
||||
|
||||
var sig = GetSig(member);
|
||||
|
||||
//ExplorerCore.Log($"Trying to cache member {sig}... ({member.MemberType})");
|
||||
// ExplorerCore.Log($"Trying to cache member {sig}... ({member.MemberType})");
|
||||
|
||||
CacheMember cached;
|
||||
Type returnType;
|
||||
switch (member.MemberType)
|
||||
{
|
||||
case MemberTypes.Constructor:
|
||||
{
|
||||
var ci = member as ConstructorInfo;
|
||||
sig += GetArgumentString(ci.GetParameters());
|
||||
if (cachedSigs.Contains(sig))
|
||||
return;
|
||||
cached = new CacheConstructor(ci);
|
||||
returnType = ci.DeclaringType;
|
||||
}
|
||||
break;
|
||||
|
||||
case MemberTypes.Method:
|
||||
{
|
||||
var mi = member as MethodInfo;
|
||||
@ -255,15 +271,11 @@ namespace UnityExplorer.CacheObject
|
||||
&& (mi.Name.StartsWith("get_") || mi.Name.StartsWith("set_")))
|
||||
return;
|
||||
|
||||
//var args = mi.GetParameters();
|
||||
//if (!CanParseArgs(args))
|
||||
// return;
|
||||
|
||||
sig += GetArgumentString(mi.GetParameters());
|
||||
if (cachedSigs.Contains(sig))
|
||||
return;
|
||||
|
||||
cached = new CacheMethod() { MethodInfo = mi };
|
||||
cached = new CacheMethod(mi);
|
||||
returnType = mi.ReturnType;
|
||||
break;
|
||||
}
|
||||
@ -272,16 +284,12 @@ namespace UnityExplorer.CacheObject
|
||||
{
|
||||
var pi = member as PropertyInfo;
|
||||
|
||||
//var args = pi.GetIndexParameters();
|
||||
//if (!CanParseArgs(args))
|
||||
// return;
|
||||
|
||||
if (!pi.CanRead && pi.CanWrite)
|
||||
{
|
||||
// write-only property, cache the set method instead.
|
||||
var setMethod = pi.GetSetMethod(true);
|
||||
if (setMethod != null)
|
||||
TryCacheMember(setMethod, list, cachedSigs, declaringType, _inspector, false);
|
||||
TryCacheMember(setMethod, list, cachedSigs, declaringType, inspector, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -289,7 +297,7 @@ namespace UnityExplorer.CacheObject
|
||||
if (cachedSigs.Contains(sig))
|
||||
return;
|
||||
|
||||
cached = new CacheProperty() { PropertyInfo = pi };
|
||||
cached = new CacheProperty(pi);
|
||||
returnType = pi.PropertyType;
|
||||
break;
|
||||
}
|
||||
@ -297,7 +305,7 @@ namespace UnityExplorer.CacheObject
|
||||
case MemberTypes.Field:
|
||||
{
|
||||
var fi = member as FieldInfo;
|
||||
cached = new CacheField() { FieldInfo = fi };
|
||||
cached = new CacheField(fi);
|
||||
returnType = fi.FieldType;
|
||||
break;
|
||||
}
|
||||
@ -308,7 +316,7 @@ namespace UnityExplorer.CacheObject
|
||||
cachedSigs.Add(sig);
|
||||
|
||||
cached.SetFallbackType(returnType);
|
||||
cached.SetInspectorOwner(_inspector, member);
|
||||
cached.SetInspectorOwner(inspector, member);
|
||||
|
||||
list.Add(cached);
|
||||
}
|
||||
|
@ -11,13 +11,18 @@ namespace UnityExplorer.CacheObject
|
||||
{
|
||||
public class CacheMethod : CacheMember
|
||||
{
|
||||
public MethodInfo MethodInfo { get; internal set; }
|
||||
public MethodInfo MethodInfo { get; }
|
||||
public override Type DeclaringType => MethodInfo.DeclaringType;
|
||||
public override bool CanWrite => false;
|
||||
public override bool IsStatic => MethodInfo.IsStatic;
|
||||
|
||||
public override bool ShouldAutoEvaluate => false;
|
||||
|
||||
public CacheMethod (MethodInfo mi)
|
||||
{
|
||||
this.MethodInfo = mi;
|
||||
}
|
||||
|
||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
base.SetInspectorOwner(inspector, member);
|
||||
|
@ -3,7 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.Inspectors;
|
||||
using UnityExplorer.Runtime;
|
||||
|
||||
namespace UnityExplorer.CacheObject
|
||||
{
|
||||
@ -17,6 +19,11 @@ namespace UnityExplorer.CacheObject
|
||||
|
||||
public override bool ShouldAutoEvaluate => !HasArguments;
|
||||
|
||||
public CacheProperty(PropertyInfo pi)
|
||||
{
|
||||
this.PropertyInfo = pi;
|
||||
}
|
||||
|
||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||
{
|
||||
base.SetInspectorOwner(inspector, member);
|
||||
|
@ -29,8 +29,11 @@ namespace UnityExplorer.CacheObject.IValues
|
||||
private EnumCompleter enumCompleter;
|
||||
|
||||
private GameObject toggleHolder;
|
||||
private readonly List<Toggle> flagToggles = new List<Toggle>();
|
||||
private readonly List<Text> flagTexts = new List<Text>();
|
||||
private readonly List<Toggle> flagToggles = new();
|
||||
private readonly List<Text> flagTexts = new();
|
||||
|
||||
public CachedEnumValue ValueAtIndex(int idx) => (CachedEnumValue)CurrentValues[idx];
|
||||
public CachedEnumValue ValueAtKey(object key) => (CachedEnumValue)CurrentValues[key];
|
||||
|
||||
// Setting value from owner
|
||||
public override void SetValue(object value)
|
||||
@ -70,13 +73,8 @@ namespace UnityExplorer.CacheObject.IValues
|
||||
{
|
||||
try
|
||||
{
|
||||
var split = value.ToString().Split(',');
|
||||
var set = new HashSet<string>();
|
||||
foreach (var s in split)
|
||||
set.Add(s.Trim());
|
||||
|
||||
for (int i = 0; i < CurrentValues.Count; i++)
|
||||
flagToggles[i].isOn = set.Contains(ValueAtIdx(i).Name);
|
||||
flagToggles[i].isOn = (value as Enum).HasFlag(ValueAtIndex(i).ActualValue as Enum);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -116,7 +114,7 @@ namespace UnityExplorer.CacheObject.IValues
|
||||
for (int i = 0; i < CurrentValues.Count; i++)
|
||||
{
|
||||
if (flagToggles[i].isOn)
|
||||
values.Add(ValueAtIdx(i).Name);
|
||||
values.Add(ValueAtIndex(i).Name);
|
||||
}
|
||||
|
||||
CurrentOwner.SetUserValue(Enum.Parse(EnumType, string.Join(", ", values.ToArray())));
|
||||
@ -166,9 +164,6 @@ namespace UnityExplorer.CacheObject.IValues
|
||||
return UIRoot;
|
||||
}
|
||||
|
||||
public CachedEnumValue ValueAtIdx(int idx) => (CachedEnumValue)CurrentValues[idx];
|
||||
public CachedEnumValue ValueAtKey(object key) => (CachedEnumValue)CurrentValues[key];
|
||||
|
||||
private void SetupTogglesForEnumType()
|
||||
{
|
||||
toggleHolder.SetActive(true);
|
||||
@ -191,7 +186,7 @@ namespace UnityExplorer.CacheObject.IValues
|
||||
AddToggleRow();
|
||||
|
||||
flagToggles[i].isOn = false;
|
||||
flagTexts[i].text = ValueAtIdx(i).Name;
|
||||
flagTexts[i].text = ValueAtIndex(i).Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,8 @@ namespace UnityExplorer.Config
|
||||
public static ConfigElement<bool> Hide_On_Startup;
|
||||
public static ConfigElement<float> Startup_Delay_Time;
|
||||
public static ConfigElement<string> Reflection_Signature_Blacklist;
|
||||
public static ConfigElement<KeyCode> World_MouseInspect_Keybind;
|
||||
public static ConfigElement<KeyCode> UI_MouseInspect_Keybind;
|
||||
|
||||
// internal configs
|
||||
internal static InternalConfigHandler InternalHandler { get; private set; }
|
||||
@ -93,13 +95,18 @@ namespace UnityExplorer.Config
|
||||
"Should UnityExplorer be hidden on startup?",
|
||||
false);
|
||||
|
||||
World_MouseInspect_Keybind = new("World Mouse-Inspect Keybind",
|
||||
"Optional keybind to being a World-mode Mouse Inspect.",
|
||||
KeyCode.None);
|
||||
|
||||
UI_MouseInspect_Keybind = new("UI Mouse-Inspect Keybind",
|
||||
"Optional keybind to begin a UI_mode Mouse Inspect.",
|
||||
KeyCode.None);
|
||||
|
||||
Force_Unlock_Mouse = new ConfigElement<bool>("Force Unlock Mouse",
|
||||
"Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.",
|
||||
true);
|
||||
Force_Unlock_Mouse.OnValueChanged += (bool value) =>
|
||||
{
|
||||
UniverseLib.Config.ConfigManager.Force_Unlock_Mouse = value;
|
||||
};
|
||||
Force_Unlock_Mouse.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Force_Unlock_Mouse = value;
|
||||
|
||||
Force_Unlock_Toggle = new ConfigElement<KeyCode>("Force Unlock Toggle Key",
|
||||
"The keybind to toggle the 'Force Unlock Mouse' setting. Only usable when UnityExplorer is open.",
|
||||
@ -108,10 +115,7 @@ namespace UnityExplorer.Config
|
||||
Disable_EventSystem_Override = new ConfigElement<bool>("Disable EventSystem override",
|
||||
"If enabled, UnityExplorer will not override the EventSystem from the game.\n<b>May require restart to take effect.</b>",
|
||||
false);
|
||||
Disable_EventSystem_Override.OnValueChanged += (bool value) =>
|
||||
{
|
||||
UniverseLib.Config.ConfigManager.Disable_EventSystem_Override = value;
|
||||
};
|
||||
Disable_EventSystem_Override.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Disable_EventSystem_Override = value;
|
||||
|
||||
Log_Unity_Debug = new ConfigElement<bool>("Log Unity Debug",
|
||||
"Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?",
|
||||
|
@ -11,13 +11,14 @@ using UnityExplorer.UI.Panels;
|
||||
using UnityExplorer.Runtime;
|
||||
using UniverseLib.Input;
|
||||
using UniverseLib.UI;
|
||||
using System.Reflection;
|
||||
|
||||
namespace UnityExplorer
|
||||
{
|
||||
public static class ExplorerCore
|
||||
{
|
||||
public const string NAME = "UnityExplorer";
|
||||
public const string VERSION = "4.5.4";
|
||||
public const string VERSION = "4.5.12";
|
||||
public const string AUTHOR = "Sinai";
|
||||
public const string GUID = "com.sinai.unityexplorer";
|
||||
|
||||
@ -45,6 +46,7 @@ namespace UnityExplorer
|
||||
ConfigManager.Init(Loader.ConfigHandler);
|
||||
UERuntimeHelper.Init();
|
||||
ExplorerBehaviour.Setup();
|
||||
UnityCrashPrevention.Init();
|
||||
|
||||
UniverseLib.Universe.Init(ConfigManager.Startup_Delay_Time.Value, LateInit, Log, new()
|
||||
{
|
||||
@ -67,7 +69,7 @@ namespace UnityExplorer
|
||||
|
||||
UIManager.InitUI();
|
||||
|
||||
Log($"{NAME} {VERSION} initialized.");
|
||||
Log($"{NAME} {VERSION} initialized for {UniverseLib.Universe.Context}.");
|
||||
|
||||
//InspectorManager.Inspect(typeof(Tests.TestClass));
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ namespace UnityExplorer.Inspectors
|
||||
this.Target = newTarget;
|
||||
GOControls.UpdateGameObjectInfo(true, true);
|
||||
GOControls.UpdateTransformControlValues(true);
|
||||
TransformTree.RefreshData(true, false);
|
||||
TransformTree.RefreshData(true, false, true, false);
|
||||
UpdateComponents();
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
GOControls.UpdateGameObjectInfo(false, false);
|
||||
|
||||
TransformTree.RefreshData(true, false);
|
||||
TransformTree.RefreshData(true, false, false, false);
|
||||
UpdateComponents();
|
||||
}
|
||||
}
|
||||
@ -220,7 +220,7 @@ namespace UnityExplorer.Inspectors
|
||||
var newObject = new GameObject(input);
|
||||
newObject.transform.parent = GOTarget.transform;
|
||||
|
||||
TransformTree.RefreshData(true, false);
|
||||
TransformTree.RefreshData(true, false, true, false);
|
||||
}
|
||||
|
||||
private void OnAddComponentClicked(string input)
|
||||
|
@ -18,7 +18,7 @@ namespace UnityExplorer
|
||||
{
|
||||
public static class InspectorManager
|
||||
{
|
||||
public static readonly List<InspectorBase> Inspectors = new List<InspectorBase>();
|
||||
public static readonly List<InspectorBase> Inspectors = new();
|
||||
|
||||
public static InspectorBase ActiveInspector { get; private set; }
|
||||
private static InspectorBase lastActiveInspector;
|
||||
@ -94,17 +94,17 @@ namespace UnityExplorer
|
||||
}
|
||||
|
||||
private static void CreateInspector<T>(object target, bool staticReflection = false,
|
||||
CacheObjectBase sourceCache = null) where T : InspectorBase
|
||||
CacheObjectBase parentObject = null) where T : InspectorBase
|
||||
{
|
||||
var inspector = Pool<T>.Borrow();
|
||||
Inspectors.Add(inspector);
|
||||
inspector.Target = target;
|
||||
|
||||
if (sourceCache != null && sourceCache.CanWrite)
|
||||
if (parentObject != null && parentObject.CanWrite)
|
||||
{
|
||||
// only set parent cache object if we are inspecting a struct, otherwise there is no point.
|
||||
if (target.GetType().IsValueType && inspector is ReflectionInspector ri)
|
||||
ri.ParentCacheObject = sourceCache;
|
||||
ri.ParentCacheObject = parentObject;
|
||||
}
|
||||
|
||||
UIManager.SetPanelActive(UIManager.Panels.Inspector, true);
|
||||
|
@ -43,9 +43,10 @@ namespace UnityExplorer.Inspectors
|
||||
TabButton = UIFactory.CreateButton(UIRoot, "TabButton", "");
|
||||
UIFactory.SetLayoutElement(TabButton.Component.gameObject, minWidth: 173, flexibleWidth: 0);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(TabButton.Component.gameObject, false, false, true, true, 0, 0, 0, 3);
|
||||
TabButton.GameObject.AddComponent<Mask>();
|
||||
|
||||
TabText = TabButton.Component.GetComponentInChildren<Text>();
|
||||
UIFactory.SetLayoutElement(TabText.gameObject, minHeight: 25, minWidth: 173, flexibleWidth: 0);
|
||||
TabText = TabButton.ButtonText;
|
||||
UIFactory.SetLayoutElement(TabText.gameObject, minHeight: 25, minWidth: 150, flexibleWidth: 0);
|
||||
TabText.alignment = TextAnchor.MiddleLeft;
|
||||
TabText.fontSize = 12;
|
||||
TabText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||
|
@ -13,6 +13,7 @@ using UnityExplorer.UI.Panels;
|
||||
using UniverseLib;
|
||||
using UniverseLib.UI;
|
||||
using UniverseLib.Utility;
|
||||
using UnityExplorer.Config;
|
||||
|
||||
namespace UnityExplorer.Inspectors
|
||||
{
|
||||
@ -22,9 +23,9 @@ namespace UnityExplorer.Inspectors
|
||||
UI
|
||||
}
|
||||
|
||||
public class InspectUnderMouse : UIPanel
|
||||
public class MouseInspector : UIPanel
|
||||
{
|
||||
public static InspectUnderMouse Instance { get; private set; }
|
||||
public static MouseInspector Instance { get; private set; }
|
||||
|
||||
private readonly WorldInspector worldInspector;
|
||||
private readonly UiInspector uiInspector;
|
||||
@ -58,7 +59,7 @@ namespace UnityExplorer.Inspectors
|
||||
internal Text objPathLabel;
|
||||
internal Text mousePosLabel;
|
||||
|
||||
public InspectUnderMouse()
|
||||
public MouseInspector()
|
||||
{
|
||||
Instance = this;
|
||||
worldInspector = new WorldInspector();
|
||||
@ -116,6 +117,26 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
private static float timeOfLastRaycast;
|
||||
|
||||
public bool TryUpdate()
|
||||
{
|
||||
if (ConfigManager.World_MouseInspect_Keybind.Value != KeyCode.None)
|
||||
{
|
||||
if (InputManager.GetKeyDown(ConfigManager.World_MouseInspect_Keybind.Value))
|
||||
Instance.StartInspect(MouseInspectMode.World);
|
||||
}
|
||||
|
||||
if (ConfigManager.World_MouseInspect_Keybind.Value != KeyCode.None)
|
||||
{
|
||||
if (InputManager.GetKeyDown(ConfigManager.World_MouseInspect_Keybind.Value))
|
||||
Instance.StartInspect(MouseInspectMode.World);
|
||||
}
|
||||
|
||||
if (Inspecting)
|
||||
UpdateInspect();
|
||||
|
||||
return Inspecting;
|
||||
}
|
||||
|
||||
public void UpdateInspect()
|
||||
{
|
||||
if (InputManager.GetKeyDown(KeyCode.Escape))
|
||||
@ -177,10 +198,10 @@ namespace UnityExplorer.Inspectors
|
||||
public override void ConstructPanelContent()
|
||||
{
|
||||
// hide title bar
|
||||
this.titleBar.SetActive(false);
|
||||
this.TitleBar.SetActive(false);
|
||||
this.UIRoot.transform.SetParent(UIManager.UIRoot.transform, false);
|
||||
|
||||
var inspectContent = UIFactory.CreateVerticalGroup(this.uiRoot, "InspectContent", true, true, true, true, 3, new Vector4(2, 2, 2, 2));
|
||||
var inspectContent = UIFactory.CreateVerticalGroup(this.uiContent, "InspectContent", true, true, true, true, 3, new Vector4(2, 2, 2, 2));
|
||||
UIFactory.SetLayoutElement(inspectContent, flexibleWidth: 9999, flexibleHeight: 9999);
|
||||
|
||||
// Title text
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -8,6 +9,7 @@ using UnityEngine.UI;
|
||||
using UnityExplorer.UI;
|
||||
using UnityExplorer.UI.Panels;
|
||||
using UniverseLib;
|
||||
using UniverseLib.Input;
|
||||
|
||||
namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
{
|
||||
@ -26,7 +28,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
public override void OnBeginMouseInspect()
|
||||
{
|
||||
SetupUIRaycast();
|
||||
InspectUnderMouse.Instance.objPathLabel.text = "";
|
||||
MouseInspector.Instance.objPathLabel.text = "";
|
||||
}
|
||||
|
||||
public override void ClearHitData()
|
||||
@ -38,6 +40,12 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
{
|
||||
LastHitObjects.Clear();
|
||||
LastHitObjects.AddRange(currentHitObjects);
|
||||
RuntimeHelper.StartCoroutine(SetPanelActiveCoro());
|
||||
}
|
||||
|
||||
IEnumerator SetPanelActiveCoro()
|
||||
{
|
||||
yield return null;
|
||||
var panel = UIManager.GetPanel<UiInspectorResultsPanel>(UIManager.Panels.UIInspectorResults);
|
||||
panel.SetActive(true);
|
||||
panel.ShowResults();
|
||||
@ -70,9 +78,9 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
}
|
||||
|
||||
if (currentHitObjects.Any())
|
||||
InspectUnderMouse.Instance.objNameLabel.text = $"Click to view UI Objects under mouse: {currentHitObjects.Count}";
|
||||
MouseInspector.Instance.objNameLabel.text = $"Click to view UI Objects under mouse: {currentHitObjects.Count}";
|
||||
else
|
||||
InspectUnderMouse.Instance.objNameLabel.text = $"No UI objects under mouse.";
|
||||
MouseInspector.Instance.objNameLabel.text = $"No UI objects under mouse.";
|
||||
}
|
||||
|
||||
private static void SetupUIRaycast()
|
||||
|
@ -41,7 +41,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
if (!MainCamera)
|
||||
{
|
||||
ExplorerCore.LogWarning("No Main Camera was found, unable to inspect world!");
|
||||
InspectUnderMouse.Instance.StopInspect();
|
||||
MouseInspector.Instance.StopInspect();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
if (hit.transform)
|
||||
OnHitGameObject(hit.transform.gameObject);
|
||||
else if (lastHitObject)
|
||||
InspectUnderMouse.Instance.ClearHitData();
|
||||
MouseInspector.Instance.ClearHitData();
|
||||
}
|
||||
|
||||
internal void OnHitGameObject(GameObject obj)
|
||||
@ -59,8 +59,8 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
if (obj != lastHitObject)
|
||||
{
|
||||
lastHitObject = obj;
|
||||
InspectUnderMouse.Instance.objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
|
||||
InspectUnderMouse.Instance.objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
|
||||
MouseInspector.Instance.objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
|
||||
MouseInspector.Instance.objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,9 @@ namespace UnityExplorer.Inspectors
|
||||
None = 0,
|
||||
Property = 1,
|
||||
Field = 2,
|
||||
Method = 4,
|
||||
All = 7
|
||||
Constructor = 4,
|
||||
Method = 8,
|
||||
All = Property | Field | Method | Constructor,
|
||||
}
|
||||
|
||||
// UI
|
||||
@ -133,7 +134,7 @@ namespace UnityExplorer.Inspectors
|
||||
currentBaseTabText = $"{prefix} {SignatureHighlighter.Parse(TargetType, false)}";
|
||||
Tab.TabText.text = currentBaseTabText;
|
||||
NameText.text = SignatureHighlighter.Parse(TargetType, true);
|
||||
HiddenNameText.Text = TargetType.FullName;
|
||||
HiddenNameText.Text = SignatureHighlighter.RemoveHighlighting(NameText.text);
|
||||
|
||||
string asmText;
|
||||
if (TargetType.Assembly is AssemblyBuilder || string.IsNullOrEmpty(TargetType.Assembly.Location))
|
||||
@ -153,7 +154,7 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
this.filterInputField.Text = "";
|
||||
|
||||
SetFilter("", StaticOnly ? BindingFlags.Static : BindingFlags.Instance);
|
||||
SetFilter("", StaticOnly ? BindingFlags.Static : BindingFlags.Default);
|
||||
scopeFilterButtons[BindingFlags.Default].Component.gameObject.SetActive(!StaticOnly);
|
||||
scopeFilterButtons[BindingFlags.Instance].Component.gameObject.SetActive(!StaticOnly);
|
||||
|
||||
@ -261,7 +262,8 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
if ((member is CacheMethod && !MemberFilter.HasFlag(MemberFlags.Method))
|
||||
|| (member is CacheField && !MemberFilter.HasFlag(MemberFlags.Field))
|
||||
|| (member is CacheProperty && !MemberFilter.HasFlag(MemberFlags.Property)))
|
||||
|| (member is CacheProperty && !MemberFilter.HasFlag(MemberFlags.Property))
|
||||
|| (member is CacheConstructor && !MemberFilter.HasFlag(MemberFlags.Constructor)))
|
||||
continue;
|
||||
|
||||
if (!string.IsNullOrEmpty(NameFilter) && !member.NameForFiltering.ContainsIgnoreCase(NameFilter))
|
||||
@ -462,6 +464,7 @@ namespace UnityExplorer.Inspectors
|
||||
AddMemberTypeToggle(rowObj, MemberTypes.Property, 90);
|
||||
AddMemberTypeToggle(rowObj, MemberTypes.Field, 70);
|
||||
AddMemberTypeToggle(rowObj, MemberTypes.Method, 90);
|
||||
AddMemberTypeToggle(rowObj, MemberTypes.Constructor, 110);
|
||||
}
|
||||
|
||||
private void AddScopeFilterButton(GameObject parent, BindingFlags flags, bool setAsActive = false)
|
||||
@ -480,25 +483,26 @@ namespace UnityExplorer.Inspectors
|
||||
{
|
||||
var toggleObj = UIFactory.CreateToggle(parent, "Toggle_" + type, out Toggle toggle, out Text toggleText);
|
||||
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: width);
|
||||
var color = type switch
|
||||
string color = type switch
|
||||
{
|
||||
MemberTypes.Method => SignatureHighlighter.METHOD_INSTANCE,
|
||||
MemberTypes.Field => SignatureHighlighter.FIELD_INSTANCE,
|
||||
MemberTypes.Property => SignatureHighlighter.PROP_INSTANCE,
|
||||
MemberTypes.Constructor => SignatureHighlighter.CLASS_INSTANCE,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
toggleText.text = $"<color={color}>{type}</color>";
|
||||
|
||||
toggle.graphic.TryCast<Image>().color = color.ToColor() * 0.65f;
|
||||
|
||||
MemberFlags flag;
|
||||
switch (type)
|
||||
MemberFlags flag = type switch
|
||||
{
|
||||
case MemberTypes.Method: flag = MemberFlags.Method; break;
|
||||
case MemberTypes.Property: flag = MemberFlags.Property; break;
|
||||
case MemberTypes.Field: flag = MemberFlags.Field; break;
|
||||
default: return;
|
||||
}
|
||||
MemberTypes.Method => MemberFlags.Method,
|
||||
MemberTypes.Property => MemberFlags.Property,
|
||||
MemberTypes.Field => MemberFlags.Field,
|
||||
MemberTypes.Constructor => MemberFlags.Constructor,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
toggle.onValueChanged.AddListener((bool val) => { OnMemberTypeToggled(flag, val); });
|
||||
|
||||
|
@ -31,9 +31,9 @@ namespace UnityExplorer
|
||||
public ConfigHandler ConfigHandler => _configHandler;
|
||||
public MelonLoaderConfigHandler _configHandler;
|
||||
|
||||
public Action<object> OnLogMessage => MelonLogger.Msg;
|
||||
public Action<object> OnLogWarning => MelonLogger.Warning;
|
||||
public Action<object> OnLogError => MelonLogger.Error;
|
||||
public Action<object> OnLogMessage => LoggerInstance.Msg;
|
||||
public Action<object> OnLogWarning => LoggerInstance.Warning;
|
||||
public Action<object> OnLogError => LoggerInstance.Error;
|
||||
|
||||
public override void OnApplicationStart()
|
||||
{
|
||||
|
@ -99,7 +99,13 @@ namespace UnityExplorer.ObjectExplorer
|
||||
|
||||
nameInputRow.SetActive(context == SearchContext.UnityObject);
|
||||
|
||||
typeAutocompleter.BaseType = context == SearchContext.UnityObject ? typeof(UnityEngine.Object) : typeof(object);
|
||||
if (context == SearchContext.Class)
|
||||
typeAutocompleter.AllTypes = true;
|
||||
else
|
||||
{
|
||||
typeAutocompleter.BaseType = context == SearchContext.UnityObject ? typeof(UnityEngine.Object) : typeof(object);
|
||||
typeAutocompleter.AllTypes = false;
|
||||
}
|
||||
typeAutocompleter.CacheTypes();
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
Parent = parent;
|
||||
|
||||
SceneHandler.OnInspectedSceneChanged += SceneHandler_OnInspectedSceneChanged;
|
||||
SceneHandler.OnLoadedScenesChanged += SceneHandler_OnLoadedScenesChanged;
|
||||
SceneHandler.OnLoadedScenesUpdated += SceneHandler_OnLoadedScenesUpdated;
|
||||
}
|
||||
|
||||
public override GameObject UIRoot => uiRoot;
|
||||
@ -64,7 +64,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
public void UpdateTree()
|
||||
{
|
||||
SceneHandler.Update();
|
||||
Tree.RefreshData(true);
|
||||
Tree.RefreshData(true, false, false, false);
|
||||
}
|
||||
|
||||
public void JumpToTransform(Transform transform)
|
||||
@ -87,21 +87,21 @@ namespace UnityExplorer.ObjectExplorer
|
||||
Tree.JumpAndExpandToTransform(transform);
|
||||
}
|
||||
|
||||
private void OnDropdownChanged(int value)
|
||||
private void OnSceneSelectionDropdownChanged(int value)
|
||||
{
|
||||
if (value < 0 || SceneHandler.LoadedScenes.Count <= value)
|
||||
return;
|
||||
|
||||
SceneHandler.SelectedScene = SceneHandler.LoadedScenes[value];
|
||||
SceneHandler.Update();
|
||||
Tree.RefreshData(true);
|
||||
Tree.RefreshData(true, true, true, false);
|
||||
OnSelectedSceneChanged(SceneHandler.SelectedScene.Value);
|
||||
}
|
||||
|
||||
private void SceneHandler_OnInspectedSceneChanged(Scene scene)
|
||||
{
|
||||
if (!sceneToDropdownOption.ContainsKey(scene))
|
||||
PopulateSceneDropdown();
|
||||
PopulateSceneDropdown(SceneHandler.LoadedScenes);
|
||||
|
||||
if (sceneToDropdownOption.ContainsKey(scene))
|
||||
{
|
||||
@ -122,17 +122,17 @@ namespace UnityExplorer.ObjectExplorer
|
||||
refreshRow.SetActive(!scene.IsValid());
|
||||
}
|
||||
|
||||
private void SceneHandler_OnLoadedScenesChanged(List<Scene> loadedScenes)
|
||||
private void SceneHandler_OnLoadedScenesUpdated(List<Scene> loadedScenes)
|
||||
{
|
||||
PopulateSceneDropdown();
|
||||
PopulateSceneDropdown(loadedScenes);
|
||||
}
|
||||
|
||||
private void PopulateSceneDropdown()
|
||||
private void PopulateSceneDropdown(List<Scene> loadedScenes)
|
||||
{
|
||||
sceneToDropdownOption.Clear();
|
||||
sceneDropdown.options.Clear();
|
||||
|
||||
foreach (var scene in SceneHandler.LoadedScenes)
|
||||
foreach (var scene in loadedScenes)
|
||||
{
|
||||
if (sceneToDropdownOption.ContainsKey(scene))
|
||||
continue;
|
||||
@ -158,7 +158,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
}
|
||||
|
||||
Tree.CurrentFilter = input;
|
||||
Tree.RefreshData(true, true);
|
||||
Tree.RefreshData(true, false, true, false);
|
||||
}
|
||||
|
||||
private void TryLoadScene(LoadSceneMode mode, Dropdown allSceneDrop)
|
||||
@ -198,11 +198,11 @@ namespace UnityExplorer.ObjectExplorer
|
||||
var dropLabel = UIFactory.CreateLabel(dropRow, "SelectorLabel", "Scene:", TextAnchor.MiddleLeft, Color.cyan, false, 15);
|
||||
UIFactory.SetLayoutElement(dropLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0);
|
||||
|
||||
var dropdownObj = UIFactory.CreateDropdown(dropRow, "SceneDropdown", out sceneDropdown, "<notset>", 13, OnDropdownChanged);
|
||||
var dropdownObj = UIFactory.CreateDropdown(dropRow, "SceneDropdown", out sceneDropdown, "<notset>", 13, OnSceneSelectionDropdownChanged);
|
||||
UIFactory.SetLayoutElement(dropdownObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||
|
||||
SceneHandler.Update();
|
||||
PopulateSceneDropdown();
|
||||
PopulateSceneDropdown(SceneHandler.LoadedScenes);
|
||||
sceneDropdown.captionText.text = sceneToDropdownOption.First().Value.text;
|
||||
|
||||
// Filter row
|
||||
@ -239,6 +239,17 @@ namespace UnityExplorer.ObjectExplorer
|
||||
|
||||
refreshRow.SetActive(false);
|
||||
|
||||
// tree labels row
|
||||
|
||||
var labelsRow = UIFactory.CreateHorizontalGroup(toolbar, "LabelsRow", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||
UIFactory.SetLayoutElement(labelsRow, minHeight: 30, flexibleHeight: 0);
|
||||
|
||||
var nameLabel = UIFactory.CreateLabel(labelsRow, "NameLabel", "Name", TextAnchor.MiddleLeft, color: Color.grey);
|
||||
UIFactory.SetLayoutElement(nameLabel.gameObject, flexibleWidth: 9999, minHeight: 25);
|
||||
|
||||
var indexLabel = UIFactory.CreateLabel(labelsRow, "IndexLabel", "Sibling Index", TextAnchor.MiddleLeft, fontSize: 12, color: Color.grey);
|
||||
UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 100, flexibleWidth: 0, minHeight: 25);
|
||||
|
||||
// Transform Tree
|
||||
|
||||
var scrollPool = UIFactory.CreateScrollPool<TransformCell>(uiRoot, "TransformTree", out GameObject scrollObj,
|
||||
@ -248,7 +259,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
|
||||
Tree = new TransformTree(scrollPool, GetRootEntries);
|
||||
Tree.Init();
|
||||
Tree.RefreshData(true, true);
|
||||
Tree.RefreshData(true, true, true, false);
|
||||
//scrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
||||
//UIRoot.GetComponent<Mask>().enabled = false;
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
get => selectedScene;
|
||||
internal set
|
||||
{
|
||||
if (selectedScene != null && selectedScene == value)
|
||||
if (selectedScene.HasValue && selectedScene == value)
|
||||
return;
|
||||
selectedScene = value;
|
||||
OnInspectedSceneChanged?.Invoke((Scene)selectedScene);
|
||||
@ -30,7 +30,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
|
||||
/// <summary>All currently loaded Scenes.</summary>
|
||||
public static List<Scene> LoadedScenes { get; private set; } = new();
|
||||
private static HashSet<Scene> previousLoadedScenes;
|
||||
//private static HashSet<Scene> previousLoadedScenes;
|
||||
|
||||
/// <summary>The names of all scenes in the build settings, if they could be retrieved.</summary>
|
||||
public static List<string> AllSceneNames { get; private set; } = new();
|
||||
@ -39,7 +39,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
public static event Action<Scene> OnInspectedSceneChanged;
|
||||
|
||||
/// <summary>Invoked whenever the list of currently loaded Scenes changes. The argument contains all loaded scenes after the change.</summary>
|
||||
public static event Action<List<Scene>> OnLoadedScenesChanged;
|
||||
public static event Action<List<Scene>> OnLoadedScenesUpdated;
|
||||
|
||||
/// <summary>Generally will be 2, unless DontDestroyExists == false, then this will be 1.</summary>
|
||||
internal static int DefaultSceneCount => 1 + (DontDestroyExists ? 1 : 0);
|
||||
@ -84,23 +84,20 @@ namespace UnityExplorer.ObjectExplorer
|
||||
|
||||
internal static void Update()
|
||||
{
|
||||
// check if the loaded scenes changed. always confirm DontDestroy / HideAndDontSave
|
||||
int confirmedCount = DefaultSceneCount;
|
||||
bool inspectedExists = (SelectedScene.HasValue && SelectedScene.Value.handle == -12)
|
||||
|| (SelectedScene.HasValue && SelectedScene.Value.handle == -1);
|
||||
// Inspected scene will exist if it's DontDestroyOnLoad or HideAndDontSave
|
||||
bool inspectedExists =
|
||||
SelectedScene.HasValue
|
||||
&& ((DontDestroyExists && SelectedScene.Value.handle == -12)
|
||||
|| SelectedScene.Value.handle == -1);
|
||||
|
||||
LoadedScenes.Clear();
|
||||
|
||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
Scene scene = SceneManager.GetSceneAt(i);
|
||||
if (scene == default || !scene.isLoaded)
|
||||
if (scene == default || !scene.isLoaded || !scene.IsValid())
|
||||
continue;
|
||||
|
||||
// If no changes yet, ensure the previous list contained the scene
|
||||
if (previousLoadedScenes != null && previousLoadedScenes.Contains(scene))
|
||||
confirmedCount++;
|
||||
|
||||
// If we have not yet confirmed inspectedExists, check if this scene is our currently inspected one.
|
||||
if (!inspectedExists && scene == SelectedScene)
|
||||
inspectedExists = true;
|
||||
@ -112,17 +109,12 @@ namespace UnityExplorer.ObjectExplorer
|
||||
LoadedScenes.Add(new Scene { m_Handle = -12 });
|
||||
LoadedScenes.Add(new Scene { m_Handle = -1 });
|
||||
|
||||
bool anyChange = confirmedCount != LoadedScenes.Count;
|
||||
|
||||
previousLoadedScenes = new HashSet<Scene>(LoadedScenes);
|
||||
|
||||
// Default to first scene if none selected or previous selection no longer exists.
|
||||
if (!inspectedExists)
|
||||
SelectedScene = LoadedScenes.First();
|
||||
|
||||
// Notify on the list changing at all
|
||||
if (anyChange)
|
||||
OnLoadedScenesChanged?.Invoke(LoadedScenes);
|
||||
OnLoadedScenesUpdated?.Invoke(LoadedScenes);
|
||||
|
||||
// Finally, update the root objects list.
|
||||
if (SelectedScene != null && ((Scene)SelectedScene).IsValid())
|
||||
|
@ -1,5 +1,4 @@
|
||||
#if MONO
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.Runtime
|
||||
|
38
src/Runtime/UnityCrashPrevention.cs
Normal file
38
src/Runtime/UnityCrashPrevention.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using HarmonyLib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.CacheObject;
|
||||
|
||||
namespace UnityExplorer.Runtime
|
||||
{
|
||||
internal static class UnityCrashPrevention
|
||||
{
|
||||
internal static void Init()
|
||||
{
|
||||
try
|
||||
{
|
||||
ExplorerCore.Harmony.PatchAll(typeof(UnityCrashPrevention));
|
||||
ExplorerCore.Log("Initialized UnityCrashPrevention.");
|
||||
}
|
||||
catch //(Exception ex)
|
||||
{
|
||||
//ExplorerCore.Log($"Exception setting up Canvas crash prevention patch: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
// In Unity 2020 they introduced "Canvas.renderingDisplaySize".
|
||||
// If you try to get the value on a Canvas which has a renderMode value of WorldSpace and no worldCamera set,
|
||||
// the game will Crash (I think from Unity trying to read from null ptr).
|
||||
[HarmonyPatch(typeof(Canvas), "renderingDisplaySize", MethodType.Getter)]
|
||||
[HarmonyPrefix]
|
||||
internal static void Prefix_Canvas_renderingDisplaySize(Canvas __instance)
|
||||
{
|
||||
if (__instance.renderMode == RenderMode.WorldSpace && !__instance.worldCamera)
|
||||
throw new InvalidOperationException(
|
||||
"Canvas is set to RenderMode.WorldSpace but not worldCamera is set, cannot get renderingDisplaySize.");
|
||||
}
|
||||
}
|
||||
}
|
@ -146,22 +146,22 @@ namespace UnityExplorer.Tests
|
||||
}
|
||||
|
||||
#if CPP
|
||||
public static Il2CppSystem.Collections.Generic.Dictionary<string, string> IL2CPP_Dict;
|
||||
public static Il2CppSystem.Collections.Generic.HashSet<string> IL2CPP_HashSet;
|
||||
public static Il2CppSystem.Collections.Generic.List<string> IL2CPP_ListString;
|
||||
public static Il2CppSystem.Collections.Hashtable IL2CPP_HashTable;
|
||||
public static List<Il2CppSystem.Object> IL2CPP_listOfBoxedObjects;
|
||||
public static Il2CppStructArray<int> IL2CPP_structArray;
|
||||
public static Il2CppReferenceArray<Il2CppSystem.Object> IL2CPP_ReferenceArray;
|
||||
public static Il2CppSystem.Collections.IDictionary IL2CPP_IDict;
|
||||
public static Il2CppSystem.Collections.IList IL2CPP_IList;
|
||||
public static Dictionary<Il2CppSystem.String, Il2CppSystem.Object> CppBoxedDict;
|
||||
|
||||
public static Il2CppSystem.Collections.Generic.HashSet<string> IL2CPP_HashSet;
|
||||
public static Il2CppSystem.Collections.Generic.Dictionary<string, string> IL2CPP_Dict;
|
||||
public static Il2CppSystem.Collections.Hashtable IL2CPP_HashTable;
|
||||
public static Il2CppSystem.Object cppBoxedInt;
|
||||
public static Il2CppSystem.Int32 cppInt;
|
||||
public static Il2CppSystem.Decimal cppDecimal;
|
||||
public static Il2CppSystem.Object cppDecimalBoxed;
|
||||
public static Il2CppSystem.Object cppVector3Boxed;
|
||||
public static Dictionary<Il2CppSystem.Object, Il2CppSystem.Object> IL2CPP_BoxedDict;
|
||||
|
||||
public static Il2CppSystem.Object IL2CPP_BoxedInt;
|
||||
public static Il2CppSystem.Int32 IL2CPP_Int;
|
||||
public static Il2CppSystem.Decimal IL2CPP_Decimal;
|
||||
public static Il2CppSystem.Object IL2CPP_DecimalBoxed;
|
||||
public static Il2CppSystem.Object IL2CPP_Vector3Boxed;
|
||||
public static string IL2CPP_systemString = "Test";
|
||||
public static Il2CppSystem.Object IL2CPP_objectString = "string boxed as cpp object";
|
||||
public static Il2CppSystem.String IL2CPP_il2cppString = "string boxed as cpp string";
|
||||
@ -175,40 +175,41 @@ namespace UnityExplorer.Tests
|
||||
IL2CPP_Dict.Add("key2", "value2");
|
||||
IL2CPP_Dict.Add("key3", "value3");
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 2: Il2Cpp Hashtable");
|
||||
IL2CPP_HashTable = new Il2CppSystem.Collections.Hashtable();
|
||||
IL2CPP_HashTable.Add("key1", "value1");
|
||||
IL2CPP_HashTable.Add("key2", "value2");
|
||||
IL2CPP_HashTable.Add("key3", "value3");
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 3: Il2Cpp IDictionary");
|
||||
var dict2 = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
|
||||
dict2.Add("key1", "value1");
|
||||
IL2CPP_IDict = dict2.TryCast<Il2CppSystem.Collections.IDictionary>();
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 4: Il2Cpp List of Il2Cpp Object");
|
||||
var list = new Il2CppSystem.Collections.Generic.List<Il2CppSystem.Object>(5);
|
||||
list.Add("one");
|
||||
list.Add("two");
|
||||
IL2CPP_IList = list.TryCast<Il2CppSystem.Collections.IList>();
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 5: Il2Cpp List of strings");
|
||||
IL2CPP_ListString = new Il2CppSystem.Collections.Generic.List<string>();
|
||||
IL2CPP_ListString.Add("hello,");
|
||||
IL2CPP_ListString.Add("world!");
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 6: Il2Cpp HashSet of strings");
|
||||
IL2CPP_HashSet = new Il2CppSystem.Collections.Generic.HashSet<string>();
|
||||
IL2CPP_HashSet.Add("one");
|
||||
IL2CPP_HashSet.Add("two");
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 2: Il2Cpp Hashtable");
|
||||
IL2CPP_HashTable = new Il2CppSystem.Collections.Hashtable();
|
||||
IL2CPP_HashTable.Add("key1", "value1");
|
||||
IL2CPP_HashTable.Add("key2", "value2");
|
||||
IL2CPP_HashTable.Add("key3", "value3");
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 3: Il2Cpp IDictionary");
|
||||
var dict2 = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
|
||||
dict2.Add("key1", "value1");
|
||||
IL2CPP_IDict = dict2.TryCast<Il2CppSystem.Collections.IDictionary>();
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 4: Il2Cpp List of Il2Cpp Object");
|
||||
var list = new Il2CppSystem.Collections.Generic.List<Il2CppSystem.Object>(5);
|
||||
list.Add("one");
|
||||
list.Add("two");
|
||||
IL2CPP_IList = list.TryCast<Il2CppSystem.Collections.IList>();
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 5: Il2Cpp List of strings");
|
||||
IL2CPP_ListString = new Il2CppSystem.Collections.Generic.List<string>();
|
||||
IL2CPP_ListString.Add("hello,");
|
||||
IL2CPP_ListString.Add("world!");
|
||||
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 7: Dictionary of Il2Cpp String and Il2Cpp Object");
|
||||
CppBoxedDict = new Dictionary<Il2CppSystem.String, Il2CppSystem.Object>();
|
||||
CppBoxedDict.Add("1", new Il2CppSystem.Int32 { m_value = 1 }.BoxIl2CppObject());
|
||||
CppBoxedDict.Add("2", new Il2CppSystem.Int32 { m_value = 2 }.BoxIl2CppObject());
|
||||
CppBoxedDict.Add("3", new Il2CppSystem.Int32 { m_value = 3 }.BoxIl2CppObject());
|
||||
CppBoxedDict.Add("4", new Il2CppSystem.Int32 { m_value = 4 }.BoxIl2CppObject());
|
||||
|
||||
IL2CPP_BoxedDict = new();
|
||||
IL2CPP_BoxedDict[(Il2CppSystem.String)"one"] = new Il2CppSystem.Int32 { m_value = 1 }.BoxIl2CppObject();
|
||||
IL2CPP_BoxedDict[(Il2CppSystem.String)"two"] = new Il2CppSystem.Int32 { m_value = 2 }.BoxIl2CppObject();
|
||||
IL2CPP_BoxedDict[(Il2CppSystem.String)"three"] = new Il2CppSystem.Int32 { m_value = 3 }.BoxIl2CppObject();
|
||||
IL2CPP_BoxedDict[(Il2CppSystem.String)"four"] = new Il2CppSystem.Int32 { m_value = 4 }.BoxIl2CppObject();
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 8: List of boxed Il2Cpp Objects");
|
||||
IL2CPP_listOfBoxedObjects = new List<Il2CppSystem.Object>();
|
||||
IL2CPP_listOfBoxedObjects.Add((Il2CppSystem.String)"boxedString");
|
||||
@ -223,16 +224,16 @@ namespace UnityExplorer.Tests
|
||||
var boxedEnum = Il2CppSystem.Enum.Parse(cppType, "Color");
|
||||
IL2CPP_listOfBoxedObjects.Add(boxedEnum);
|
||||
}
|
||||
|
||||
|
||||
var structBox = Vector3.one.BoxIl2CppObject();
|
||||
IL2CPP_listOfBoxedObjects.Add(structBox);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Boxed enum test fail: {ex}");
|
||||
}
|
||||
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 9: Il2Cpp struct array of ints");
|
||||
IL2CPP_structArray = new UnhollowerBaseLib.Il2CppStructArray<int>(5);
|
||||
IL2CPP_structArray[0] = 0;
|
||||
@ -240,19 +241,19 @@ namespace UnityExplorer.Tests
|
||||
IL2CPP_structArray[2] = 2;
|
||||
IL2CPP_structArray[3] = 3;
|
||||
IL2CPP_structArray[4] = 4;
|
||||
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 10: Il2Cpp reference array of boxed objects");
|
||||
IL2CPP_ReferenceArray = new UnhollowerBaseLib.Il2CppReferenceArray<Il2CppSystem.Object>(3);
|
||||
IL2CPP_ReferenceArray[0] = new Il2CppSystem.Int32 { m_value = 5 }.BoxIl2CppObject();
|
||||
IL2CPP_ReferenceArray[1] = null;
|
||||
IL2CPP_ReferenceArray[2] = (Il2CppSystem.String)"whats up";
|
||||
|
||||
|
||||
ExplorerCore.Log($"IL2CPP 11: Misc il2cpp members");
|
||||
cppBoxedInt = new Il2CppSystem.Int32() { m_value = 5 }.BoxIl2CppObject();
|
||||
cppInt = new Il2CppSystem.Int32 { m_value = 420 };
|
||||
cppDecimal = new Il2CppSystem.Decimal(1f);
|
||||
cppDecimalBoxed = new Il2CppSystem.Decimal(1f).BoxIl2CppObject();
|
||||
cppVector3Boxed = Vector3.down.BoxIl2CppObject();
|
||||
IL2CPP_BoxedInt = new Il2CppSystem.Int32() { m_value = 5 }.BoxIl2CppObject();
|
||||
IL2CPP_Int = new Il2CppSystem.Int32 { m_value = 420 };
|
||||
IL2CPP_Decimal = new Il2CppSystem.Decimal(1f);
|
||||
IL2CPP_DecimalBoxed = new Il2CppSystem.Decimal(1f).BoxIl2CppObject();
|
||||
IL2CPP_Vector3Boxed = Vector3.down.BoxIl2CppObject();
|
||||
|
||||
ExplorerCore.Log($"Finished Init_Il2Cpp");
|
||||
}
|
||||
|
@ -30,13 +30,13 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
public override int MinWidth => -1;
|
||||
public override int MinHeight => -1;
|
||||
|
||||
public override bool CanDragAndResize => false;
|
||||
public override bool CanDragAndResize => true;
|
||||
public override bool ShouldSaveActiveState => false;
|
||||
public override bool NavButtonWanted => false;
|
||||
|
||||
public static ISuggestionProvider CurrentHandler { get; private set; }
|
||||
|
||||
public static ButtonListHandler<Suggestion, ButtonCell> dataHandler;
|
||||
public static ButtonListHandler<Suggestion, ButtonCell> buttonListDataHandler;
|
||||
public static ScrollPool<ButtonCell> scrollPool;
|
||||
private static GameObject navigationTipRow;
|
||||
|
||||
@ -82,7 +82,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
{
|
||||
base.UIRoot.SetActive(true);
|
||||
base.UIRoot.transform.SetAsLastSibling();
|
||||
dataHandler.RefreshData();
|
||||
buttonListDataHandler.RefreshData();
|
||||
scrollPool.Refresh(true, true);
|
||||
}
|
||||
}
|
||||
@ -294,24 +294,44 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
|
||||
// UI Construction
|
||||
|
||||
const float MIN_X = 0.42f;
|
||||
const float MAX_Y = 0.6f;
|
||||
|
||||
protected internal override void DoSetDefaultPosAndAnchors()
|
||||
{
|
||||
Rect.pivot = new Vector2(0f, 1f);
|
||||
Rect.anchorMin = new Vector2(0.42f, 0.4f);
|
||||
Rect.anchorMax = new Vector2(0.68f, 0.6f);
|
||||
Rect.anchorMin = new Vector2(MIN_X, 0.4f);
|
||||
Rect.anchorMax = new Vector2(0.68f, MAX_Y);
|
||||
}
|
||||
|
||||
public override void OnFinishResize(RectTransform panel)
|
||||
{
|
||||
float xDiff = panel.anchorMin.x - MIN_X;
|
||||
float yDiff = panel.anchorMax.y - MAX_Y;
|
||||
|
||||
if (xDiff != 0 || yDiff != 0)
|
||||
{
|
||||
panel.anchorMin = new(MIN_X, panel.anchorMin.y - yDiff);
|
||||
panel.anchorMax = new(panel.anchorMax.x - xDiff, MAX_Y);
|
||||
}
|
||||
|
||||
base.OnFinishResize(panel);
|
||||
}
|
||||
|
||||
public override void ConstructPanelContent()
|
||||
{
|
||||
dataHandler = new ButtonListHandler<Suggestion, ButtonCell>(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked);
|
||||
// hide the titlebar
|
||||
this.TitleBar.gameObject.SetActive(false);
|
||||
|
||||
scrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiRoot, "AutoCompleter", out GameObject scrollObj,
|
||||
buttonListDataHandler = new ButtonListHandler<Suggestion, ButtonCell>(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked);
|
||||
|
||||
scrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiContent, "AutoCompleter", out GameObject scrollObj,
|
||||
out GameObject scrollContent);
|
||||
scrollPool.Initialize(dataHandler);
|
||||
scrollPool.Initialize(buttonListDataHandler);
|
||||
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, false, true, false);
|
||||
|
||||
navigationTipRow = UIFactory.CreateHorizontalGroup(this.uiRoot, "BottomRow", true, true, true, true, 0, new Vector4(2, 2, 2, 2));
|
||||
navigationTipRow = UIFactory.CreateHorizontalGroup(this.uiContent, "BottomRow", true, true, true, true, 0, new Vector4(2, 2, 2, 2));
|
||||
UIFactory.SetLayoutElement(navigationTipRow, minHeight: 20, flexibleWidth: 9999);
|
||||
UIFactory.CreateLabel(navigationTipRow, "HelpText", "Up/Down to select, Enter to use, Esc to close",
|
||||
TextAnchor.MiddleLeft, Color.grey, false, 13);
|
@ -75,7 +75,7 @@ namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
// Tools Row
|
||||
|
||||
var toolsRow = UIFactory.CreateHorizontalGroup(this.uiRoot, "ToggleRow", false, false, true, true, 5, new Vector4(8, 8, 10, 5),
|
||||
var toolsRow = UIFactory.CreateHorizontalGroup(this.uiContent, "ToggleRow", false, false, true, true, 5, new Vector4(8, 8, 10, 5),
|
||||
default, TextAnchor.MiddleLeft);
|
||||
UIFactory.SetLayoutElement(toolsRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||
|
||||
@ -124,7 +124,7 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
// Console Input
|
||||
|
||||
var inputArea = UIFactory.CreateUIObject("InputGroup", uiRoot);
|
||||
var inputArea = UIFactory.CreateUIObject("InputGroup", uiContent);
|
||||
UIFactory.SetLayoutElement(inputArea, flexibleWidth: 9999, flexibleHeight: 9999);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(inputArea, false, true, true, true);
|
||||
inputArea.AddComponent<Image>().color = Color.white;
|
||||
|
@ -89,7 +89,7 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
// Actual panel content
|
||||
|
||||
var firstRow = UIFactory.CreateHorizontalGroup(UIRoot, "FirstRow", false, false, true, true, 5, new(2,2,2,2), new(1,1,1,0));
|
||||
var firstRow = UIFactory.CreateHorizontalGroup(uiContent, "FirstRow", false, false, true, true, 5, new(2,2,2,2), new(1,1,1,0));
|
||||
UIFactory.SetLayoutElement(firstRow, minHeight: 25, flexibleWidth: 999);
|
||||
|
||||
// Title for "Current Paste:"
|
||||
@ -102,7 +102,7 @@ namespace UnityExplorer.UI.Panels
|
||||
clearButton.OnClick += () => Copy(null);
|
||||
|
||||
// Current Paste info row
|
||||
var currentPasteHolder = UIFactory.CreateHorizontalGroup(UIRoot, "SecondRow", false, false, true, true, 0,
|
||||
var currentPasteHolder = UIFactory.CreateHorizontalGroup(uiContent, "SecondRow", false, false, true, true, 0,
|
||||
new(2, 2, 2, 2), childAlignment: TextAnchor.UpperCenter);
|
||||
|
||||
// Actual current paste info label
|
||||
|
@ -83,7 +83,7 @@ namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
// ~~~~~~~~~ Active hooks scroll pool
|
||||
|
||||
currentHooksPanel = UIFactory.CreateUIObject("CurrentHooksPanel", this.uiRoot);
|
||||
currentHooksPanel = UIFactory.CreateUIObject("CurrentHooksPanel", this.uiContent);
|
||||
UIFactory.SetLayoutElement(currentHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(currentHooksPanel, true, true, true, true);
|
||||
|
||||
@ -109,7 +109,7 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
// ~~~~~~~~~ Add hooks panel
|
||||
|
||||
addHooksPanel = UIFactory.CreateUIObject("AddHooksPanel", this.uiRoot);
|
||||
addHooksPanel = UIFactory.CreateUIObject("AddHooksPanel", this.uiContent);
|
||||
UIFactory.SetLayoutElement(addHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(addHooksPanel, true, true, true, true);
|
||||
|
||||
@ -136,7 +136,7 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
// ~~~~~~~~~ Hook source editor panel
|
||||
|
||||
editorPanel = UIFactory.CreateUIObject("HookSourceEditor", this.uiRoot);
|
||||
editorPanel = UIFactory.CreateUIObject("HookSourceEditor", this.uiContent);
|
||||
UIFactory.SetLayoutElement(editorPanel, flexibleHeight: 9999, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(editorPanel, true, true, true, true);
|
||||
|
||||
|
@ -54,12 +54,12 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
public override void ConstructPanelContent()
|
||||
{
|
||||
var closeHolder = this.titleBar.transform.Find("CloseHolder").gameObject;
|
||||
var closeHolder = this.TitleBar.transform.Find("CloseHolder").gameObject;
|
||||
|
||||
// Inspect under mouse dropdown on title bar
|
||||
|
||||
var mouseDropdown = UIFactory.CreateDropdown(closeHolder, "MouseInspectDropdown", out MouseInspectDropdown, "Mouse Inspect", 14,
|
||||
InspectUnderMouse.OnDropdownSelect);
|
||||
MouseInspector.OnDropdownSelect);
|
||||
UIFactory.SetLayoutElement(mouseDropdown, minHeight: 25, minWidth: 140);
|
||||
MouseInspectDropdown.options.Add(new Dropdown.OptionData("Mouse Inspect"));
|
||||
MouseInspectDropdown.options.Add(new Dropdown.OptionData("World"));
|
||||
@ -76,14 +76,14 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
// this.UIRoot.GetComponent<Mask>().enabled = false;
|
||||
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiRoot, true, true, true, true, 4, padLeft: 5, padRight: 5);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiContent, true, true, true, true, 4, padLeft: 5, padRight: 5);
|
||||
|
||||
this.NavbarHolder = UIFactory.CreateGridGroup(this.uiRoot, "Navbar", new Vector2(200, 22), new Vector2(4, 4),
|
||||
this.NavbarHolder = UIFactory.CreateGridGroup(this.uiContent, "Navbar", new Vector2(200, 22), new Vector2(4, 4),
|
||||
new Color(0.05f, 0.05f, 0.05f));
|
||||
//UIFactory.SetLayoutElement(NavbarHolder, flexibleWidth: 9999, minHeight: 0, preferredHeight: 0, flexibleHeight: 9999);
|
||||
NavbarHolder.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
this.ContentHolder = UIFactory.CreateVerticalGroup(this.uiRoot, "ContentHolder", true, true, true, true, 0, default,
|
||||
this.ContentHolder = UIFactory.CreateVerticalGroup(this.uiContent, "ContentHolder", true, true, true, true, 0, default,
|
||||
new Color(0.1f, 0.1f, 0.1f));
|
||||
UIFactory.SetLayoutElement(ContentHolder, flexibleHeight: 9999);
|
||||
ContentRect = ContentHolder.GetComponent<RectTransform>();
|
||||
|
@ -161,13 +161,13 @@ namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
// Log scroll pool
|
||||
|
||||
logScrollPool = UIFactory.CreateScrollPool<ConsoleLogCell>(this.uiRoot, "Logs", out GameObject scrollObj,
|
||||
logScrollPool = UIFactory.CreateScrollPool<ConsoleLogCell>(this.uiContent, "Logs", out GameObject scrollObj,
|
||||
out GameObject scrollContent, new Color(0.03f, 0.03f, 0.03f));
|
||||
UIFactory.SetLayoutElement(scrollObj, flexibleWidth: 9999, flexibleHeight: 9999);
|
||||
|
||||
// Buttons and toggles
|
||||
|
||||
var optionsRow = UIFactory.CreateUIObject("OptionsRow", this.uiRoot);
|
||||
var optionsRow = UIFactory.CreateUIObject("OptionsRow", this.uiContent);
|
||||
UIFactory.SetLayoutElement(optionsRow, minHeight: 25, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(optionsRow, false, false, true, true, 5, 2, 2, 2, 2);
|
||||
|
||||
|
@ -99,17 +99,17 @@ namespace UnityExplorer.UI.Panels
|
||||
public override void ConstructPanelContent()
|
||||
{
|
||||
// Tab bar
|
||||
var tabGroup = UIFactory.CreateHorizontalGroup(uiRoot, "TabBar", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||
var tabGroup = UIFactory.CreateHorizontalGroup(uiContent, "TabBar", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||
UIFactory.SetLayoutElement(tabGroup, minHeight: 25, flexibleHeight: 0);
|
||||
|
||||
// Scene Explorer
|
||||
SceneExplorer = new SceneExplorer(this);
|
||||
SceneExplorer.ConstructUI(uiRoot);
|
||||
SceneExplorer.ConstructUI(uiContent);
|
||||
tabPages.Add(SceneExplorer);
|
||||
|
||||
// Object search
|
||||
ObjectSearch = new ObjectSearch(this);
|
||||
ObjectSearch.ConstructUI(uiRoot);
|
||||
ObjectSearch.ConstructUI(uiContent);
|
||||
tabPages.Add(ObjectSearch);
|
||||
|
||||
// set up tabs
|
||||
|
@ -71,13 +71,13 @@ namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
// Save button
|
||||
|
||||
var saveBtn = UIFactory.CreateButton(this.uiRoot, "Save", "Save Options", new Color(0.2f, 0.3f, 0.2f));
|
||||
var saveBtn = UIFactory.CreateButton(this.uiContent, "Save", "Save Options", new Color(0.2f, 0.3f, 0.2f));
|
||||
UIFactory.SetLayoutElement(saveBtn.Component.gameObject, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 0);
|
||||
saveBtn.OnClick += ConfigManager.Handler.SaveConfig;
|
||||
|
||||
// Config entries
|
||||
|
||||
var scrollPool = UIFactory.CreateScrollPool<ConfigEntryCell>(this.uiRoot, "ConfigEntries", out GameObject scrollObj,
|
||||
var scrollPool = UIFactory.CreateScrollPool<ConfigEntryCell>(this.uiContent, "ConfigEntries", out GameObject scrollObj,
|
||||
out GameObject scrollContent);
|
||||
|
||||
scrollPool.Initialize(this);
|
||||
|
@ -87,13 +87,14 @@ namespace UnityExplorer.UI.Panels
|
||||
public virtual bool CanDragAndResize => true;
|
||||
public virtual bool NavButtonWanted => true;
|
||||
|
||||
public ButtonRef NavButton;
|
||||
public PanelDragger Dragger;
|
||||
public ButtonRef NavButton { get; internal set; }
|
||||
public PanelDragger Dragger { get; internal set; }
|
||||
|
||||
public override GameObject UIRoot => uiRoot;
|
||||
protected GameObject uiRoot;
|
||||
public RectTransform Rect;
|
||||
public GameObject titleBar;
|
||||
protected GameObject uiContent;
|
||||
public RectTransform Rect { get; private set; }
|
||||
public GameObject TitleBar { get; private set; }
|
||||
|
||||
public virtual void OnFinishResize(RectTransform panel)
|
||||
{
|
||||
@ -107,22 +108,27 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
public override void SetActive(bool active)
|
||||
{
|
||||
if (this.Enabled == active)
|
||||
return;
|
||||
|
||||
base.SetActive(active);
|
||||
|
||||
if (!ApplyingSaveData)
|
||||
SaveInternalData();
|
||||
|
||||
if (NavButtonWanted)
|
||||
if (this.Enabled != active)
|
||||
{
|
||||
var color = active ? UniversalUI.EnabledButtonColor : UniversalUI.DisabledButtonColor;
|
||||
RuntimeHelper.SetColorBlock(NavButton.Component, color, color * 1.2f);
|
||||
base.SetActive(active);
|
||||
|
||||
if (!ApplyingSaveData)
|
||||
SaveInternalData();
|
||||
|
||||
if (NavButtonWanted)
|
||||
{
|
||||
var color = active ? UniversalUI.EnabledButtonColor : UniversalUI.DisabledButtonColor;
|
||||
RuntimeHelper.SetColorBlock(NavButton.Component, color, color * 1.2f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!active)
|
||||
this.Dragger.WasDragging = false;
|
||||
else
|
||||
{
|
||||
this.UIRoot.transform.SetAsLastSibling();
|
||||
InvokeOnPanelsReordered();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
@ -247,29 +253,28 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
|
||||
// create core canvas
|
||||
uiRoot = UIFactory.CreatePanel(Name, UIManager.PanelHolder);
|
||||
uiRoot = UIFactory.CreatePanel(Name, UIManager.PanelHolder, out uiContent);
|
||||
Rect = this.uiRoot.GetComponent<RectTransform>();
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiRoot, false, false, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft);
|
||||
//UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiRoot, false, false, true, true, 0, 2, 2, 2, 2, TextAnchor.UpperLeft);
|
||||
|
||||
int id = this.uiRoot.transform.GetInstanceID();
|
||||
transformToPanelDict.Add(id, this);
|
||||
|
||||
//content = panelContent;
|
||||
//UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.content, false, false, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft);
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiContent, false, false, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft);
|
||||
|
||||
// Title bar
|
||||
titleBar = UIFactory.CreateHorizontalGroup(uiRoot, "TitleBar", false, true, true, true, 2,
|
||||
TitleBar = UIFactory.CreateHorizontalGroup(uiContent, "TitleBar", false, true, true, true, 2,
|
||||
new Vector4(2, 2, 2, 2), new Color(0.06f, 0.06f, 0.06f));
|
||||
UIFactory.SetLayoutElement(titleBar, minHeight: 25, flexibleHeight: 0);
|
||||
UIFactory.SetLayoutElement(TitleBar, minHeight: 25, flexibleHeight: 0);
|
||||
|
||||
// Title text
|
||||
|
||||
var titleTxt = UIFactory.CreateLabel(titleBar, "TitleBar", Name, TextAnchor.MiddleLeft);
|
||||
var titleTxt = UIFactory.CreateLabel(TitleBar, "TitleBar", Name, TextAnchor.MiddleLeft);
|
||||
UIFactory.SetLayoutElement(titleTxt.gameObject, minWidth: 250, minHeight: 25, flexibleHeight: 0);
|
||||
|
||||
// close button
|
||||
|
||||
var closeHolder = UIFactory.CreateUIObject("CloseHolder", titleBar);
|
||||
var closeHolder = UIFactory.CreateUIObject("CloseHolder", TitleBar);
|
||||
UIFactory.SetLayoutElement(closeHolder, minHeight: 25, flexibleHeight: 0, minWidth: 30, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(closeHolder, false, false, true, true, 3, childAlignment: TextAnchor.MiddleRight);
|
||||
var closeBtn = UIFactory.CreateButton(closeHolder, "CloseButton", "—");
|
||||
@ -283,11 +288,11 @@ namespace UnityExplorer.UI.Panels
|
||||
};
|
||||
|
||||
if (!CanDragAndResize)
|
||||
titleBar.SetActive(false);
|
||||
TitleBar.SetActive(false);
|
||||
|
||||
// Panel dragger
|
||||
|
||||
Dragger = new PanelDragger(titleBar.GetComponent<RectTransform>(), Rect, this);
|
||||
Dragger = new PanelDragger(TitleBar.GetComponent<RectTransform>(), Rect, this);
|
||||
Dragger.OnFinishResize += OnFinishResize;
|
||||
Dragger.OnFinishDrag += OnFinishDrag;
|
||||
|
||||
|
@ -61,7 +61,7 @@ namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
dataHandler = new ButtonListHandler<GameObject, ButtonCell>(buttonScrollPool, GetEntries, SetCell, ShouldDisplayCell, OnCellClicked);
|
||||
|
||||
buttonScrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiRoot, "ResultsList", out GameObject scrollObj,
|
||||
buttonScrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiContent, "ResultsList", out GameObject scrollObj,
|
||||
out GameObject scrollContent);
|
||||
|
||||
buttonScrollPool.Initialize(dataHandler);
|
||||
|
@ -73,7 +73,7 @@ namespace UnityExplorer.UI
|
||||
return;
|
||||
|
||||
UniversalUI.SetUIActive(ExplorerCore.GUID, value);
|
||||
UniversalUI.SetUIActive(InspectUnderMouse.UIBaseGUID, value);
|
||||
UniversalUI.SetUIActive(MouseInspector.UIBaseGUID, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ namespace UnityExplorer.UI
|
||||
UIPanels.Add(Panels.ConsoleLog, new LogPanel());
|
||||
UIPanels.Add(Panels.Options, new OptionsPanel());
|
||||
UIPanels.Add(Panels.UIInspectorResults, new UiInspectorResultsPanel());
|
||||
UIPanels.Add(Panels.MouseInspector, new InspectUnderMouse());
|
||||
UIPanels.Add(Panels.MouseInspector, new MouseInspector());
|
||||
|
||||
foreach (var panel in UIPanels.Values)
|
||||
panel.ConstructUI();
|
||||
@ -135,12 +135,9 @@ namespace UnityExplorer.UI
|
||||
if (!UIRoot)
|
||||
return;
|
||||
|
||||
// if doing Mouse Inspect, update that and return.
|
||||
if (InspectUnderMouse.Inspecting)
|
||||
{
|
||||
InspectUnderMouse.Instance.UpdateInspect();
|
||||
// If we are doing a Mouse Inspect, we don't need to update anything else.
|
||||
if (MouseInspector.Instance.TryUpdate())
|
||||
return;
|
||||
}
|
||||
|
||||
// Update Notification modal
|
||||
Notification.Update();
|
||||
@ -187,26 +184,21 @@ namespace UnityExplorer.UI
|
||||
SetPanelActive(panel, !uiPanel.Enabled);
|
||||
}
|
||||
|
||||
public static void SetPanelActive(Panels panel, bool active)
|
||||
public static void SetPanelActive(Panels panelType, bool active)
|
||||
{
|
||||
var obj = GetPanel(panel);
|
||||
SetPanelActive(obj, active);
|
||||
GetPanel(panelType)
|
||||
.SetActive(active);
|
||||
}
|
||||
|
||||
public static void SetPanelActive(UIPanel panel, bool active)
|
||||
{
|
||||
panel.SetActive(active);
|
||||
if (active)
|
||||
{
|
||||
panel.UIRoot.transform.SetAsLastSibling();
|
||||
UIPanel.InvokeOnPanelsReordered();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SetPanelActive(Transform transform, bool value)
|
||||
{
|
||||
if (UIPanel.transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel))
|
||||
SetPanelActive(panel, value);
|
||||
panel.SetActive(value);
|
||||
}
|
||||
|
||||
// navbar
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using HarmonyLib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniverseLib;
|
||||
using UniverseLib.UI;
|
||||
using UniverseLib.UI.Models;
|
||||
@ -25,6 +27,8 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
|
||||
public Type BaseType { get; set; }
|
||||
public Type[] GenericConstraints { get; set; }
|
||||
public bool AllTypes { get; set; }
|
||||
|
||||
private readonly bool allowAbstract;
|
||||
private readonly bool allowEnum;
|
||||
|
||||
@ -58,7 +62,24 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
|
||||
public void CacheTypes()
|
||||
{
|
||||
allowedTypes = ReflectionUtility.GetImplementationsOf(BaseType, allowAbstract, allowEnum, false);
|
||||
if (!AllTypes)
|
||||
allowedTypes = ReflectionUtility.GetImplementationsOf(BaseType, allowAbstract, allowEnum, false);
|
||||
else
|
||||
{
|
||||
allowedTypes = new();
|
||||
foreach (var entry in ReflectionUtility.AllTypes)
|
||||
{
|
||||
// skip <PrivateImplementationDetails> and <AnonymousClass> classes
|
||||
var type = entry.Value;
|
||||
if (type.FullName.Contains("PrivateImplementationDetails")
|
||||
|| type.FullName.Contains("DisplayClass")
|
||||
|| type.FullName.Contains('<'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
allowedTypes.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSuggestionClicked(Suggestion suggestion)
|
||||
|
@ -12,6 +12,7 @@ using UniverseLib.UI;
|
||||
using UniverseLib;
|
||||
using UnityExplorer.CacheObject;
|
||||
using UniverseLib.UI.ObjectPool;
|
||||
using UniverseLib.Utility;
|
||||
|
||||
namespace UnityExplorer.UI.Widgets
|
||||
{
|
||||
@ -76,6 +77,9 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
public object[] TryParseArguments()
|
||||
{
|
||||
if (!parameters.Any())
|
||||
return ArgumentUtility.EmptyArgs;
|
||||
|
||||
object[] outArgs = new object[parameters.Length];
|
||||
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
|
@ -17,8 +17,9 @@ namespace UnityExplorer.UI.Widgets
|
||||
public int ChildCount { get; internal set; }
|
||||
public string Name { get; internal set; }
|
||||
public bool Enabled { get; internal set; }
|
||||
public int SiblingIndex { get; internal set; }
|
||||
|
||||
public bool Expanded => Tree.IsCellExpanded(InstanceID);
|
||||
public bool Expanded => Tree.IsTransformExpanded(InstanceID);
|
||||
|
||||
public CachedTransform(TransformTree tree, Transform transform, int depth, CachedTransform parent = null)
|
||||
{
|
||||
@ -26,27 +27,32 @@ namespace UnityExplorer.UI.Widgets
|
||||
Value = transform;
|
||||
Parent = parent;
|
||||
InstanceID = transform.GetInstanceID();
|
||||
SiblingIndex = transform.GetSiblingIndex();
|
||||
Update(transform, depth);
|
||||
}
|
||||
|
||||
public bool Update(Transform transform, int depth)
|
||||
{
|
||||
bool ret = false;
|
||||
bool changed = false;
|
||||
|
||||
if (Value != transform
|
||||
|| depth != Depth
|
||||
|| ChildCount != transform.childCount
|
||||
|| Name != transform.name
|
||||
|| Enabled != transform.gameObject.activeSelf)
|
||||
|| Enabled != transform.gameObject.activeSelf
|
||||
|| SiblingIndex != transform.GetSiblingIndex())
|
||||
{
|
||||
changed = true;
|
||||
|
||||
Value = transform;
|
||||
Depth = depth;
|
||||
ChildCount = transform.childCount;
|
||||
Name = transform.name;
|
||||
Enabled = transform.gameObject.activeSelf;
|
||||
ret = true;
|
||||
SiblingIndex = transform.GetSiblingIndex();
|
||||
}
|
||||
return ret;
|
||||
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ using UniverseLib.UI;
|
||||
using UniverseLib.UI.Models;
|
||||
using UniverseLib.UI.Widgets;
|
||||
using UniverseLib.UI.Widgets.ScrollView;
|
||||
using UniverseLib.Utility;
|
||||
|
||||
namespace UnityExplorer.UI.Widgets
|
||||
{
|
||||
@ -36,6 +37,7 @@ namespace UnityExplorer.UI.Widgets
|
||||
public ButtonRef ExpandButton;
|
||||
public ButtonRef NameButton;
|
||||
public Toggle EnabledToggle;
|
||||
public InputFieldRef SiblingIndex;
|
||||
|
||||
public LayoutElement spacer;
|
||||
|
||||
@ -77,6 +79,15 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
EnabledToggle.Set(cached.Value.gameObject.activeSelf, false);
|
||||
|
||||
if (!cached.Value.parent)
|
||||
SiblingIndex.GameObject.SetActive(false);
|
||||
else
|
||||
{
|
||||
SiblingIndex.GameObject.SetActive(true);
|
||||
if (!SiblingIndex.Component.isFocused)
|
||||
SiblingIndex.Text = cached.Value.GetSiblingIndex().ToString();
|
||||
}
|
||||
|
||||
int childCount = cached.Value.childCount;
|
||||
if (childCount > 0)
|
||||
{
|
||||
@ -97,6 +108,8 @@ namespace UnityExplorer.UI.Widgets
|
||||
{
|
||||
NameButton.ButtonText.text = $"[Destroyed]";
|
||||
NameButton.ButtonText.color = Color.red;
|
||||
|
||||
SiblingIndex.GameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +131,17 @@ namespace UnityExplorer.UI.Widgets
|
||||
OnEnableToggled?.Invoke(cachedTransform);
|
||||
}
|
||||
|
||||
private void OnSiblingIndexEndEdit(string input)
|
||||
{
|
||||
if (this.cachedTransform == null || !this.cachedTransform.Value)
|
||||
return;
|
||||
|
||||
if (int.TryParse(input.Trim(), out int index))
|
||||
this.cachedTransform.Value.SetSiblingIndex(index);
|
||||
|
||||
this.SiblingIndex.Text = this.cachedTransform.Value.GetSiblingIndex().ToString();
|
||||
}
|
||||
|
||||
public GameObject CreateContent(GameObject parent)
|
||||
{
|
||||
UIRoot = UIFactory.CreateUIObject("TransformCell", parent);
|
||||
@ -152,10 +176,22 @@ namespace UnityExplorer.UI.Widgets
|
||||
nameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||
nameLabel.alignment = TextAnchor.MiddleLeft;
|
||||
|
||||
Color normal = new Color(0.11f, 0.11f, 0.11f);
|
||||
Color highlight = new Color(0.25f, 0.25f, 0.25f);
|
||||
Color pressed = new Color(0.05f, 0.05f, 0.05f);
|
||||
Color disabled = new Color(1, 1, 1, 0);
|
||||
// Sibling index input
|
||||
|
||||
SiblingIndex = UIFactory.CreateInputField(this.UIRoot, "SiblingIndexInput", string.Empty);
|
||||
SiblingIndex.Component.textComponent.fontSize = 11;
|
||||
SiblingIndex.Component.textComponent.alignment = TextAnchor.MiddleRight;
|
||||
var siblingImage = SiblingIndex.GameObject.GetComponent<Image>();
|
||||
siblingImage.color = new(0f, 0f, 0f, 0.25f);
|
||||
UIFactory.SetLayoutElement(SiblingIndex.GameObject, 35, 20, 0, 0);
|
||||
SiblingIndex.Component.GetOnEndEdit().AddListener(OnSiblingIndexEndEdit);
|
||||
|
||||
// Setup selectables
|
||||
|
||||
Color normal = new(0.11f, 0.11f, 0.11f);
|
||||
Color highlight = new(0.25f, 0.25f, 0.25f);
|
||||
Color pressed = new(0.05f, 0.05f, 0.05f);
|
||||
Color disabled = new(1, 1, 1, 0);
|
||||
RuntimeHelper.SetColorBlock(ExpandButton.Component, normal, highlight, pressed, disabled);
|
||||
RuntimeHelper.SetColorBlock(NameButton.Component, normal, highlight, pressed, disabled);
|
||||
|
||||
|
@ -2,12 +2,9 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UniverseLib;
|
||||
using UniverseLib.UI.Widgets;
|
||||
using UniverseLib.UI.Widgets.ScrollView;
|
||||
using UniverseLib.Utility;
|
||||
|
||||
@ -20,22 +17,36 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
public ScrollPool<TransformCell> ScrollPool;
|
||||
|
||||
// IMPORTANT CAVEAT WITH OrderedDictionary:
|
||||
// While the performance is mostly good, there are two methods we should NEVER use:
|
||||
// - Remove(object)
|
||||
// - set_Item[object]
|
||||
// These two methods have extremely bad performance due to using IndexOfKey(), which iterates the whole dictionary.
|
||||
// Currently we do not use either of these methods, so everything should be constant time hash lookups.
|
||||
// We DO make use of get_Item[object], get_Item[index], Add, Insert and RemoveAt, which OrderedDictionary perfectly meets our needs for.
|
||||
/// <summary>
|
||||
/// Key: UnityEngine.Transform instance ID<br/>
|
||||
/// Value: CachedTransform
|
||||
/// </summary>
|
||||
internal readonly OrderedDictionary cachedTransforms = new OrderedDictionary();
|
||||
internal readonly OrderedDictionary cachedTransforms = new();
|
||||
|
||||
// for keeping track of which actual transforms are expanded or not, outside of the cache data.
|
||||
private readonly HashSet<int> expandedInstanceIDs = new HashSet<int>();
|
||||
private readonly HashSet<int> autoExpandedIDs = new HashSet<int>();
|
||||
private readonly HashSet<int> expandedInstanceIDs = new();
|
||||
private readonly HashSet<int> autoExpandedIDs = new();
|
||||
|
||||
private readonly HashSet<int> visited = new HashSet<int>();
|
||||
private bool needRefresh;
|
||||
// state for Traverse parse
|
||||
private readonly HashSet<int> visited = new();
|
||||
private bool needRefreshUI;
|
||||
private int displayIndex;
|
||||
int prevDisplayIndex;
|
||||
|
||||
public int ItemCount => cachedTransforms.Count;
|
||||
private Coroutine refreshCoroutine;
|
||||
private readonly Stopwatch traversedThisFrame = new();
|
||||
|
||||
// ScrollPool item count. PrevDisplayIndex is the highest index + 1 from our last traverse.
|
||||
public int ItemCount => prevDisplayIndex;
|
||||
|
||||
// Search filter
|
||||
public bool Filtering => !string.IsNullOrEmpty(currentFilter);
|
||||
private bool wasFiltering;
|
||||
|
||||
@ -62,44 +73,24 @@ namespace UnityExplorer.UI.Widgets
|
||||
GetRootEntriesMethod = getRootEntriesMethod;
|
||||
}
|
||||
|
||||
public void OnCellBorrowed(TransformCell cell)
|
||||
{
|
||||
cell.OnExpandToggled += OnCellExpandToggled;
|
||||
cell.OnGameObjectClicked += OnGameObjectClicked;
|
||||
cell.OnEnableToggled += OnCellEnableToggled;
|
||||
}
|
||||
|
||||
private void OnGameObjectClicked(GameObject obj)
|
||||
{
|
||||
if (OnClickOverrideHandler != null)
|
||||
OnClickOverrideHandler.Invoke(obj);
|
||||
else
|
||||
InspectorManager.Inspect(obj);
|
||||
}
|
||||
|
||||
public void OnCellExpandToggled(CachedTransform cache)
|
||||
{
|
||||
var instanceID = cache.InstanceID;
|
||||
if (expandedInstanceIDs.Contains(instanceID))
|
||||
expandedInstanceIDs.Remove(instanceID);
|
||||
else
|
||||
expandedInstanceIDs.Add(instanceID);
|
||||
|
||||
RefreshData(true);
|
||||
}
|
||||
|
||||
public void OnCellEnableToggled(CachedTransform cache)
|
||||
{
|
||||
cache.Value.gameObject.SetActive(!cache.Value.gameObject.activeSelf);
|
||||
|
||||
RefreshData(true);
|
||||
}
|
||||
// Initialize and reset
|
||||
|
||||
// Must be called externally from owner of this TransformTree
|
||||
public void Init()
|
||||
{
|
||||
ScrollPool.Initialize(this);
|
||||
}
|
||||
|
||||
// Called to completely reset the tree, ie. switching inspected GameObject
|
||||
public void Rebuild()
|
||||
{
|
||||
autoExpandedIDs.Clear();
|
||||
expandedInstanceIDs.Clear();
|
||||
|
||||
RefreshData(true, true, true, false);
|
||||
}
|
||||
|
||||
// Called to completely wipe our data (ie, GameObject inspector returning to pool)
|
||||
public void Clear()
|
||||
{
|
||||
this.cachedTransforms.Clear();
|
||||
@ -107,14 +98,21 @@ namespace UnityExplorer.UI.Widgets
|
||||
autoExpandedIDs.Clear();
|
||||
expandedInstanceIDs.Clear();
|
||||
this.ScrollPool.Refresh(true, true);
|
||||
if (refreshCoroutine != null)
|
||||
{
|
||||
RuntimeHelper.StopCoroutine(refreshCoroutine);
|
||||
refreshCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCellExpanded(int instanceID)
|
||||
// Checks if the given Instance ID is expanded or not
|
||||
public bool IsTransformExpanded(int instanceID)
|
||||
{
|
||||
return Filtering ? autoExpandedIDs.Contains(instanceID)
|
||||
: expandedInstanceIDs.Contains(instanceID);
|
||||
}
|
||||
|
||||
// Jumps to a specific Transform in the tree and highlights it.
|
||||
public void JumpAndExpandToTransform(Transform transform)
|
||||
{
|
||||
// make sure all parents of the object are expanded
|
||||
@ -128,8 +126,9 @@ namespace UnityExplorer.UI.Widgets
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
// Refresh cached transforms (no UI rebuild yet)
|
||||
RefreshData(false);
|
||||
// Refresh cached transforms (no UI rebuild yet).
|
||||
// Stop existing coroutine and do it oneshot.
|
||||
RefreshData(false, false, true, true);
|
||||
|
||||
int transformID = transform.GetInstanceID();
|
||||
|
||||
@ -162,62 +161,88 @@ namespace UnityExplorer.UI.Widgets
|
||||
button.OnDeselect(null);
|
||||
}
|
||||
|
||||
public void Rebuild()
|
||||
// Perform a Traverse and optionally refresh the ScrollPool as well.
|
||||
// If oneShot, then this happens instantly with no yield.
|
||||
public void RefreshData(bool andRefreshUI, bool jumpToTop, bool stopExistingCoroutine, bool oneShot)
|
||||
{
|
||||
autoExpandedIDs.Clear();
|
||||
expandedInstanceIDs.Clear();
|
||||
if (refreshCoroutine != null)
|
||||
{
|
||||
if (stopExistingCoroutine)
|
||||
{
|
||||
RuntimeHelper.StopCoroutine(refreshCoroutine);
|
||||
refreshCoroutine = null;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshData(true, true);
|
||||
}
|
||||
|
||||
public void RefreshData(bool andReload = false, bool jumpToTop = false)
|
||||
{
|
||||
visited.Clear();
|
||||
displayIndex = 0;
|
||||
needRefresh = false;
|
||||
needRefreshUI = false;
|
||||
traversedThisFrame.Reset();
|
||||
traversedThisFrame.Start();
|
||||
|
||||
var rootObjects = GetRootEntriesMethod.Invoke();
|
||||
IEnumerable<GameObject> rootObjects = GetRootEntriesMethod.Invoke();
|
||||
|
||||
//int displayIndex = 0;
|
||||
foreach (var obj in rootObjects)
|
||||
if (obj) Traverse(obj.transform);
|
||||
refreshCoroutine = RuntimeHelper.StartCoroutine(RefreshCoroutine(rootObjects, andRefreshUI, jumpToTop, oneShot));
|
||||
}
|
||||
|
||||
// Coroutine for batched updates, max 2000 gameobjects per frame so FPS doesn't get tanked when there is like 100k gameobjects.
|
||||
// if "oneShot", then this will NOT be batched (if we need an immediate full update).
|
||||
IEnumerator RefreshCoroutine(IEnumerable<GameObject> rootObjects, bool andRefreshUI, bool jumpToTop, bool oneShot)
|
||||
{
|
||||
foreach (var gameObj in rootObjects)
|
||||
{
|
||||
if (gameObj)
|
||||
{
|
||||
var enumerator = Traverse(gameObj.transform, null, 0, oneShot);
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (!oneShot)
|
||||
yield return enumerator.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prune displayed transforms that we didnt visit in that traverse
|
||||
for (int i = cachedTransforms.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var obj = (CachedTransform)cachedTransforms[i];
|
||||
if (!visited.Contains(obj.InstanceID))
|
||||
var cached = (CachedTransform)cachedTransforms[i];
|
||||
if (!visited.Contains(cached.InstanceID))
|
||||
{
|
||||
cachedTransforms.Remove(obj.InstanceID);
|
||||
needRefresh = true;
|
||||
cachedTransforms.RemoveAt(i);
|
||||
needRefreshUI = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!needRefresh)
|
||||
return;
|
||||
if (andRefreshUI && needRefreshUI)
|
||||
ScrollPool.Refresh(true, jumpToTop);
|
||||
|
||||
//displayedObjects.Clear();
|
||||
prevDisplayIndex = displayIndex;
|
||||
refreshCoroutine = null;
|
||||
}
|
||||
|
||||
if (andReload)
|
||||
{
|
||||
if (!jumpToTop)
|
||||
ScrollPool.Refresh(true);
|
||||
else
|
||||
ScrollPool.Refresh(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void Traverse(Transform transform, CachedTransform parent = null, int depth = 0)
|
||||
// Recursive method to check a Transform and its children (if expanded).
|
||||
// Parent and depth can be null/default.
|
||||
private IEnumerator Traverse(Transform transform, CachedTransform parent, int depth, bool oneShot)
|
||||
{
|
||||
// Let's only tank 2ms of each frame (60->53fps)
|
||||
if (traversedThisFrame.ElapsedMilliseconds > 2)
|
||||
{
|
||||
yield return null;
|
||||
traversedThisFrame.Reset();
|
||||
traversedThisFrame.Start();
|
||||
}
|
||||
|
||||
int instanceID = transform.GetInstanceID();
|
||||
|
||||
if (visited.Contains(instanceID))
|
||||
return;
|
||||
yield break;
|
||||
|
||||
if (Filtering)
|
||||
{
|
||||
if (!FilterHierarchy(transform))
|
||||
return;
|
||||
yield break;
|
||||
|
||||
visited.Add(instanceID);
|
||||
|
||||
@ -231,12 +256,25 @@ namespace UnityExplorer.UI.Widgets
|
||||
if (cachedTransforms.Contains(instanceID))
|
||||
{
|
||||
cached = (CachedTransform)cachedTransforms[(object)instanceID];
|
||||
int prevSiblingIdx = cached.SiblingIndex;
|
||||
if (cached.Update(transform, depth))
|
||||
needRefresh = true;
|
||||
{
|
||||
needRefreshUI = true;
|
||||
|
||||
// If the sibling index changed, we need to shuffle it in our cached transforms list.
|
||||
if (prevSiblingIdx != cached.SiblingIndex)
|
||||
{
|
||||
cachedTransforms.Remove(instanceID);
|
||||
if (cachedTransforms.Count <= displayIndex)
|
||||
cachedTransforms.Add(instanceID, cached);
|
||||
else
|
||||
cachedTransforms.Insert(displayIndex, instanceID, cached);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needRefresh = true;
|
||||
needRefreshUI = true;
|
||||
cached = new CachedTransform(this, transform, depth, parent);
|
||||
if (cachedTransforms.Count <= displayIndex)
|
||||
cachedTransforms.Add(instanceID, cached);
|
||||
@ -246,10 +284,17 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
displayIndex++;
|
||||
|
||||
if (IsCellExpanded(instanceID) && cached.Value.childCount > 0)
|
||||
if (IsTransformExpanded(instanceID) && cached.Value.childCount > 0)
|
||||
{
|
||||
for (int i = 0; i < transform.childCount; i++)
|
||||
Traverse(transform.GetChild(i), cached, depth + 1);
|
||||
{
|
||||
var enumerator = Traverse(transform.GetChild(i), cached, depth + 1, oneShot);
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (!oneShot)
|
||||
yield return enumerator.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,13 +321,44 @@ namespace UnityExplorer.UI.Widgets
|
||||
if (Filtering)
|
||||
{
|
||||
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
|
||||
{
|
||||
cell.NameButton.ButtonText.color = Color.green;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
cell.Disable();
|
||||
}
|
||||
|
||||
public void OnCellBorrowed(TransformCell cell)
|
||||
{
|
||||
cell.OnExpandToggled += OnCellExpandToggled;
|
||||
cell.OnGameObjectClicked += OnGameObjectClicked;
|
||||
cell.OnEnableToggled += OnCellEnableToggled;
|
||||
}
|
||||
|
||||
private void OnGameObjectClicked(GameObject obj)
|
||||
{
|
||||
if (OnClickOverrideHandler != null)
|
||||
OnClickOverrideHandler.Invoke(obj);
|
||||
else
|
||||
InspectorManager.Inspect(obj);
|
||||
}
|
||||
|
||||
public void OnCellExpandToggled(CachedTransform cache)
|
||||
{
|
||||
var instanceID = cache.InstanceID;
|
||||
if (expandedInstanceIDs.Contains(instanceID))
|
||||
expandedInstanceIDs.Remove(instanceID);
|
||||
else
|
||||
expandedInstanceIDs.Add(instanceID);
|
||||
|
||||
RefreshData(true, false, true, true);
|
||||
}
|
||||
|
||||
public void OnCellEnableToggled(CachedTransform cache)
|
||||
{
|
||||
cache.Value.gameObject.SetActive(!cache.Value.gameObject.activeSelf);
|
||||
|
||||
RefreshData(true, false, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,13 +175,13 @@
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UniverseLib.Mono">
|
||||
<HintPath>packages\UniverseLib.1.2.2\lib\net35\UniverseLib.Mono.dll</HintPath>
|
||||
<HintPath>packages\UniverseLib.1.2.16\lib\net35\UniverseLib.Mono.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<!-- Il2Cpp refs -->
|
||||
<ItemGroup Condition="'$(IsCpp)'=='true'">
|
||||
<Reference Include="UniverseLib.IL2CPP">
|
||||
<HintPath>packages\UniverseLib.1.2.2\lib\net472\UniverseLib.IL2CPP.dll</HintPath>
|
||||
<HintPath>packages\UniverseLib.1.2.16\lib\net472\UniverseLib.IL2CPP.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnhollowerBaseLib, Version=0.4.22.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Il2CppAssemblyUnhollower.BaseLib.0.4.22\lib\net472\UnhollowerBaseLib.dll</HintPath>
|
||||
@ -225,6 +225,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CacheObject\CacheConstructor.cs" />
|
||||
<Compile Include="Hooks\HookCell.cs" />
|
||||
<Compile Include="Hooks\HookInstance.cs" />
|
||||
<Compile Include="Hooks\HookManager.cs" />
|
||||
@ -246,7 +247,7 @@
|
||||
<Compile Include="Inspectors\GameObjectWidgets\ComponentCell.cs" />
|
||||
<Compile Include="Inspectors\GameObjectWidgets\ComponentList.cs" />
|
||||
<Compile Include="Inspectors\GameObjectWidgets\GameObjectControls.cs" />
|
||||
<Compile Include="Inspectors\InspectUnderMouse.cs" />
|
||||
<Compile Include="Inspectors\MouseInspector.cs" />
|
||||
<Compile Include="CSConsole\ConsoleController.cs" />
|
||||
<Compile Include="CacheObject\CacheField.cs" />
|
||||
<Compile Include="CacheObject\CacheKeyValuePair.cs" />
|
||||
@ -259,6 +260,7 @@
|
||||
<Compile Include="CacheObject\Views\CacheListEntryCell.cs" />
|
||||
<Compile Include="CacheObject\Views\CacheMemberCell.cs" />
|
||||
<Compile Include="CacheObject\Views\CacheObjectCell.cs" />
|
||||
<Compile Include="Runtime\UnityCrashPrevention.cs" />
|
||||
<Compile Include="UI\DisplayManager.cs" />
|
||||
<Compile Include="UI\Notification.cs" />
|
||||
<Compile Include="UI\Panels\ClipboardPanel.cs" />
|
||||
@ -311,7 +313,7 @@
|
||||
<Compile Include="UI\Panels\ObjectExplorerPanel.cs" />
|
||||
<Compile Include="UI\UIManager.cs" />
|
||||
<Compile Include="UI\Panels\PanelDragger.cs" />
|
||||
<Compile Include="UI\Widgets\AutoComplete\AutoCompleteModal.cs" />
|
||||
<Compile Include="UI\Panels\AutoCompleteModal.cs" />
|
||||
<Compile Include="UI\Widgets\AutoComplete\TypeCompleter.cs" />
|
||||
<Compile Include="ObjectExplorer\ObjectSearch.cs" />
|
||||
<Compile Include="ObjectExplorer\SceneExplorer.cs" />
|
||||
@ -324,6 +326,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ILRepack.targets" />
|
||||
<None Include="nuget.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
19
src/nuget.config
Normal file
19
src/nuget.config
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<config>
|
||||
<add key="dependencyVersion" value="Lowest" />
|
||||
</config>
|
||||
|
||||
<packageRestore>
|
||||
<!-- Allow NuGet to download missing packages -->
|
||||
<add key="enabled" value="True" />
|
||||
|
||||
<!-- Automatically check for missing packages during build in Visual Studio -->
|
||||
<add key="automatic" value="True" />
|
||||
</packageRestore>
|
||||
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
<add key="BepInEx" value="https://nuget.bepinex.dev/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
@ -6,6 +6,6 @@
|
||||
<package id="ILRepack.Lib.MSBuild.Task" version="2.0.18.2" targetFramework="net35" />
|
||||
<package id="Mono.Cecil" version="0.10.4" targetFramework="net35" />
|
||||
<package id="Samboy063.Tomlet" version="3.1.3" targetFramework="net472" />
|
||||
<package id="UniverseLib" version="1.2.2" targetFramework="net35" />
|
||||
<package id="UniverseLib" version="1.2.16" targetFramework="net35" />
|
||||
<package id="UniverseLib.Analyzers" version="1.0.3" targetFramework="net35" developmentDependency="true" />
|
||||
</packages>
|
Reference in New Issue
Block a user