diff --git a/README.md b/README.md index faaf22e..f74dfc7 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,7 @@ Note: You must use version 0.3 of MelonLoader or greater. Version 0.3 is current 0. Load the DLL from your mod or inject it. You must also make sure that the required libraries (Harmony, Unhollower for Il2Cpp, etc) are loaded. 1. Create an instance of Unity Explorer with `ExplorerStandalone.CreateInstance();` -2. You will need to call `ExplorerStandalone.Update()` from your Update method. -3. Subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish. +2. Optionally subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish. ## Logging @@ -115,6 +114,7 @@ For IL2CPP: 1. Install BepInEx or MelonLoader for your game. 2. Open the `src\UnityExplorer.csproj` file in a text editor. 3. Set `BIECppGameFolder` (for BepInEx) and/or `MLCppGameFolder` (for MelonLoader) so the project can locate the necessary references. +4. For Standalone builds, you can either install BepInEx for the game to build, or just change the .csproj file and set the Unhollower reference manually. For all builds: 1. Open the `src\UnityExplorer.sln` project. diff --git a/src/Loader/ExplorerBepIn6Plugin.cs b/src/Loader/ExplorerBepIn6Plugin.cs index 0c2e311..efbe06f 100644 --- a/src/Loader/ExplorerBepIn6Plugin.cs +++ b/src/Loader/ExplorerBepIn6Plugin.cs @@ -39,8 +39,6 @@ namespace UnityExplorer Instance = this; new ExplorerCore(); - - // HarmonyInstance.PatchAll(); } internal void Update() @@ -83,8 +81,6 @@ namespace UnityExplorer GameObject.DontDestroyOnLoad(obj); new ExplorerCore(); - - // HarmonyInstance.PatchAll(); } // BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy. diff --git a/src/Loader/ExplorerStandalone.cs b/src/Loader/ExplorerStandalone.cs index a3fff85..11cc164 100644 --- a/src/Loader/ExplorerStandalone.cs +++ b/src/Loader/ExplorerStandalone.cs @@ -3,11 +3,19 @@ using HarmonyLib; using System; using System.IO; using System.Reflection; +using UnityEngine; +#if CPP +using UnhollowerRuntimeLib; +#endif namespace UnityExplorer { public class ExplorerStandalone : IExplorerLoader { + /// + /// Call this to initialize UnityExplorer. Optionally, also subscribe to the 'OnLog' event to handle logging. + /// + /// The new (or active, if one exists) instance of ExplorerStandalone. public static ExplorerStandalone CreateInstance() { if (Instance != null) @@ -18,8 +26,7 @@ namespace UnityExplorer private ExplorerStandalone() { - Instance = this; - new ExplorerCore(); + Init(); } public static ExplorerStandalone Instance { get; private set; } @@ -27,7 +34,7 @@ namespace UnityExplorer /// /// Invoked whenever Explorer logs something. Subscribe to this to handle logging. /// - public static event Action OnLog; + public static event Action OnLog; public Harmony HarmonyInstance => s_harmony; public static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID); @@ -50,16 +57,42 @@ namespace UnityExplorer public string ConfigFolder => ExplorerFolder; - Action IExplorerLoader.OnLogMessage => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", UnityEngine.LogType.Log); }; - Action IExplorerLoader.OnLogWarning => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", UnityEngine.LogType.Warning); }; - Action IExplorerLoader.OnLogError => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", UnityEngine.LogType.Error); }; + Action IExplorerLoader.OnLogMessage => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", LogType.Log); }; + Action IExplorerLoader.OnLogWarning => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", LogType.Warning); }; + Action IExplorerLoader.OnLogError => (object log) => { OnLog?.Invoke(log?.ToString() ?? "", LogType.Error); }; - /// - /// Call this once per frame for Explorer to update. - /// - public static void Update() + private void Init() { - ExplorerCore.Update(); + Instance = this; +#if CPP + ClassInjector.RegisterTypeInIl2Cpp(); + + var obj = new GameObject( + "ExplorerBehaviour", + new Il2CppSystem.Type[] { Il2CppType.Of() } + ); +#else + var obj = new GameObject( + "ExplorerBehaviour", + new Type[] { typeof(ExplorerBehaviour) } + ); +#endif + + obj.hideFlags = HideFlags.HideAndDontSave; + GameObject.DontDestroyOnLoad(obj); + + new ExplorerCore(); + } + + public class ExplorerBehaviour : MonoBehaviour + { +#if CPP + public ExplorerBehaviour(IntPtr ptr) : base(ptr) { } +#endif + internal void Update() + { + ExplorerCore.Update(); + } } } }