Compare commits

..

7 Commits
4.1.6 ... 4.1.7

Author SHA1 Message Date
92447b55cd Update README.md 2021-06-22 19:48:41 +10:00
87d5d5a2de Bump version 2021-06-22 19:46:14 +10:00
08cff3386b Fix issues with Il2Cpp nullables 2021-06-22 19:46:09 +10:00
6033200579 Don't use WaitForEndOfFrame in SrollPool init coroutine 2021-06-22 19:45:57 +10:00
94ec1c4908 Update line numbers on panel resize 2021-06-21 19:50:11 +10:00
7a400e762c Cleanup 2021-06-21 19:49:44 +10:00
67f9f744bb Handle Unity 2021+ InputField.onEndEdit change 2021-06-21 19:26:05 +10:00
9 changed files with 76 additions and 28 deletions

View File

@ -6,7 +6,7 @@
🔍 An in-game UI for exploring, debugging and modifying Unity games.
</p>
<p align="center">
✔️ Supports most Unity versions from 5.2 to 2020+ (IL2CPP and Mono).
✔️ Supports most Unity versions from 5.2 to 2021+ (IL2CPP and Mono).
</p>
<p align="center">
☕ Enjoy this tool? Consider supporting me on <a href="https://ko-fi.com/sinaidev">ko-fi</a>!

View File

@ -132,7 +132,6 @@ namespace UnityExplorer
return null;
var type = obj.GetType();
try
{
if (IsString(obj))
@ -216,7 +215,7 @@ namespace UnityExplorer
// from other structs to il2cpp object
else if (typeof(Il2CppSystem.Object).IsAssignableFrom(castTo))
{
return BoxIl2CppObject(obj);
return BoxIl2CppObject(obj).TryCast(castTo);
}
else
return obj;
@ -295,7 +294,27 @@ namespace UnityExplorer
try
{
if (toType.IsEnum)
{
// Check for nullable enums
var type = cppObj.GetType();
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Il2CppSystem.Nullable<>))
{
var nullable = cppObj.TryCast(type);
var nullableHasValueProperty = type.GetProperty("HasValue");
if ((bool)nullableHasValueProperty.GetValue(nullable, null))
{
// nullable has a value.
var nullableValueProperty = type.GetProperty("Value");
return Enum.Parse(toType, nullableValueProperty.GetValue(nullable, null).ToString());
}
// nullable and no current value.
return cppObj;
}
return Enum.Parse(toType, cppObj.ToString());
}
// Not enum, unbox with Il2CppObjectBase.Unbox
var name = toType.AssemblyQualifiedName;

View File

@ -2,9 +2,11 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Object = UnityEngine.Object;
// Project-wide namespace for accessibility
@ -107,5 +109,16 @@ namespace UnityExplorer
return color;
}
private static PropertyInfo onEndEdit;
public static UnityEvent<string> GetOnEndEdit(this InputField _this)
{
if (onEndEdit == null)
onEndEdit = typeof(InputField).GetProperty("onEndEdit")
?? throw new Exception("Could not get InputField.onEndEdit property!");
return onEndEdit.GetValue(_this, null).TryCast<UnityEvent<string>>();
}
}
}

View File

@ -20,7 +20,7 @@ namespace UnityExplorer
public static class ExplorerCore
{
public const string NAME = "UnityExplorer";
public const string VERSION = "4.1.6";
public const string VERSION = "4.1.7";
public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer";

View File

@ -53,12 +53,38 @@ namespace UnityExplorer.UI.CSConsole
public static void Init()
{
// Make sure console is supported on this platform
try
{
ResetConsole(false);
// ensure the compiler is supported (if this fails then SRE is probably stubbed)
Evaluator.Compile("0 == 0");
}
catch (Exception ex)
{
DisableConsole(ex);
return;
}
// Setup console
Lexer = new LexerBuilder();
Completer = new CSAutoCompleter();
SetupHelpInteraction();
Panel.OnInputChanged += OnInputChanged;
Panel.InputScroller.OnScroll += OnInputScrolled;
Panel.OnCompileClicked += Evaluate;
Panel.OnResetClicked += ResetConsole;
Panel.OnHelpDropdownChanged += HelpSelected;
Panel.OnAutoIndentToggled += OnToggleAutoIndent;
Panel.OnCtrlRToggled += OnToggleCtrlRShortcut;
Panel.OnSuggestionsToggled += OnToggleSuggestions;
Panel.OnPanelResized += OnInputScrolled;
// Run startup script
try
{
if (!Directory.Exists(ScriptsFolder))
Directory.CreateDirectory(ScriptsFolder);
@ -73,23 +99,8 @@ namespace UnityExplorer.UI.CSConsole
}
catch (Exception ex)
{
DisableConsole(ex);
return;
ExplorerCore.LogWarning($"Exception executing startup script: {ex}");
}
Lexer = new LexerBuilder();
Completer = new CSAutoCompleter();
SetupHelpInteraction();
Panel.OnInputChanged += OnInputChanged;
Panel.InputScroller.OnScroll += OnInputScrolled;
Panel.OnCompileClicked += Evaluate;
Panel.OnResetClicked += ResetConsole;
Panel.OnHelpDropdownChanged += HelpSelected;
Panel.OnAutoIndentToggled += OnToggleAutoIndent;
Panel.OnCtrlRToggled += OnToggleCtrlRShortcut;
Panel.OnSuggestionsToggled += OnToggleSuggestions;
}

View File

@ -468,7 +468,7 @@ namespace UnityExplorer.UI.Inspectors
//UIFactory.SetLayoutElement(pathApplyBtn.Component.gameObject, minHeight: 25, minWidth: 120);
//pathApplyBtn.OnClick += () => { OnPathEndEdit(PathInput.Text); };
PathInput.Component.onEndEdit.AddListener((string val) => { OnPathEndEdit(val); });
PathInput.Component.GetOnEndEdit().AddListener((string val) => { OnPathEndEdit(val); });
// Title and update row
@ -484,7 +484,7 @@ namespace UnityExplorer.UI.Inspectors
NameInput = UIFactory.CreateInputField(titleRow, "NameInput", "untitled");
UIFactory.SetLayoutElement(NameInput.Component.gameObject, minHeight: 30, minWidth: 100, flexibleWidth: 9999);
NameInput.Component.textComponent.fontSize = 15;
NameInput.Component.onEndEdit.AddListener((string val) => { OnNameEndEdit(val); });
NameInput.Component.GetOnEndEdit().AddListener((string val) => { OnNameEndEdit(val); });
// second row (toggles, instanceID, tag, buttons)
@ -521,7 +521,7 @@ namespace UnityExplorer.UI.Inspectors
TagInput = UIFactory.CreateInputField(secondRow, "TagInput", "none");
UIFactory.SetLayoutElement(TagInput.Component.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 999);
TagInput.Component.textComponent.color = Color.white;
TagInput.Component.onEndEdit.AddListener((string val) => { OnTagEndEdit(val); });
TagInput.Component.GetOnEndEdit().AddListener((string val) => { OnTagEndEdit(val); });
// Instantiate
var instantiateBtn = UIFactory.CreateButton(secondRow, "InstantiateBtn", "Instantiate", new Color(0.2f, 0.2f, 0.2f));
@ -644,7 +644,7 @@ namespace UnityExplorer.UI.Inspectors
var inputField = UIFactory.CreateInputField(rowObj, "InputField", "...");
UIFactory.SetLayoutElement(inputField.Component.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 999);
inputField.Component.onEndEdit.AddListener((string value) => { OnTransformInputEndEdit(type, value); });
inputField.Component.GetOnEndEdit().AddListener((string value) => { OnTransformInputEndEdit(type, value); });
var control = new TransformControl(type, inputField);

View File

@ -35,6 +35,7 @@ namespace UnityExplorer.UI.Panels
public Action<bool> OnCtrlRToggled;
public Action<bool> OnSuggestionsToggled;
public Action<bool> OnAutoIndentToggled;
public Action OnPanelResized;
private void InvokeOnValueChanged(string value)
{
@ -62,6 +63,11 @@ namespace UnityExplorer.UI.Panels
// UI Construction
public override void OnFinishResize(RectTransform panel)
{
OnPanelResized?.Invoke();
}
protected internal override void DoSetDefaultPosAndAnchors()
{
Rect.localPosition = Vector2.zero;

View File

@ -378,7 +378,7 @@ namespace UnityExplorer.UI
timeInput = UIFactory.CreateInputField(navbarPanel, "TimeInput", "timeScale");
UIFactory.SetLayoutElement(timeInput.Component.gameObject, minHeight: 25, minWidth: 40);
timeInput.Text = Time.timeScale.ToString("F2");
timeInput.Component.onEndEdit.AddListener(OnTimeInputEndEdit);
timeInput.Component.GetOnEndEdit().AddListener(OnTimeInputEndEdit);
pauseBtn = UIFactory.CreateButton(navbarPanel, "PauseButton", "||", new Color(0.2f, 0.2f, 0.2f));
UIFactory.SetLayoutElement(pauseBtn.Component.gameObject, minHeight: 25, minWidth: 25);

View File

@ -193,12 +193,11 @@ namespace UnityExplorer.UI.Widgets
RuntimeProvider.Instance.StartCoroutine(InitCoroutine(onHeightChangedListener));
}
private WaitForEndOfFrame waitForEndOfFrame = new WaitForEndOfFrame();
private IEnumerator InitCoroutine(Action onHeightChangedListener)
{
ScrollRect.content.anchoredPosition = Vector2.zero;
yield return waitForEndOfFrame ?? (waitForEndOfFrame = new WaitForEndOfFrame());
yield return null;
yield return null;
LayoutRebuilder.ForceRebuildLayoutImmediate(Content);