mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-01 11:12:49 +08:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
c38155ab04 | |||
97dbecaa2a | |||
e77e4cce07 | |||
dcf0bdce48 | |||
2a3df5de9d |
@ -25,8 +25,8 @@
|
||||
|
||||
| Mod Loader | IL2CPP | Mono |
|
||||
| ----------- | ------ | ---- |
|
||||
| [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) | ✔️ [link](https://github.com/sinai-dev/Explorer/releases/latest/download/Explorer.MelonLoader.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/Explorer/releases/latest/download/Explorer.MelonLoader.Mono.zip) |
|
||||
| [BepInEx](https://github.com/BepInEx/BepInEx) | ✔️ [link](https://github.com/sinai-dev/Explorer/releases/latest/download/Explorer.BepInEx.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/Explorer/releases/latest/download/Explorer.BepInEx.Mono.zip) |
|
||||
| [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Mono.zip) |
|
||||
| [BepInEx](https://github.com/BepInEx/BepInEx) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Mono.zip) |
|
||||
|
||||
<b>IL2CPP Issues:</b>
|
||||
* Some methods may still fail with a `MissingMethodException`, please let me know if you experience this (with full debug log please).
|
||||
|
@ -8,13 +8,14 @@ using UnityExplorer.Inspectors;
|
||||
using System.IO;
|
||||
using UnityExplorer.Unstrip;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityExplorer.Helpers;
|
||||
|
||||
namespace UnityExplorer
|
||||
{
|
||||
public class ExplorerCore
|
||||
{
|
||||
public const string NAME = "UnityExplorer";
|
||||
public const string VERSION = "3.0.1";
|
||||
public const string VERSION = "3.0.2.1";
|
||||
public const string AUTHOR = "Sinai";
|
||||
public const string GUID = "com.sinai.unityexplorer";
|
||||
public const string EXPLORER_FOLDER = @"Mods\UnityExplorer";
|
||||
@ -41,6 +42,10 @@ namespace UnityExplorer
|
||||
|
||||
Instance = this;
|
||||
|
||||
#if CPP
|
||||
ReflectionHelpers.TryLoadGameModules();
|
||||
#endif
|
||||
|
||||
if (!Directory.Exists(EXPLORER_FOLDER))
|
||||
Directory.CreateDirectory(EXPLORER_FOLDER);
|
||||
|
||||
|
@ -105,21 +105,19 @@ namespace UnityExplorer.Helpers
|
||||
return getType;
|
||||
}
|
||||
|
||||
private static readonly Dictionary<Type, IntPtr> ClassPointers = new Dictionary<Type, IntPtr>();
|
||||
private static readonly Dictionary<Type, IntPtr> CppClassPointers = new Dictionary<Type, IntPtr>();
|
||||
|
||||
public static object Il2CppCast(this object obj, Type castTo)
|
||||
{
|
||||
if (!(obj is Il2CppSystem.Object ilObj))
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (!Il2CppTypeNotNull(castTo, out IntPtr castToPtr))
|
||||
return obj;
|
||||
|
||||
IntPtr classPtr = il2cpp_object_get_class(ilObj.Pointer);
|
||||
IntPtr castFromPtr = il2cpp_object_get_class(ilObj.Pointer);
|
||||
|
||||
if (!il2cpp_class_is_assignable_from(castToPtr, classPtr))
|
||||
if (!il2cpp_class_is_assignable_from(castToPtr, castFromPtr))
|
||||
return obj;
|
||||
|
||||
if (RuntimeSpecificsStore.IsInjected(castToPtr))
|
||||
@ -128,24 +126,21 @@ namespace UnityExplorer.Helpers
|
||||
return Activator.CreateInstance(castTo, ilObj.Pointer);
|
||||
}
|
||||
|
||||
public static bool Il2CppTypeNotNull(Type type)
|
||||
{
|
||||
return Il2CppTypeNotNull(type, out _);
|
||||
}
|
||||
public static bool Il2CppTypeNotNull(Type type) => Il2CppTypeNotNull(type, out _);
|
||||
|
||||
public static bool Il2CppTypeNotNull(Type type, out IntPtr il2cppPtr)
|
||||
{
|
||||
if (!ClassPointers.ContainsKey(type))
|
||||
if (!CppClassPointers.ContainsKey(type))
|
||||
{
|
||||
il2cppPtr = (IntPtr)typeof(Il2CppClassPointerStore<>)
|
||||
.MakeGenericType(new Type[] { type })
|
||||
.GetField("NativeClassPtr", BF.Public | BF.Static)
|
||||
.GetValue(null);
|
||||
|
||||
ClassPointers.Add(type, il2cppPtr);
|
||||
CppClassPointers.Add(type, il2cppPtr);
|
||||
}
|
||||
else
|
||||
il2cppPtr = ClassPointers[type];
|
||||
il2cppPtr = CppClassPointers[type];
|
||||
|
||||
return il2cppPtr != IntPtr.Zero;
|
||||
}
|
||||
@ -181,31 +176,44 @@ namespace UnityExplorer.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
#if CPP
|
||||
internal static void TryLoadGameModules()
|
||||
{
|
||||
LoadModule("Assembly-CSharp");
|
||||
LoadModule("Assembly-CSharp-firstpass");
|
||||
}
|
||||
|
||||
public static bool LoadModule(string module)
|
||||
{
|
||||
#if CPP
|
||||
#if ML
|
||||
string path = $@"MelonLoader\Managed\{module}.dll";
|
||||
var path = $@"MelonLoader\Managed\{module}.dll";
|
||||
#else
|
||||
var path = $@"BepInEx\unhollowed\{module}.dll";
|
||||
#endif
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
|
||||
return LoadModuleInternal(path);
|
||||
}
|
||||
|
||||
internal static bool LoadModuleInternal(string fullPath)
|
||||
{
|
||||
if (!File.Exists(fullPath))
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Assembly.Load(File.ReadAllBytes(path));
|
||||
Assembly.Load(File.ReadAllBytes(fullPath));
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.Log(e.GetType() + ", " + e.Message);
|
||||
Console.WriteLine(e.GetType() + ", " + e.Message);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
public static bool LoadModule(string module) => true;
|
||||
#endif
|
||||
|
||||
public static bool IsEnumerable(Type t)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace UnityExplorer.Input
|
||||
{
|
||||
@ -11,5 +12,12 @@ namespace UnityExplorer.Input
|
||||
|
||||
bool GetMouseButtonDown(int btn);
|
||||
bool GetMouseButton(int btn);
|
||||
|
||||
BaseInputModule UIModule { get; }
|
||||
|
||||
PointerEventData InputPointerEvent { get; }
|
||||
|
||||
void AddUIInputModule();
|
||||
void ActivateModule();
|
||||
}
|
||||
}
|
||||
|
@ -2,34 +2,26 @@
|
||||
using UnityEngine;
|
||||
using UnityExplorer.Helpers;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using UnityEngine.EventSystems;
|
||||
#if CPP
|
||||
using UnhollowerBaseLib;
|
||||
#endif
|
||||
|
||||
namespace UnityExplorer.Input
|
||||
{
|
||||
public enum InputType
|
||||
{
|
||||
InputSystem,
|
||||
Legacy,
|
||||
None
|
||||
}
|
||||
|
||||
public static class InputManager
|
||||
{
|
||||
public static InputType CurrentType { get; private set; }
|
||||
|
||||
private static IHandleInput m_inputModule;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (InputSystem.TKeyboard != null || (ReflectionHelpers.LoadModule("Unity.InputSystem") && InputSystem.TKeyboard != null))
|
||||
{
|
||||
m_inputModule = new InputSystem();
|
||||
}
|
||||
else if (LegacyInput.TInput != null || (ReflectionHelpers.LoadModule("UnityEngine.InputLegacyModule") && LegacyInput.TInput != null))
|
||||
{
|
||||
m_inputModule = new LegacyInput();
|
||||
}
|
||||
|
||||
if (m_inputModule == null)
|
||||
{
|
||||
ExplorerCore.LogWarning("Could not find any Input module!");
|
||||
m_inputModule = new NoInput();
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector3 MousePosition => m_inputModule.MousePosition;
|
||||
|
||||
public static bool GetKeyDown(KeyCode key) => m_inputModule.GetKeyDown(key);
|
||||
@ -37,5 +29,37 @@ namespace UnityExplorer.Input
|
||||
|
||||
public static bool GetMouseButtonDown(int btn) => m_inputModule.GetMouseButtonDown(btn);
|
||||
public static bool GetMouseButton(int btn) => m_inputModule.GetMouseButton(btn);
|
||||
|
||||
public static BaseInputModule UIInput => m_inputModule.UIModule;
|
||||
public static PointerEventData InputPointerEvent => m_inputModule.InputPointerEvent;
|
||||
|
||||
public static void ActivateUIModule() => m_inputModule.ActivateModule();
|
||||
|
||||
public static void AddUIModule()
|
||||
{
|
||||
m_inputModule.AddUIInputModule();
|
||||
ActivateUIModule();
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (InputSystem.TKeyboard != null || (ReflectionHelpers.LoadModule("Unity.InputSystem") && InputSystem.TKeyboard != null))
|
||||
{
|
||||
m_inputModule = new InputSystem();
|
||||
CurrentType = InputType.InputSystem;
|
||||
}
|
||||
else if (LegacyInput.TInput != null || (ReflectionHelpers.LoadModule("UnityEngine.InputLegacyModule") && LegacyInput.TInput != null))
|
||||
{
|
||||
m_inputModule = new LegacyInput();
|
||||
CurrentType = InputType.Legacy;
|
||||
}
|
||||
|
||||
if (m_inputModule == null)
|
||||
{
|
||||
ExplorerCore.LogWarning("Could not find any Input module!");
|
||||
m_inputModule = new NoInput();
|
||||
CurrentType = InputType.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,9 @@
|
||||
using System.Reflection;
|
||||
using UnityExplorer.Helpers;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityExplorer.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityExplorer.Input
|
||||
{
|
||||
@ -64,24 +67,46 @@ namespace UnityExplorer.Input
|
||||
private static PropertyInfo m_positionProp;
|
||||
private static MethodInfo m_readVector2InputMethod;
|
||||
|
||||
public Vector2 MousePosition => (Vector2)m_readVector2InputMethod.Invoke(MousePositionInfo, new object[0]);
|
||||
|
||||
public bool GetKeyDown(KeyCode key)
|
||||
public Vector2 MousePosition
|
||||
{
|
||||
var parsedKey = Enum.Parse(TKey, key.ToString());
|
||||
var actualKey = m_kbIndexer.GetValue(CurrentKeyboard, new object[] { parsedKey });
|
||||
|
||||
return (bool)m_btnWasPressedProp.GetValue(actualKey, null);
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Vector2)m_readVector2InputMethod.Invoke(MousePositionInfo, new object[0]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Vector2.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetKey(KeyCode key)
|
||||
{
|
||||
var parsed = Enum.Parse(TKey, key.ToString());
|
||||
var actualKey = m_kbIndexer.GetValue(CurrentKeyboard, new object[] { parsed });
|
||||
internal static Dictionary<KeyCode, object> ActualKeyDict = new Dictionary<KeyCode, object>();
|
||||
|
||||
return (bool)m_btnIsPressedProp.GetValue(actualKey, null);
|
||||
internal object GetActualKey(KeyCode key)
|
||||
{
|
||||
if (!ActualKeyDict.ContainsKey(key))
|
||||
{
|
||||
var s = key.ToString();
|
||||
if (s.Contains("Control"))
|
||||
s = s.Replace("Control", "Ctrl");
|
||||
else if (s.Contains("Return"))
|
||||
s = "Enter";
|
||||
|
||||
var parsed = Enum.Parse(TKey, s);
|
||||
var actualKey = m_kbIndexer.GetValue(CurrentKeyboard, new object[] { parsed });
|
||||
|
||||
ActualKeyDict.Add(key, actualKey);
|
||||
}
|
||||
|
||||
return ActualKeyDict[key];
|
||||
}
|
||||
|
||||
public bool GetKeyDown(KeyCode key) => (bool)m_btnWasPressedProp.GetValue(GetActualKey(key), null);
|
||||
|
||||
public bool GetKey(KeyCode key) => (bool)m_btnIsPressedProp.GetValue(GetActualKey(key), null);
|
||||
|
||||
public bool GetMouseButtonDown(int btn)
|
||||
{
|
||||
switch (btn)
|
||||
@ -103,5 +128,44 @@ namespace UnityExplorer.Input
|
||||
default: throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
// UI Input
|
||||
|
||||
//public Type TInputSystemUIInputModule
|
||||
// => m_tUIInputModule
|
||||
// ?? (m_tUIInputModule = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.UI.InputSystemUIInputModule"));
|
||||
//internal Type m_tUIInputModule;
|
||||
|
||||
public BaseInputModule UIModule => null; // m_newInputModule;
|
||||
//internal BaseInputModule m_newInputModule;
|
||||
|
||||
public PointerEventData InputPointerEvent => null;
|
||||
|
||||
public void AddUIInputModule()
|
||||
{
|
||||
// if (TInputSystemUIInputModule != null)
|
||||
// {
|
||||
//#if CPP
|
||||
// // m_newInputModule = UIManager.CanvasRoot.AddComponent(Il2CppType.From(TInputSystemUIInputModule)).TryCast<BaseInputModule>();
|
||||
//#else
|
||||
// m_newInputModule = (BaseInputModule)UIManager.CanvasRoot.AddComponent(TInputSystemUIInputModule);
|
||||
//#endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ExplorerCore.LogWarning("New input system: Could not find type by name 'UnityEngine.InputSystem.UI.InputSystemUIInputModule'");
|
||||
// }
|
||||
}
|
||||
|
||||
public void ActivateModule()
|
||||
{
|
||||
//#if CPP
|
||||
// // m_newInputModule.ActivateModule();
|
||||
//#else
|
||||
// m_newInputModule.ActivateModule();
|
||||
//#endif
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
using System.Reflection;
|
||||
using UnityExplorer.Helpers;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityExplorer.UI;
|
||||
|
||||
namespace UnityExplorer.Input
|
||||
{
|
||||
@ -36,5 +38,27 @@ namespace UnityExplorer.Input
|
||||
public bool GetMouseButton(int btn) => (bool)m_getMouseButtonMethod.Invoke(null, new object[] { btn });
|
||||
|
||||
public bool GetMouseButtonDown(int btn) => (bool)m_getMouseButtonDownMethod.Invoke(null, new object[] { btn });
|
||||
|
||||
// UI Input module
|
||||
|
||||
public BaseInputModule UIModule => m_inputModule;
|
||||
internal StandaloneInputModule m_inputModule;
|
||||
|
||||
public PointerEventData InputPointerEvent =>
|
||||
#if CPP
|
||||
m_inputModule.m_InputPointerEvent;
|
||||
#else
|
||||
null;
|
||||
#endif
|
||||
|
||||
public void AddUIInputModule()
|
||||
{
|
||||
m_inputModule = UIManager.CanvasRoot.gameObject.AddComponent<StandaloneInputModule>();
|
||||
}
|
||||
|
||||
public void ActivateModule()
|
||||
{
|
||||
m_inputModule.ActivateModule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace UnityExplorer.Input
|
||||
{
|
||||
@ -13,5 +14,10 @@ namespace UnityExplorer.Input
|
||||
|
||||
public bool GetMouseButton(int btn) => false;
|
||||
public bool GetMouseButtonDown(int btn) => false;
|
||||
|
||||
public BaseInputModule UIModule => null;
|
||||
public PointerEventData InputPointerEvent => null;
|
||||
public void ActivateModule() { }
|
||||
public void AddUIInputModule() { }
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.Reflection;
|
||||
using UnityExplorer.UI;
|
||||
using UnityExplorer.Helpers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.Inspectors.Reflection
|
||||
{
|
||||
@ -14,7 +15,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
|
||||
public override Type FallbackType => (MemInfo as FieldInfo).FieldType;
|
||||
|
||||
public CacheField(FieldInfo fieldInfo, object declaringInstance) : base(fieldInfo, declaringInstance)
|
||||
public CacheField(FieldInfo fieldInfo, object declaringInstance, GameObject parent) : base(fieldInfo, declaringInstance, parent)
|
||||
{
|
||||
CreateIValue(null, fieldInfo.FieldType);
|
||||
}
|
||||
|
@ -43,11 +43,12 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
public string RichTextName => m_richTextName ?? GetRichTextName();
|
||||
private string m_richTextName;
|
||||
|
||||
public CacheMember(MemberInfo memberInfo, object declaringInstance)
|
||||
public CacheMember(MemberInfo memberInfo, object declaringInstance, GameObject parentContent)
|
||||
{
|
||||
MemInfo = memberInfo;
|
||||
DeclaringType = memberInfo.DeclaringType;
|
||||
DeclaringInstance = declaringInstance;
|
||||
this.m_parentContent = parentContent;
|
||||
#if CPP
|
||||
if (DeclaringInstance != null)
|
||||
DeclaringInstance = DeclaringInstance.Il2CppCast(DeclaringType);
|
||||
|
@ -26,7 +26,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
|
||||
public string[] m_genericArgInput = new string[0];
|
||||
|
||||
public CacheMethod(MethodInfo methodInfo, object declaringInstance) : base(methodInfo, declaringInstance)
|
||||
public CacheMethod(MethodInfo methodInfo, object declaringInstance, GameObject parent) : base(methodInfo, declaringInstance, parent)
|
||||
{
|
||||
GenericArgs = methodInfo.GetGenericArguments();
|
||||
|
||||
|
@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.Reflection;
|
||||
using UnityExplorer.UI;
|
||||
using UnityExplorer.Helpers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.Inspectors.Reflection
|
||||
{
|
||||
@ -14,7 +15,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
|
||||
public override bool IsStatic => (MemInfo as PropertyInfo).GetAccessors(true)[0].IsStatic;
|
||||
|
||||
public CacheProperty(PropertyInfo propertyInfo, object declaringInstance) : base(propertyInfo, declaringInstance)
|
||||
public CacheProperty(PropertyInfo propertyInfo, object declaringInstance, GameObject parent) : base(propertyInfo, declaringInstance, parent)
|
||||
{
|
||||
this.m_arguments = propertyInfo.GetIndexParameters();
|
||||
this.m_argumentInput = new string[m_arguments.Length];
|
||||
|
@ -45,19 +45,95 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
|
||||
public void ConstructInstanceHelpers()
|
||||
{
|
||||
if (!typeof(Component).IsAssignableFrom(m_targetType) && !typeof(UnityEngine.Object).IsAssignableFrom(m_targetType))
|
||||
return;
|
||||
|
||||
var rowObj = UIFactory.CreateHorizontalGroup(Content, new Color(0.1f, 0.1f, 0.1f));
|
||||
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
||||
rowGroup.childForceExpandWidth = true;
|
||||
rowGroup.childControlWidth = true;
|
||||
rowGroup.spacing = 5;
|
||||
rowGroup.padding.top = 2;
|
||||
rowGroup.padding.bottom = 2;
|
||||
rowGroup.padding.right = 2;
|
||||
rowGroup.padding.left = 2;
|
||||
var rowLayout = rowObj.AddComponent<LayoutElement>();
|
||||
rowLayout.minHeight = 25;
|
||||
rowLayout.flexibleWidth = 5000;
|
||||
|
||||
if (typeof(Component).IsAssignableFrom(m_targetType))
|
||||
{
|
||||
ConstructCompHelper(rowObj);
|
||||
}
|
||||
|
||||
ConstructUObjHelper(rowObj);
|
||||
|
||||
// WIP
|
||||
|
||||
//if (m_targetType == typeof(Texture2D))
|
||||
// ConstructTextureHelper();
|
||||
}
|
||||
|
||||
// todo other helpers
|
||||
internal void ConstructCompHelper(GameObject rowObj)
|
||||
{
|
||||
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
||||
var labelLayout = labelObj.AddComponent<LayoutElement>();
|
||||
labelLayout.minWidth = 90;
|
||||
labelLayout.minHeight = 25;
|
||||
labelLayout.flexibleWidth = 0;
|
||||
var labelText = labelObj.GetComponent<Text>();
|
||||
labelText.text = "GameObject:";
|
||||
|
||||
//if (typeof(Component).IsAssignableFrom(m_targetType))
|
||||
//{
|
||||
//}
|
||||
//else if (typeof(UnityEngine.Object).IsAssignableFrom(m_targetType))
|
||||
//{
|
||||
//}
|
||||
#if MONO
|
||||
var comp = Target as Component;
|
||||
#else
|
||||
var comp = (Target as Il2CppSystem.Object).TryCast<Component>();
|
||||
#endif
|
||||
|
||||
var goBtnObj = UIFactory.CreateButton(rowObj, new Color(0.2f, 0.5f, 0.2f));
|
||||
var goBtnLayout = goBtnObj.AddComponent<LayoutElement>();
|
||||
goBtnLayout.minHeight = 25;
|
||||
goBtnLayout.minWidth = 200;
|
||||
goBtnLayout.flexibleWidth = 0;
|
||||
var text = goBtnObj.GetComponentInChildren<Text>();
|
||||
text.text = comp.name;
|
||||
var btn = goBtnObj.GetComponent<Button>();
|
||||
btn.onClick.AddListener(() => { InspectorManager.Instance.Inspect(comp.gameObject); });
|
||||
}
|
||||
|
||||
internal void ConstructUObjHelper(GameObject rowObj)
|
||||
{
|
||||
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
||||
var labelLayout = labelObj.AddComponent<LayoutElement>();
|
||||
labelLayout.minWidth = 60;
|
||||
labelLayout.minHeight = 25;
|
||||
labelLayout.flexibleWidth = 0;
|
||||
var labelText = labelObj.GetComponent<Text>();
|
||||
labelText.text = "Name:";
|
||||
|
||||
#if MONO
|
||||
var uObj = Target as UnityEngine.Object;
|
||||
#else
|
||||
var uObj = (Target as Il2CppSystem.Object).TryCast<UnityEngine.Object>();
|
||||
#endif
|
||||
|
||||
var inputObj = UIFactory.CreateInputField(rowObj, 14, 3, 1);
|
||||
var inputLayout = inputObj.AddComponent<LayoutElement>();
|
||||
inputLayout.minHeight = 25;
|
||||
inputLayout.flexibleWidth = 2000;
|
||||
var inputField = inputObj.GetComponent<InputField>();
|
||||
inputField.readOnly = true;
|
||||
inputField.text = uObj.name;
|
||||
|
||||
//var goBtnObj = UIFactory.CreateButton(rowObj, new Color(0.2f, 0.5f, 0.2f));
|
||||
//var goBtnLayout = goBtnObj.AddComponent<LayoutElement>();
|
||||
//goBtnLayout.minHeight = 25;
|
||||
//goBtnLayout.minWidth = 200;
|
||||
//goBtnLayout.flexibleWidth = 0;
|
||||
//var text = goBtnObj.GetComponentInChildren<Text>();
|
||||
//text.text = comp.name;
|
||||
//var btn = goBtnObj.GetComponent<Button>();
|
||||
//btn.onClick.AddListener(() => { InspectorManager.Instance.Inspect(comp.gameObject); });
|
||||
}
|
||||
|
||||
//internal bool showingTextureHelper;
|
||||
|
@ -34,7 +34,7 @@ namespace UnityExplorer.Inspectors
|
||||
}
|
||||
|
||||
// Blacklists
|
||||
private static readonly HashSet<string> s_typeAndMemberBlacklist = new HashSet<string>
|
||||
private static readonly HashSet<string> bl_typeAndMember = new HashSet<string>
|
||||
{
|
||||
#if CPP
|
||||
// these cause a crash in IL2CPP
|
||||
@ -45,14 +45,14 @@ namespace UnityExplorer.Inspectors
|
||||
"Texture2D.SetPixelDataImpl",
|
||||
#endif
|
||||
};
|
||||
private static readonly HashSet<string> s_methodStartsWithBlacklist = new HashSet<string>
|
||||
private static readonly HashSet<string> bl_memberNameStartsWith = new HashSet<string>
|
||||
{
|
||||
// these are redundant
|
||||
"get_",
|
||||
"set_",
|
||||
};
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region INSTANCE
|
||||
|
||||
@ -132,24 +132,99 @@ namespace UnityExplorer.Inspectors
|
||||
RefreshDisplay();
|
||||
}
|
||||
|
||||
private void OnMemberFilterClicked(MemberTypes type, Button button)
|
||||
internal bool IsBlacklisted(string sig) => bl_typeAndMember.Any(it => sig.Contains(it));
|
||||
internal bool IsBlacklisted(MethodInfo method) => bl_memberNameStartsWith.Any(it => method.Name.StartsWith(it));
|
||||
|
||||
internal string GetSig(MemberInfo member) => $"{member.DeclaringType.Name}.{member.Name}";
|
||||
internal string AppendArgsToSig(ParameterInfo[] args)
|
||||
{
|
||||
if (m_lastActiveMemButton)
|
||||
string ret = " (";
|
||||
foreach (var param in args)
|
||||
ret += $"{param.ParameterType.Name} {param.Name}, ";
|
||||
ret += ")";
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void CacheMembers(Type type)
|
||||
{
|
||||
var list = new List<CacheMember>();
|
||||
var cachedSigs = new HashSet<string>();
|
||||
|
||||
var types = ReflectionHelpers.GetAllBaseTypes(type);
|
||||
|
||||
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
|
||||
if (this is InstanceInspector)
|
||||
flags |= BindingFlags.Instance;
|
||||
|
||||
foreach (var declaringType in types)
|
||||
{
|
||||
var lastColors = m_lastActiveMemButton.colors;
|
||||
lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
|
||||
m_lastActiveMemButton.colors = lastColors;
|
||||
var target = Target;
|
||||
#if CPP
|
||||
target = target.Il2CppCast(declaringType);
|
||||
#endif
|
||||
IEnumerable<MemberInfo> infos = declaringType.GetMethods(flags);
|
||||
infos = infos.Concat(declaringType.GetProperties(flags));
|
||||
infos = infos.Concat(declaringType.GetFields(flags));
|
||||
|
||||
foreach (var member in infos)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ExplorerCore.Log($"Trying to cache member {sig}...");
|
||||
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
|
||||
|
||||
var sig = GetSig(member);
|
||||
|
||||
var mi = member as MethodInfo;
|
||||
var pi = member as PropertyInfo;
|
||||
var fi = member as FieldInfo;
|
||||
|
||||
if (IsBlacklisted(sig) || (mi != null && IsBlacklisted(mi)))
|
||||
continue;
|
||||
|
||||
var args = mi?.GetParameters() ?? pi?.GetIndexParameters();
|
||||
if (args != null)
|
||||
{
|
||||
if (!CacheMember.CanProcessArgs(args))
|
||||
continue;
|
||||
|
||||
sig += AppendArgsToSig(args);
|
||||
}
|
||||
|
||||
if (cachedSigs.Contains(sig))
|
||||
continue;
|
||||
|
||||
cachedSigs.Add(sig);
|
||||
|
||||
if (mi != null)
|
||||
list.Add(new CacheMethod(mi, target, m_scrollContent));
|
||||
else if (pi != null)
|
||||
list.Add(new CacheProperty(pi, target, m_scrollContent));
|
||||
else
|
||||
list.Add(new CacheField(fi, target, m_scrollContent));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Exception caching member {member.DeclaringType.FullName}.{member.Name}!");
|
||||
ExplorerCore.Log(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_memberFilter = type;
|
||||
m_lastActiveMemButton = button;
|
||||
var typeList = types.ToList();
|
||||
|
||||
var colors = m_lastActiveMemButton.colors;
|
||||
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
|
||||
m_lastActiveMemButton.colors = colors;
|
||||
var sorted = new List<CacheMember>();
|
||||
sorted.AddRange(list.Where(it => it is CacheMethod)
|
||||
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
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));
|
||||
|
||||
FilterMembers(null, true);
|
||||
m_sliderScroller.m_slider.value = 1f;
|
||||
m_allMembers = sorted.ToArray();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
@ -178,6 +253,26 @@ namespace UnityExplorer.Inspectors
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMemberFilterClicked(MemberTypes type, Button button)
|
||||
{
|
||||
if (m_lastActiveMemButton)
|
||||
{
|
||||
var lastColors = m_lastActiveMemButton.colors;
|
||||
lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
|
||||
m_lastActiveMemButton.colors = lastColors;
|
||||
}
|
||||
|
||||
m_memberFilter = type;
|
||||
m_lastActiveMemButton = button;
|
||||
|
||||
var colors = m_lastActiveMemButton.colors;
|
||||
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
|
||||
m_lastActiveMemButton.colors = colors;
|
||||
|
||||
FilterMembers(null, true);
|
||||
m_sliderScroller.m_slider.value = 1f;
|
||||
}
|
||||
|
||||
public void FilterMembers(string nameFilter = null, bool force = false)
|
||||
{
|
||||
int lastCount = m_membersFiltered.Count;
|
||||
@ -200,7 +295,7 @@ namespace UnityExplorer.Inspectors
|
||||
}
|
||||
|
||||
// name filter
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !mem.NameForFiltering.Contains(nameFilter))
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !mem.NameForFiltering.Contains(nameFilter))
|
||||
continue;
|
||||
|
||||
m_membersFiltered.Add(mem);
|
||||
@ -266,137 +361,6 @@ namespace UnityExplorer.Inspectors
|
||||
}
|
||||
}
|
||||
|
||||
public void CacheMembers(Type type)
|
||||
{
|
||||
var list = new List<CacheMember>();
|
||||
var cachedSigs = new HashSet<string>();
|
||||
|
||||
var types = ReflectionHelpers.GetAllBaseTypes(type);
|
||||
|
||||
foreach (var declaringType in types)
|
||||
{
|
||||
MemberInfo[] infos;
|
||||
try
|
||||
{
|
||||
infos = declaringType.GetMembers(ReflectionHelpers.CommonFlags);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ExplorerCore.Log($"Exception getting members for type: {declaringType.FullName}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var target = Target;
|
||||
#if CPP
|
||||
try
|
||||
{
|
||||
target = target.Il2CppCast(declaringType);
|
||||
}
|
||||
catch //(Exception e)
|
||||
{
|
||||
//ExplorerCore.LogWarning("Excepting casting " + target.GetType().FullName + " to " + declaringType.FullName);
|
||||
}
|
||||
#endif
|
||||
|
||||
foreach (var member in infos)
|
||||
{
|
||||
try
|
||||
{
|
||||
// make sure member type is Field, Method or Property (4 / 8 / 16)
|
||||
int m = (int)member.MemberType;
|
||||
if (m < 4 || m > 16)
|
||||
continue;
|
||||
|
||||
//ExplorerCore.Log($"Trying to cache member {sig}...");
|
||||
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
|
||||
|
||||
var pi = member as PropertyInfo;
|
||||
var mi = member as MethodInfo;
|
||||
|
||||
if (this is StaticInspector)
|
||||
{
|
||||
if (member is FieldInfo fi && !fi.IsStatic) continue;
|
||||
else if (pi != null && !pi.GetAccessors(true)[0].IsStatic) continue;
|
||||
else if (mi != null && !mi.IsStatic) continue;
|
||||
}
|
||||
|
||||
// check blacklisted members
|
||||
var sig = $"{member.DeclaringType.Name}.{member.Name}";
|
||||
|
||||
if (s_typeAndMemberBlacklist.Any(it => sig.Contains(it)))
|
||||
continue;
|
||||
|
||||
if (s_methodStartsWithBlacklist.Any(it => member.Name.StartsWith(it)))
|
||||
continue;
|
||||
|
||||
if (mi != null)
|
||||
AppendParams(mi.GetParameters());
|
||||
else if (pi != null)
|
||||
AppendParams(pi.GetIndexParameters());
|
||||
|
||||
void AppendParams(ParameterInfo[] _args)
|
||||
{
|
||||
sig += " (";
|
||||
foreach (var param in _args)
|
||||
sig += $"{param.ParameterType.Name} {param.Name}, ";
|
||||
sig += ")";
|
||||
}
|
||||
|
||||
if (cachedSigs.Contains(sig))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
CacheMember cached;
|
||||
if (mi != null && CacheMember.CanProcessArgs(mi.GetParameters()))
|
||||
cached = new CacheMethod(mi, target);
|
||||
else if (pi != null && CacheMember.CanProcessArgs(pi.GetIndexParameters()))
|
||||
cached = new CacheProperty(pi, target);
|
||||
else if (member is FieldInfo fi)
|
||||
cached = new CacheField(fi, target);
|
||||
else
|
||||
continue;
|
||||
|
||||
cached.m_parentContent = m_scrollContent;
|
||||
|
||||
if (cached != null)
|
||||
{
|
||||
cachedSigs.Add(sig);
|
||||
list.Add(cached);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Exception caching member {sig}!");
|
||||
ExplorerCore.Log(e.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Exception caching member {member.DeclaringType.FullName}.{member.Name}!");
|
||||
ExplorerCore.Log(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var typeList = types.ToList();
|
||||
|
||||
var sorted = new List<CacheMember>();
|
||||
sorted.AddRange(list.Where(it => it is CacheMethod)
|
||||
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
||||
.ThenBy(it => it.NameForFiltering));
|
||||
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));
|
||||
|
||||
m_allMembers = sorted.ToArray();
|
||||
|
||||
// ExplorerCore.Log("Cached " + m_allMembers.Length + " members");
|
||||
}
|
||||
|
||||
#region UI CONSTRUCTION
|
||||
|
||||
internal void ConstructUI()
|
||||
@ -578,7 +542,7 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
internal void ConstructOptionsArea()
|
||||
{
|
||||
var optionsRowObj = UIFactory.CreateHorizontalGroup(Content, new Color(1,1,1,0));
|
||||
var optionsRowObj = UIFactory.CreateHorizontalGroup(Content, new Color(1, 1, 1, 0));
|
||||
var optionsLayout = optionsRowObj.AddComponent<LayoutElement>();
|
||||
optionsLayout.minHeight = 25;
|
||||
var optionsGroup = optionsRowObj.GetComponent<HorizontalLayoutGroup>();
|
||||
@ -596,7 +560,7 @@ namespace UnityExplorer.Inspectors
|
||||
var updateText = updateButtonObj.GetComponentInChildren<Text>();
|
||||
updateText.text = "Update Values";
|
||||
var updateBtn = updateButtonObj.GetComponent<Button>();
|
||||
updateBtn.onClick.AddListener(() =>
|
||||
updateBtn.onClick.AddListener(() =>
|
||||
{
|
||||
bool orig = m_autoUpdate;
|
||||
m_autoUpdate = true;
|
||||
@ -617,7 +581,7 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
internal void ConstructMemberList()
|
||||
{
|
||||
var scrollobj = UIFactory.CreateScrollView(Content, out m_scrollContent, out m_sliderScroller, new Color(0.08f, 0.08f, 0.08f));
|
||||
var scrollobj = UIFactory.CreateScrollView(Content, out m_scrollContent, out m_sliderScroller, new Color(0.05f, 0.05f, 0.05f));
|
||||
|
||||
m_scrollContentRect = m_scrollContent.GetComponent<RectTransform>();
|
||||
|
||||
|
@ -63,6 +63,8 @@ namespace UnityExplorer.UI
|
||||
throw new Exception("Could not find Type 'UnityEngine.Cursor'!");
|
||||
}
|
||||
|
||||
ExplorerCore.Log("setting up forceunlockcursor patches...");
|
||||
|
||||
// Get current cursor state and enable cursor
|
||||
try
|
||||
{
|
||||
@ -77,11 +79,6 @@ namespace UnityExplorer.UI
|
||||
catch { }
|
||||
|
||||
// Setup Harmony Patches
|
||||
TryPatch(typeof(EventSystem),
|
||||
"current",
|
||||
new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_EventSystem_set_current))),
|
||||
true);
|
||||
|
||||
TryPatch(typeof(Cursor),
|
||||
"lockState",
|
||||
new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_set_lockState))),
|
||||
@ -91,10 +88,21 @@ namespace UnityExplorer.UI
|
||||
"visible",
|
||||
new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_set_visible))),
|
||||
true);
|
||||
|
||||
#if BIE
|
||||
#if CPP
|
||||
// temporarily disabling this patch in BepInEx il2cpp as it's causing a crash in some games.
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
TryPatch(typeof(EventSystem),
|
||||
"current",
|
||||
new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_EventSystem_set_current))),
|
||||
true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.Log($"Exception on CursorControl.Init! {e.GetType()}, {e.Message}");
|
||||
ExplorerCore.Log($"Exception on ForceUnlockCursor.Init! {e.GetType()}, {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,10 +128,10 @@ namespace UnityExplorer.UI
|
||||
harmony.Patch(prop.GetGetMethod(), postfix: patch);
|
||||
}
|
||||
}
|
||||
catch // (Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
//string suf = setter ? "set_" : "get_";
|
||||
//ExplorerCore.Log($"Unable to patch {type.Name}.{suf}{property}: {e.Message}");
|
||||
string suf = setter ? "set_" : "get_";
|
||||
ExplorerCore.Log($"Unable to patch {type.Name}.{suf}{property}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,13 +166,20 @@ namespace UnityExplorer.UI
|
||||
|
||||
public static void SetEventSystem()
|
||||
{
|
||||
if (InputManager.CurrentType == InputType.InputSystem)
|
||||
return;
|
||||
|
||||
m_settingEventSystem = true;
|
||||
UIManager.SetEventSystem();
|
||||
EventSystem.current = UIManager.EventSys;
|
||||
InputManager.ActivateUIModule();
|
||||
m_settingEventSystem = false;
|
||||
}
|
||||
|
||||
public static void ReleaseEventSystem()
|
||||
{
|
||||
if (InputManager.CurrentType == InputType.InputSystem)
|
||||
return;
|
||||
|
||||
if (m_lastEventSystem)
|
||||
{
|
||||
m_settingEventSystem = true;
|
||||
|
@ -8,6 +8,7 @@ using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityExplorer.Helpers;
|
||||
using UnityExplorer.UI.Shared;
|
||||
using UnityExplorer.Input;
|
||||
#if CPP
|
||||
using UnityExplorer.Unstrip;
|
||||
#endif
|
||||
@ -18,37 +19,13 @@ namespace UnityExplorer.UI
|
||||
{
|
||||
public static GameObject CanvasRoot { get; private set; }
|
||||
public static EventSystem EventSys { get; private set; }
|
||||
public static StandaloneInputModule InputModule { get; private set; }
|
||||
|
||||
//internal static Material UIMaterial { get; private set; }
|
||||
internal static Sprite ResizeCursor { get; private set; }
|
||||
internal static Font ConsoleFont { get; private set; }
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
var bundlePath = ExplorerCore.EXPLORER_FOLDER + @"\explorerui.bundle";
|
||||
if (File.Exists(bundlePath))
|
||||
{
|
||||
var bundle = AssetBundle.LoadFromFile(bundlePath);
|
||||
|
||||
// Fix for games which don't ship with 'UI/Default' shader.
|
||||
if (Graphic.defaultGraphicMaterial.shader?.name != "UI/Default")
|
||||
{
|
||||
ExplorerCore.Log("This game does not ship with the 'UI/Default' shader, using manual Default Shader...");
|
||||
Graphic.defaultGraphicMaterial.shader = bundle.LoadAsset<Shader>("DefaultUI");
|
||||
}
|
||||
|
||||
ResizeCursor = bundle.LoadAsset<Sprite>("cursor");
|
||||
|
||||
ConsoleFont = bundle.LoadAsset<Font>("CONSOLA");
|
||||
|
||||
ExplorerCore.Log("Loaded UI bundle");
|
||||
}
|
||||
else
|
||||
{
|
||||
ExplorerCore.LogWarning("Could not find the ExplorerUI Bundle! It should exist at '" + bundlePath + "'");
|
||||
return;
|
||||
}
|
||||
LoadBundle();
|
||||
|
||||
// Create core UI Canvas and Event System handler
|
||||
CreateRootCanvas();
|
||||
@ -62,12 +39,6 @@ namespace UnityExplorer.UI
|
||||
Canvas.ForceUpdateCanvases();
|
||||
}
|
||||
|
||||
public static void SetEventSystem()
|
||||
{
|
||||
EventSystem.current = EventSys;
|
||||
InputModule.ActivateModule();
|
||||
}
|
||||
|
||||
public static void OnSceneChange()
|
||||
{
|
||||
SceneExplorer.Instance?.OnSceneChange();
|
||||
@ -78,23 +49,20 @@ namespace UnityExplorer.UI
|
||||
{
|
||||
MainMenu.Instance?.Update();
|
||||
|
||||
if (EventSys && InputModule)
|
||||
if (EventSys)
|
||||
{
|
||||
if (EventSystem.current != EventSys)
|
||||
{
|
||||
ForceUnlockCursor.SetEventSystem();
|
||||
//ForceUnlockCursor.Unlock = true;
|
||||
}
|
||||
|
||||
// Fix for games which override the InputModule pointer events (eg, VRChat)
|
||||
#if CPP
|
||||
if (InputModule.m_InputPointerEvent != null)
|
||||
// Fix for games which override the InputModule pointer events (eg, VRChat)
|
||||
var evt = InputManager.InputPointerEvent;
|
||||
if (evt != null)
|
||||
{
|
||||
PointerEventData evt = InputModule.m_InputPointerEvent;
|
||||
if (!evt.eligibleForClick && evt.selectedObject)
|
||||
{
|
||||
evt.eligibleForClick = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -125,6 +93,33 @@ namespace UnityExplorer.UI
|
||||
}
|
||||
}
|
||||
|
||||
private static void LoadBundle()
|
||||
{
|
||||
var bundlePath = ExplorerCore.EXPLORER_FOLDER + @"\explorerui.bundle";
|
||||
if (File.Exists(bundlePath))
|
||||
{
|
||||
var bundle = AssetBundle.LoadFromFile(bundlePath);
|
||||
|
||||
// Fix for games which don't ship with 'UI/Default' shader.
|
||||
if (Graphic.defaultGraphicMaterial.shader?.name != "UI/Default")
|
||||
{
|
||||
ExplorerCore.Log("This game does not ship with the 'UI/Default' shader, using manual Default Shader...");
|
||||
Graphic.defaultGraphicMaterial.shader = bundle.LoadAsset<Shader>("DefaultUI");
|
||||
}
|
||||
|
||||
ResizeCursor = bundle.LoadAsset<Sprite>("cursor");
|
||||
|
||||
ConsoleFont = bundle.LoadAsset<Font>("CONSOLA");
|
||||
|
||||
ExplorerCore.Log("Loaded UI bundle");
|
||||
}
|
||||
else
|
||||
{
|
||||
ExplorerCore.LogWarning("Could not find the ExplorerUI Bundle! It should exist at '" + bundlePath + "'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static GameObject CreateRootCanvas()
|
||||
{
|
||||
GameObject rootObj = new GameObject("ExplorerCanvas");
|
||||
@ -135,8 +130,7 @@ namespace UnityExplorer.UI
|
||||
CanvasRoot.transform.position = new Vector3(0f, 0f, 1f);
|
||||
|
||||
EventSys = rootObj.AddComponent<EventSystem>();
|
||||
InputModule = rootObj.AddComponent<StandaloneInputModule>();
|
||||
InputModule.ActivateModule();
|
||||
InputManager.AddUIModule();
|
||||
|
||||
Canvas canvas = rootObj.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
|
@ -42,10 +42,10 @@ namespace UnityExplorer.UI
|
||||
|
||||
public static string ParseFullSyntax(Type type, bool includeNamespace, MemberInfo memberInfo = null)
|
||||
{
|
||||
string ret = "";
|
||||
|
||||
if (type == null)
|
||||
return "????????????";
|
||||
throw new ArgumentNullException("type");
|
||||
|
||||
string ret = "";
|
||||
|
||||
if (type.IsGenericParameter || (type.HasElementType && type.GetElementType().IsGenericParameter))
|
||||
{
|
||||
|
@ -25,7 +25,7 @@
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<RootNamespace>UnityExplorer</RootNamespace>
|
||||
<!-- Set this to the BepInEx Il2Cpp Game folder, without the ending '\' character. -->
|
||||
<BIECppGameFolder>D:\Steam\steamapps\common\Outward</BIECppGameFolder>
|
||||
<BIECppGameFolder>D:\Steam\steamapps\common\Outward_IL2CPP</BIECppGameFolder>
|
||||
<!-- Set this to the BepInEx Mono Game folder, without the ending '\' character. -->
|
||||
<BIEMonoGameFolder>D:\source\Unity Projects\Test\_BUILD_MONO</BIEMonoGameFolder>
|
||||
<!-- Set this to the BepInEx Mono Managed folder, without the ending '\' character. -->
|
||||
|
Reference in New Issue
Block a user