mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-05 12:52:24 +08:00
Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
bc5ffcab40 | |||
d070ded036 | |||
8f025622b4 | |||
89f137680e | |||
f280b45ed3 | |||
456e15020f | |||
d33d46927d | |||
7a872cecf9 | |||
b2cbdc1802 | |||
3501a28fd1 | |||
40f698122d | |||
0555a644b7 | |||
f66a04c93f | |||
8f07255d1b | |||
46f35129c5 | |||
604c499822 | |||
8964c48ba0 | |||
e85a3e0f1e | |||
c658d393f5 | |||
9a45e29e02 | |||
418ece55e3 | |||
bf455893e7 | |||
6d9cb8205a | |||
0f431e997b | |||
2107df70ad | |||
a9fbea7c96 | |||
77878ddd94 | |||
594abc47f8 | |||
5e326916a2 | |||
31c2debb78 | |||
d919497e43 | |||
0c40b4fad9 | |||
bba912667f | |||
1807e7c5ff | |||
9da2ea9b1b |
152
README.md
152
README.md
@ -5,31 +5,70 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
An in-game explorer and a suite of debugging tools for <a href="https://docs.unity3d.com/Manual/IL2CPP.html">IL2CPP</a> and <b>Mono</b> Unity games, to aid with modding development.
|
An in-game explorer and a suite of debugging tools for <a href="https://docs.unity3d.com/Manual/IL2CPP.html">IL2CPP</a> and <b>Mono</b> Unity games, to aid with modding development.
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
|
||||||
<a href="../../releases/latest">
|
|
||||||
<img src="https://img.shields.io/github/release/sinai-dev/Explorer.svg" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<img src="https://img.shields.io/github/downloads/sinai-dev/Explorer/total.svg" />
|
## Releases [](../../releases/latest) []() []()
|
||||||
</p>
|
|
||||||
|
|
||||||
- [Releases](#releases)
|
|
||||||
- [Features](#features)
|
|
||||||
- [How to install](#how-to-install)
|
|
||||||
- [Mod Config](#mod-config)
|
|
||||||
- [Building](#building)
|
|
||||||
- [Credits](#credits)
|
|
||||||
|
|
||||||
## Releases
|
|
||||||
|
|
||||||
| Mod Loader | IL2CPP | Mono |
|
| Mod Loader | IL2CPP | Mono |
|
||||||
| ----------- | ------ | ---- |
|
| ----------- | ------ | ---- |
|
||||||
| [BepInEx](https://github.com/BepInEx/BepInEx) 6.X | ✅ [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.BepInEx6.Mono.zip) |
|
| [BepInEx](https://github.com/BepInEx/BepInEx) 6.X | ✅ [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.BepInEx6.Mono.zip) |
|
||||||
| [BepInEx](https://github.com/BepInEx/BepInEx) 5.X | ❌ n/a | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx5.Mono.zip) |
|
| [BepInEx](https://github.com/BepInEx/BepInEx) 5.X | ✖️ n/a | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx5.Mono.zip) |
|
||||||
| [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) 0.3 | ✅ [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) |
|
| [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) 0.3 | ✅ [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) |
|
||||||
| Standalone | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Standalone.Il2Cpp.zip) | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Standalone.Mono.zip) |
|
| Standalone | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Standalone.Il2Cpp.zip) | ✅ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Standalone.Mono.zip) |
|
||||||
|
|
||||||
\* BepInEx 6.X Mono release may not work on all games yet.
|
## How to install
|
||||||
|
|
||||||
|
### BepInEx
|
||||||
|
|
||||||
|
0. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game. For IL2CPP you should use [BepInEx 6 (Bleeding Edge)](https://builds.bepis.io/projects/bepinex_be), for Mono you should use [BepInEx 5](https://github.com/BepInEx/BepInEx/releases) (until Mono support stabilizes in BepInEx 6).
|
||||||
|
1. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
|
||||||
|
2. Take the `UnityExplorer.BIE.___.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
|
||||||
|
3. In IL2CPP, you will need to download the [Unity libs](https://github.com/LavaGang/Unity-Runtime-Libraries) for the game's Unity version and put them in the `BepInEx\unity-libs\` folder.
|
||||||
|
|
||||||
|
### MelonLoader
|
||||||
|
|
||||||
|
0. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) 0.3+ for your game. Version 0.3 is currently in pre-release, so you must "Enable ALPHA Releases" in your MelonLoader Installer settings to see the option for it.
|
||||||
|
1. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
|
||||||
|
2. Take the `UnityExplorer.ML.___.dll` file and put it in the `[GameFolder]\Mods\` folder.
|
||||||
|
|
||||||
|
### Standalone
|
||||||
|
|
||||||
|
The standalone release is based on the BepInEx build, so it requires Harmony 2.0 (or HarmonyX) to function properly.
|
||||||
|
|
||||||
|
0. Load the DLL from your mod or inject it. You must also make sure `0Harmony.dll` is loaded, and `UnhollowerBaseLib.dll` for IL2CPP as well.
|
||||||
|
1. Create an instance of Unity Explorer with `UnityExplorer.ExplorerStandalone.CreateInstance();`
|
||||||
|
2. Optionally subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish.
|
||||||
|
|
||||||
|
## Issues and contributions
|
||||||
|
|
||||||
|
Both issue reports and PR contributions are welcome in this repository.
|
||||||
|
|
||||||
|
### Issue reporting
|
||||||
|
|
||||||
|
To report an issue with UnityExplorer, please use the following template (as well as any other information / images you can provide).
|
||||||
|
|
||||||
|
Please upload your Unity log file to [Pastebin](https://pastebin.com/) and provide a link to the paste.
|
||||||
|
|
||||||
|
* The log should be found at `%userprofile%\AppData\LocalLow\[Company]\[Game]\` unless redirected by your Mod Loader.
|
||||||
|
* The file will be called either `output_log.txt` or `Player.log`
|
||||||
|
|
||||||
|
As well as the Unity log, please upload your Mod Loader's log:
|
||||||
|
|
||||||
|
* BepInEx: `BepInEx\LogOutput.log`
|
||||||
|
* MelonLoader: `MelonLoader\Latest.log`
|
||||||
|
|
||||||
|
Template:
|
||||||
|
|
||||||
|
```
|
||||||
|
* OS Platform:
|
||||||
|
* Display resolution:
|
||||||
|
* Game(s) tested on:
|
||||||
|
* UnityExplorer version(s) tested:
|
||||||
|
|
||||||
|
* Description of issue:
|
||||||
|
|
||||||
|
* Unity log pastebin link:
|
||||||
|
* Mod Loader log pastebin link:
|
||||||
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@ -46,42 +85,46 @@
|
|||||||
* <b>C# Console</b>: Interactive console for evaluating C# methods on the fly, with some basic helpers.
|
* <b>C# Console</b>: Interactive console for evaluating C# methods on the fly, with some basic helpers.
|
||||||
* <b>Inspect-under-mouse</b>: Hover over an object with a collider and inspect it by clicking on it. There's also a UI mode to inspect UI objects.
|
* <b>Inspect-under-mouse</b>: Hover over an object with a collider and inspect it by clicking on it. There's also a UI mode to inspect UI objects.
|
||||||
|
|
||||||
## How to install
|
### C# Console Tips
|
||||||
|
|
||||||
### BepInEx
|
The C# Console can be used to define temporary classes and methods, or it can be used to evaluate an expression, but you cannot do both at the same time.
|
||||||
|
|
||||||
Note: For IL2CPP you should use [BepInEx 6 (Bleeding Edge)](https://builds.bepis.io/projects/bepinex_be), for Mono you should use [BepInEx 5](https://github.com/BepInEx/BepInEx/releases) (until Mono support stabilizes in BepInEx 6).
|
For example, you could run this code to define a temporary class (it will be visible within the console until you run `Reset();`).
|
||||||
|
|
||||||
0. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game.
|
```csharp
|
||||||
1. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
|
public class MyClass
|
||||||
2. Take the `UnityExplorer.BIE.___.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
|
{
|
||||||
3. In IL2CPP, it is highly recommended to get the base Unity libs for the game's Unity version and put them in the `BepInEx\unity-libs\` folder.
|
public static void Method()
|
||||||
|
{
|
||||||
|
UnityExplorer.ExplorerCore.Log("hello");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### MelonLoader
|
You could then delete or comment out the class and run the following expression to run that method:
|
||||||
|
|
||||||
Note: You must use version 0.3 of MelonLoader or greater. Version 0.3 is currently in pre-release, so you must opt-in from your MelonLoader installer (enable alpha releases).
|
```csharp
|
||||||
|
MyClass.Method();
|
||||||
|
```
|
||||||
|
|
||||||
0. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) for your game.
|
However, you cannot define a class and run it both at the same time. You must either define class(es) and run that, or define an expression and run that.
|
||||||
1. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
|
|
||||||
2. Take the contents of the release and put it in the `[GameFolder]\Mods\` folder. It should look like `[GameFolder]\Mods\UnityExplorer.ML.___.dll`
|
|
||||||
|
|
||||||
### Standalone
|
You can also make use of the helper methods in the console to simplify some tasks, which you can see listed when the console has nothing entered for input. These methods are **not** accessible within any temporary classes you define, they can only be used in the expression context.
|
||||||
|
|
||||||
The standalone release is based on the BepInEx build, so it requires Harmony 2.0 (or HarmonyX) to function properly.
|
### Logging
|
||||||
|
|
||||||
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. Optionally subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish.
|
|
||||||
|
|
||||||
## Logging
|
|
||||||
|
|
||||||
Explorer saves all logs to disk (only keeps the most recent 10 logs). They can be found in a "UnityExplorer" folder in the same place as where you put the DLL file.
|
Explorer saves all logs to disk (only keeps the most recent 10 logs). They can be found in a "UnityExplorer" folder in the same place as where you put the DLL file.
|
||||||
|
|
||||||
These logs are also visible in the Debug Console part of the UI.
|
These logs are also visible in the Debug Console part of the UI.
|
||||||
|
|
||||||
## Settings
|
### Settings
|
||||||
|
|
||||||
You can change the settings via the "Options" page of the main menu, or directly from the config file (generated after first launch). The config file will be found either inside a "UnityExplorer" folder in the same directory as where you put the DLL file, or for BepInEx it will be at `BepInEx\config\UnityExplorer\`.
|
You can change the settings via the "Options" page of the main menu, or directly from the config file.
|
||||||
|
|
||||||
|
Depending on the release you are using, the config file will be found at:
|
||||||
|
* BepInEx: `BepInEx\config\com.sinai.unityexplorer.cfg`
|
||||||
|
* MelonLoader: `UserData\MelonPreferences.cfg`
|
||||||
|
* Standalone `{DLL_location}\UnityExplorer\config.ini`
|
||||||
|
|
||||||
`Main Menu Toggle` (KeyCode)
|
`Main Menu Toggle` (KeyCode)
|
||||||
* Default: `F7`
|
* Default: `F7`
|
||||||
@ -110,27 +153,20 @@ You can change the settings via the "Options" page of the main menu, or directly
|
|||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
If you'd like to build this yourself, all you need to do is download this repository and build from Visual Studio. If you want to build for BepInEx or MelonLoader IL2CPP then you will need to install the mod loader for a game and set the directory in the `csproj` file.
|
Building the project should be straight-forward, the references are all inside the `lib\` folder.
|
||||||
|
|
||||||
For IL2CPP:
|
1. Open the `src\UnityExplorer.sln` project in Visual Studio.
|
||||||
1. Install BepInEx or MelonLoader for your game.
|
2. Select `Solution 'UnityExplorer' (1 of 1 project)` in the Solution Explorer panel, and set the <b>Active config</b> property to the version you want to build, then build it. Alternatively, use "Batch Build" and select all releases.
|
||||||
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.
|
|
||||||
2. Select `Solution 'UnityExplorer' (1 of 1 project)` in the Solution Explorer panel, and set the <b>Active config</b> property to the version you want to build, then build it.
|
|
||||||
3. The DLLs are built to the `Release\` folder in the root of the repository.
|
3. The DLLs are built to the `Release\` folder in the root of the repository.
|
||||||
4. If ILRepack fails or is missing, use the NuGet package manager to re-install `ILRepack.Lib.MSBuild.Task`, then re-build.
|
4. If ILRepack complains about an error, just change the Active config to a different release and then back again. This sometimes happens for the first time you build the project.
|
||||||
|
|
||||||
## Credits
|
## Acknowledgments
|
||||||
|
|
||||||
Written by Sinai.
|
* [ManlyMarco](https://github.com/ManlyMarco) for [Runtime Unity Editor](https://github.com/ManlyMarco/RuntimeUnityEditor), snippets from the REPL Console were used for UnityExplorer's C# Console.
|
||||||
|
* [denikson](https://github.com/denikson) (aka Horse) for [mcs-unity](https://github.com/denikson/mcs-unity), used as the `Mono.CSharp` reference for the C# Console.
|
||||||
|
* [HerpDerpenstine](https://github.com/HerpDerpinstine) for [MelonCoroutines](https://github.com/LavaGang/MelonLoader/blob/master/MelonLoader.Support.Il2Cpp/MelonCoroutines.cs), they were included for standalone IL2CPP coroutine support.
|
||||||
|
* [InGameCodeEditor](https://assetstore.unity.com/packages/tools/gui/ingame-code-editor-144254) was used as the base for the syntax highlighting for UnityExplorer's C# console (`UnityExplorer.UI.Main.CSConsole.Lexer`).
|
||||||
|
|
||||||
### Licensing
|
### Disclaimer
|
||||||
|
|
||||||
This project uses code from:
|
UnityExplorer is in no way associated with Unity Technologies. "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere.
|
||||||
* (GPL) [ManlyMarco](https://github.com/ManlyMarco)'s [Runtime Unity Editor](https://github.com/ManlyMarco/RuntimeUnityEditor), which I used for some aspects of the C# Console and Auto-Complete features. The snippets I used are indicated with a comment.
|
|
||||||
* (MIT) [denikson](https://github.com/denikson) (aka Horse)'s [mcs-unity](https://github.com/denikson/mcs-unity). I commented out the `SkipVisibilityExt` constructor since it was causing an exception with the Hook it attempted in IL2CPP.
|
|
||||||
* (Apache) [InGameCodeEditor](https://assetstore.unity.com/packages/tools/gui/ingame-code-editor-144254) was used as the base for the syntax highlighting for UnityExplorer's C# console, although it has been heavily rewritten and optimized. Used classes are in the `UnityExplorer.CSConsole.Lexer` namespace.
|
|
||||||
|
BIN
lib/UnhollowerBaseLib.dll
Normal file
BIN
lib/UnhollowerBaseLib.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
lib/unhollowed/Il2CppSystem.Core.dll
Normal file
BIN
lib/unhollowed/Il2CppSystem.Core.dll
Normal file
Binary file not shown.
BIN
lib/unhollowed/Il2Cppmscorlib.dll
Normal file
BIN
lib/unhollowed/Il2Cppmscorlib.dll
Normal file
Binary file not shown.
BIN
lib/unhollowed/UnityEngine.CoreModule.dll
Normal file
BIN
lib/unhollowed/UnityEngine.CoreModule.dll
Normal file
Binary file not shown.
BIN
lib/unhollowed/UnityEngine.IMGUIModule.dll
Normal file
BIN
lib/unhollowed/UnityEngine.IMGUIModule.dll
Normal file
Binary file not shown.
BIN
lib/unhollowed/UnityEngine.PhysicsModule.dll
Normal file
BIN
lib/unhollowed/UnityEngine.PhysicsModule.dll
Normal file
Binary file not shown.
BIN
lib/unhollowed/UnityEngine.TextRenderingModule.dll
Normal file
BIN
lib/unhollowed/UnityEngine.TextRenderingModule.dll
Normal file
Binary file not shown.
BIN
lib/unhollowed/UnityEngine.UI.dll
Normal file
BIN
lib/unhollowed/UnityEngine.UI.dll
Normal file
Binary file not shown.
BIN
lib/unhollowed/UnityEngine.UIModule.dll
Normal file
BIN
lib/unhollowed/UnityEngine.UIModule.dll
Normal file
Binary file not shown.
BIN
lib/unhollowed/UnityEngine.dll
Normal file
BIN
lib/unhollowed/UnityEngine.dll
Normal file
Binary file not shown.
29
src/Core/CSharp/DummyBehaviour.cs
Normal file
29
src/Core/CSharp/DummyBehaviour.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#if MONO
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.CSharp
|
||||||
|
{
|
||||||
|
public class DummyBehaviour : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static DummyBehaviour Instance;
|
||||||
|
|
||||||
|
public static void Setup()
|
||||||
|
{
|
||||||
|
var obj = new GameObject("Explorer_DummyBehaviour");
|
||||||
|
DontDestroyOnLoad(obj);
|
||||||
|
obj.hideFlags |= HideFlags.HideAndDontSave;
|
||||||
|
|
||||||
|
obj.AddComponent<DummyBehaviour>();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Awake()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -15,11 +15,12 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
"mscorlib", "System.Core", "System", "System.Xml"
|
"mscorlib", "System.Core", "System", "System.Xml"
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly TextWriter tw;
|
internal static TextWriter _textWriter;
|
||||||
|
internal static StreamReportPrinter _reportPrinter;
|
||||||
|
|
||||||
public ScriptEvaluator(TextWriter tw) : base(BuildContext(tw))
|
public ScriptEvaluator(TextWriter tw) : base(BuildContext(tw))
|
||||||
{
|
{
|
||||||
this.tw = tw;
|
_textWriter = tw;
|
||||||
|
|
||||||
ImportAppdomainAssemblies(ReferenceAssembly);
|
ImportAppdomainAssemblies(ReferenceAssembly);
|
||||||
AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
|
AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
|
||||||
@ -28,23 +29,22 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
|
AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
|
||||||
tw.Dispose();
|
_textWriter.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
|
private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
|
||||||
{
|
{
|
||||||
string name = args.LoadedAssembly.GetName().Name;
|
string name = args.LoadedAssembly.GetName().Name;
|
||||||
|
|
||||||
if (StdLib.Contains(name))
|
if (StdLib.Contains(name))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
ReferenceAssembly(args.LoadedAssembly);
|
ReferenceAssembly(args.LoadedAssembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CompilerContext BuildContext(TextWriter tw)
|
private static CompilerContext BuildContext(TextWriter tw)
|
||||||
{
|
{
|
||||||
var reporter = new StreamReportPrinter(tw);
|
_reportPrinter = new StreamReportPrinter(tw);
|
||||||
|
|
||||||
var settings = new CompilerSettings
|
var settings = new CompilerSettings
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
EnhancedWarnings = false
|
EnhancedWarnings = false
|
||||||
};
|
};
|
||||||
|
|
||||||
return new CompilerContext(settings, reporter);
|
return new CompilerContext(settings, _reportPrinter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ImportAppdomainAssemblies(Action<Assembly> import)
|
private static void ImportAppdomainAssemblies(Action<Assembly> import)
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using Mono.CSharp;
|
using Mono.CSharp;
|
||||||
using UnityExplorer.UI;
|
using System.Collections;
|
||||||
using UnityExplorer.UI.Main;
|
using UnityEngine;
|
||||||
using UnityExplorer.Core.Inspectors;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
|
using UnityExplorer.UI.Main.CSConsole;
|
||||||
|
using UnityExplorer.UI.Main.Home;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.CSharp
|
namespace UnityExplorer.Core.CSharp
|
||||||
{
|
{
|
||||||
@ -13,6 +17,11 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
ExplorerCore.Log(message);
|
ExplorerCore.Log(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void StartCoroutine(IEnumerator ienumerator)
|
||||||
|
{
|
||||||
|
RuntimeProvider.Instance.StartConsoleCoroutine(ienumerator);
|
||||||
|
}
|
||||||
|
|
||||||
public static void AddUsing(string directive)
|
public static void AddUsing(string directive)
|
||||||
{
|
{
|
||||||
CSharpConsole.Instance.AddUsing(directive);
|
CSharpConsole.Instance.AddUsing(directive);
|
||||||
@ -20,7 +29,7 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
|
|
||||||
public static void GetUsing()
|
public static void GetUsing()
|
||||||
{
|
{
|
||||||
ExplorerCore.Log(CSharpConsole.Instance.m_evaluator.GetUsing());
|
ExplorerCore.Log(CSharpConsole.Instance.Evaluator.GetUsing());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Reset()
|
public static void Reset()
|
||||||
|
@ -4,8 +4,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.UI.Main.CSConsole;
|
||||||
using UnityExplorer.UI.CSConsole;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.CSharp
|
namespace UnityExplorer.Core.CSharp
|
||||||
{
|
{
|
||||||
@ -47,8 +46,8 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
|
|
||||||
// ~~~~ Static ~~~~
|
// ~~~~ Static ~~~~
|
||||||
|
|
||||||
public static HashSet<string> Namespaces => m_namspaces ?? GetNamespaces();
|
public static HashSet<string> Namespaces => m_namespaces ?? GetNamespaces();
|
||||||
private static HashSet<string> m_namspaces;
|
private static HashSet<string> m_namespaces;
|
||||||
|
|
||||||
public static HashSet<string> Keywords => m_keywords ?? (m_keywords = new HashSet<string>(CSLexerHighlighter.validKeywordMatcher.Keywords));
|
public static HashSet<string> Keywords => m_keywords ?? (m_keywords = new HashSet<string>(CSLexerHighlighter.validKeywordMatcher.Keywords));
|
||||||
private static HashSet<string> m_keywords;
|
private static HashSet<string> m_keywords;
|
||||||
@ -63,7 +62,7 @@ namespace UnityExplorer.Core.CSharp
|
|||||||
.Where(x => x.IsPublic && !string.IsNullOrEmpty(x.Namespace))
|
.Where(x => x.IsPublic && !string.IsNullOrEmpty(x.Namespace))
|
||||||
.Select(x => x.Namespace));
|
.Select(x => x.Namespace));
|
||||||
|
|
||||||
return m_namspaces = set;
|
return m_namespaces = set;
|
||||||
|
|
||||||
IEnumerable<Type> GetTypes(Assembly asm) => asm.TryGetTypes();
|
IEnumerable<Type> GetTypes(Assembly asm) => asm.TryGetTypes();
|
||||||
}
|
}
|
||||||
|
74
src/Core/Config/ConfigElement.cs
Normal file
74
src/Core/Config/ConfigElement.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.Config
|
||||||
|
{
|
||||||
|
public class ConfigElement<T> : IConfigElement
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
public string Description { get; }
|
||||||
|
|
||||||
|
public bool IsInternal { get; }
|
||||||
|
public Type ElementType => typeof(T);
|
||||||
|
|
||||||
|
public Action<T> OnValueChanged;
|
||||||
|
public Action OnValueChangedNotify { get; set; }
|
||||||
|
|
||||||
|
public object DefaultValue { get; }
|
||||||
|
|
||||||
|
public T Value
|
||||||
|
{
|
||||||
|
get => m_value;
|
||||||
|
set => SetValue(value);
|
||||||
|
}
|
||||||
|
private T m_value;
|
||||||
|
|
||||||
|
object IConfigElement.BoxedValue
|
||||||
|
{
|
||||||
|
get => m_value;
|
||||||
|
set => SetValue((T)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigElement(string name, string description, T defaultValue, bool isInternal = false)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Description = description;
|
||||||
|
|
||||||
|
m_value = defaultValue;
|
||||||
|
DefaultValue = defaultValue;
|
||||||
|
|
||||||
|
IsInternal = isInternal;
|
||||||
|
|
||||||
|
ConfigManager.RegisterConfigElement(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValue(T value)
|
||||||
|
{
|
||||||
|
if ((m_value == null && value == null) || m_value.Equals(value))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_value = value;
|
||||||
|
|
||||||
|
ConfigManager.Handler.SetConfigValue(this, value);
|
||||||
|
|
||||||
|
OnValueChanged?.Invoke(value);
|
||||||
|
OnValueChangedNotify?.Invoke();
|
||||||
|
|
||||||
|
ConfigManager.Handler.OnAnyConfigChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
object IConfigElement.GetLoaderConfigValue() => GetLoaderConfigValue();
|
||||||
|
|
||||||
|
public T GetLoaderConfigValue()
|
||||||
|
{
|
||||||
|
return ConfigManager.Handler.GetConfigValue(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RevertToDefaultValue()
|
||||||
|
{
|
||||||
|
Value = (T)DefaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/Core/Config/ConfigHandler.cs
Normal file
24
src/Core/Config/ConfigHandler.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.Config
|
||||||
|
{
|
||||||
|
public abstract class ConfigHandler
|
||||||
|
{
|
||||||
|
public abstract void RegisterConfigElement<T>(ConfigElement<T> element);
|
||||||
|
|
||||||
|
public abstract void SetConfigValue<T>(ConfigElement<T> element, T value);
|
||||||
|
|
||||||
|
public abstract T GetConfigValue<T>(ConfigElement<T> element);
|
||||||
|
|
||||||
|
public abstract void Init();
|
||||||
|
|
||||||
|
public abstract void LoadConfig();
|
||||||
|
|
||||||
|
public abstract void SaveConfig();
|
||||||
|
|
||||||
|
public virtual void OnAnyConfigChanged() { }
|
||||||
|
}
|
||||||
|
}
|
246
src/Core/Config/ConfigManager.cs
Normal file
246
src/Core/Config/ConfigManager.cs
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityExplorer.UI.Main;
|
||||||
|
using UnityExplorer.UI.Main.Home;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.Config
|
||||||
|
{
|
||||||
|
public static class ConfigManager
|
||||||
|
{
|
||||||
|
// Each Mod Loader has its own ConfigHandler.
|
||||||
|
// See the UnityExplorer.Loader namespace for the implementations.
|
||||||
|
public static ConfigHandler Handler { get; private set; }
|
||||||
|
|
||||||
|
public static ConfigElement<KeyCode> Main_Menu_Toggle;
|
||||||
|
public static ConfigElement<bool> Force_Unlock_Mouse;
|
||||||
|
public static ConfigElement<int> Default_Page_Limit;
|
||||||
|
public static ConfigElement<string> Default_Output_Path;
|
||||||
|
public static ConfigElement<bool> Log_Unity_Debug;
|
||||||
|
public static ConfigElement<bool> Hide_On_Startup;
|
||||||
|
|
||||||
|
public static ConfigElement<string> Last_Window_Anchors;
|
||||||
|
public static ConfigElement<string> Last_Window_Position;
|
||||||
|
public static ConfigElement<int> Last_Active_Tab;
|
||||||
|
public static ConfigElement<bool> Last_DebugConsole_State;
|
||||||
|
public static ConfigElement<bool> Last_SceneExplorer_State;
|
||||||
|
|
||||||
|
internal static readonly Dictionary<string, IConfigElement> ConfigElements = new Dictionary<string, IConfigElement>();
|
||||||
|
|
||||||
|
public static void Init(ConfigHandler configHandler)
|
||||||
|
{
|
||||||
|
Handler = configHandler;
|
||||||
|
Handler.Init();
|
||||||
|
|
||||||
|
CreateConfigElements();
|
||||||
|
|
||||||
|
Handler.LoadConfig();
|
||||||
|
|
||||||
|
SceneExplorer.OnToggleShow += SceneExplorer_OnToggleShow;
|
||||||
|
PanelDragger.OnFinishResize += PanelDragger_OnFinishResize;
|
||||||
|
PanelDragger.OnFinishDrag += PanelDragger_OnFinishDrag;
|
||||||
|
MainMenu.OnActiveTabChanged += MainMenu_OnActiveTabChanged;
|
||||||
|
DebugConsole.OnToggleShow += DebugConsole_OnToggleShow;
|
||||||
|
|
||||||
|
InitConsoleCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void RegisterConfigElement<T>(ConfigElement<T> configElement)
|
||||||
|
{
|
||||||
|
Handler.RegisterConfigElement(configElement);
|
||||||
|
ConfigElements.Add(configElement.Name, configElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateConfigElements()
|
||||||
|
{
|
||||||
|
Main_Menu_Toggle = new ConfigElement<KeyCode>("Main Menu Toggle",
|
||||||
|
"The UnityEngine.KeyCode to toggle the UnityExplorer Menu.",
|
||||||
|
KeyCode.F7);
|
||||||
|
|
||||||
|
Hide_On_Startup = new ConfigElement<bool>("Hide On Startup",
|
||||||
|
"Should UnityExplorer be hidden on startup?",
|
||||||
|
false);
|
||||||
|
|
||||||
|
Log_Unity_Debug = new ConfigElement<bool>("Log Unity Debug",
|
||||||
|
"Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?",
|
||||||
|
false);
|
||||||
|
|
||||||
|
Force_Unlock_Mouse = new ConfigElement<bool>("Force Unlock Mouse",
|
||||||
|
"Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.",
|
||||||
|
true);
|
||||||
|
|
||||||
|
Default_Page_Limit = new ConfigElement<int>("Default Page Limit",
|
||||||
|
"The default maximum number of elements per 'page' in UnityExplorer.",
|
||||||
|
25);
|
||||||
|
|
||||||
|
Default_Output_Path = new ConfigElement<string>("Default Output Path",
|
||||||
|
"The default output path when exporting things from UnityExplorer.",
|
||||||
|
Path.Combine(ExplorerCore.Loader.ExplorerFolder, "Output"));
|
||||||
|
|
||||||
|
// Internal configs
|
||||||
|
|
||||||
|
Last_Window_Anchors = new ConfigElement<string>("Last_Window_Anchors",
|
||||||
|
"For internal use, the last anchors of the UnityExplorer window.",
|
||||||
|
DEFAULT_WINDOW_ANCHORS,
|
||||||
|
true);
|
||||||
|
|
||||||
|
Last_Window_Position = new ConfigElement<string>("Last_Window_Position",
|
||||||
|
"For internal use, the last position of the UnityExplorer window.",
|
||||||
|
DEFAULT_WINDOW_POSITION,
|
||||||
|
true);
|
||||||
|
|
||||||
|
Last_Active_Tab = new ConfigElement<int>("Last_Active_Tab",
|
||||||
|
"For internal use, the last active tab index.",
|
||||||
|
0,
|
||||||
|
true);
|
||||||
|
|
||||||
|
Last_DebugConsole_State = new ConfigElement<bool>("Last_DebugConsole_State",
|
||||||
|
"For internal use, the collapsed state of the Debug Console.",
|
||||||
|
true,
|
||||||
|
true);
|
||||||
|
|
||||||
|
Last_SceneExplorer_State = new ConfigElement<bool>("Last_SceneExplorer_State",
|
||||||
|
"For internal use, the collapsed state of the Scene Explorer.",
|
||||||
|
true,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal config callback listeners
|
||||||
|
|
||||||
|
private static void PanelDragger_OnFinishResize(RectTransform rect)
|
||||||
|
{
|
||||||
|
Last_Window_Anchors.Value = rect.RectAnchorsToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PanelDragger_OnFinishDrag(RectTransform rect)
|
||||||
|
{
|
||||||
|
Last_Window_Position.Value = rect.RectPositionToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MainMenu_OnActiveTabChanged(int page)
|
||||||
|
{
|
||||||
|
Last_Active_Tab.Value = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DebugConsole_OnToggleShow(bool showing)
|
||||||
|
{
|
||||||
|
Last_DebugConsole_State.Value = showing;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SceneExplorer_OnToggleShow(bool showing)
|
||||||
|
{
|
||||||
|
Last_SceneExplorer_State.Value = showing;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region CONSOLE ONEXIT CALLBACK
|
||||||
|
|
||||||
|
internal static void InitConsoleCallback()
|
||||||
|
{
|
||||||
|
handler = new ConsoleEventDelegate(ConsoleEventCallback);
|
||||||
|
SetConsoleCtrlHandler(handler, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ConsoleEventCallback(int eventType)
|
||||||
|
{
|
||||||
|
// 2 is Console Quit
|
||||||
|
if (eventType == 2)
|
||||||
|
Handler.SaveConfig();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ConsoleEventDelegate handler;
|
||||||
|
private delegate bool ConsoleEventDelegate(int eventType);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region WINDOW ANCHORS / POSITION HELPERS
|
||||||
|
|
||||||
|
// Window Anchors helpers
|
||||||
|
|
||||||
|
private const string DEFAULT_WINDOW_ANCHORS = "0.25,0.10,0.78,0.95";
|
||||||
|
private const string DEFAULT_WINDOW_POSITION = "0,0";
|
||||||
|
|
||||||
|
internal static CultureInfo _enCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
|
internal static string RectAnchorsToString(this RectTransform rect)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return string.Format(_enCulture, "{0},{1},{2},{3}", new object[]
|
||||||
|
{
|
||||||
|
rect.anchorMin.x,
|
||||||
|
rect.anchorMin.y,
|
||||||
|
rect.anchorMax.x,
|
||||||
|
rect.anchorMax.y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return DEFAULT_WINDOW_ANCHORS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetAnchorsFromString(this RectTransform panel, string stringAnchors)
|
||||||
|
{
|
||||||
|
Vector4 anchors;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var split = stringAnchors.Split(',');
|
||||||
|
|
||||||
|
if (split.Length != 4)
|
||||||
|
throw new Exception();
|
||||||
|
|
||||||
|
anchors.x = float.Parse(split[0], _enCulture);
|
||||||
|
anchors.y = float.Parse(split[1], _enCulture);
|
||||||
|
anchors.z = float.Parse(split[2], _enCulture);
|
||||||
|
anchors.w = float.Parse(split[3], _enCulture);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
anchors = new Vector4(0.25f, 0.1f, 0.78f, 0.95f);
|
||||||
|
}
|
||||||
|
|
||||||
|
panel.anchorMin = new Vector2(anchors.x, anchors.y);
|
||||||
|
panel.anchorMax = new Vector2(anchors.z, anchors.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string RectPositionToString(this RectTransform rect)
|
||||||
|
{
|
||||||
|
return string.Format(_enCulture, "{0},{1}", new object[]
|
||||||
|
{
|
||||||
|
rect.localPosition.x, rect.localPosition.y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetPositionFromString(this RectTransform rect, string stringPosition)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var split = stringPosition.Split(',');
|
||||||
|
|
||||||
|
if (split.Length != 2)
|
||||||
|
throw new Exception();
|
||||||
|
|
||||||
|
Vector3 vector = rect.localPosition;
|
||||||
|
vector.x = float.Parse(split[0], _enCulture);
|
||||||
|
vector.y = float.Parse(split[1], _enCulture);
|
||||||
|
rect.localPosition = vector;
|
||||||
|
}
|
||||||
|
catch //(Exception ex)
|
||||||
|
{
|
||||||
|
//ExplorerCore.LogWarning("Exception setting window position: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -1,153 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using UnityEngine;
|
|
||||||
using IniParser;
|
|
||||||
using IniParser.Parser;
|
|
||||||
using UnityExplorer.UI;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Config
|
|
||||||
{
|
|
||||||
public class ExplorerConfig
|
|
||||||
{
|
|
||||||
public static ExplorerConfig Instance;
|
|
||||||
|
|
||||||
internal static readonly IniDataParser _parser = new IniDataParser();
|
|
||||||
internal static readonly string INI_PATH = Path.Combine(ExplorerCore.Loader.ConfigFolder, "config.ini");
|
|
||||||
|
|
||||||
static ExplorerConfig()
|
|
||||||
{
|
|
||||||
_parser.Configuration.CommentString = "#";
|
|
||||||
|
|
||||||
PanelDragger.OnFinishResize += PanelDragger_OnFinishResize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual configs
|
|
||||||
public KeyCode Main_Menu_Toggle = KeyCode.F7;
|
|
||||||
public bool Force_Unlock_Mouse = true;
|
|
||||||
public int Default_Page_Limit = 25;
|
|
||||||
public string Default_Output_Path = Path.Combine(ExplorerCore.EXPLORER_FOLDER, "Output");
|
|
||||||
public bool Log_Unity_Debug = false;
|
|
||||||
public bool Hide_On_Startup = false;
|
|
||||||
public string Window_Anchors = DEFAULT_WINDOW_ANCHORS;
|
|
||||||
|
|
||||||
private const string DEFAULT_WINDOW_ANCHORS = "0.25,0.1,0.78,0.95";
|
|
||||||
|
|
||||||
public static event Action OnConfigChanged;
|
|
||||||
|
|
||||||
internal static void InvokeConfigChanged()
|
|
||||||
{
|
|
||||||
OnConfigChanged?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void OnLoad()
|
|
||||||
{
|
|
||||||
Instance = new ExplorerConfig();
|
|
||||||
|
|
||||||
if (LoadSettings())
|
|
||||||
return;
|
|
||||||
|
|
||||||
SaveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool LoadSettings()
|
|
||||||
{
|
|
||||||
if (!File.Exists(INI_PATH))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
string ini = File.ReadAllText(INI_PATH);
|
|
||||||
|
|
||||||
var data = _parser.Parse(ini);
|
|
||||||
|
|
||||||
foreach (var config in data.Sections["Config"])
|
|
||||||
{
|
|
||||||
switch (config.KeyName)
|
|
||||||
{
|
|
||||||
case nameof(Main_Menu_Toggle):
|
|
||||||
Instance.Main_Menu_Toggle = (KeyCode)Enum.Parse(typeof(KeyCode), config.Value);
|
|
||||||
break;
|
|
||||||
case nameof(Force_Unlock_Mouse):
|
|
||||||
Instance.Force_Unlock_Mouse = bool.Parse(config.Value);
|
|
||||||
break;
|
|
||||||
case nameof(Default_Page_Limit):
|
|
||||||
Instance.Default_Page_Limit = int.Parse(config.Value);
|
|
||||||
break;
|
|
||||||
case nameof(Log_Unity_Debug):
|
|
||||||
Instance.Log_Unity_Debug = bool.Parse(config.Value);
|
|
||||||
break;
|
|
||||||
case nameof(Default_Output_Path):
|
|
||||||
Instance.Default_Output_Path = config.Value;
|
|
||||||
break;
|
|
||||||
case nameof(Hide_On_Startup):
|
|
||||||
Instance.Hide_On_Startup = bool.Parse(config.Value);
|
|
||||||
break;
|
|
||||||
case nameof(Window_Anchors):
|
|
||||||
Instance.Window_Anchors = config.Value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SaveSettings()
|
|
||||||
{
|
|
||||||
var data = new IniParser.Model.IniData();
|
|
||||||
|
|
||||||
data.Sections.AddSection("Config");
|
|
||||||
|
|
||||||
var sec = data.Sections["Config"];
|
|
||||||
sec.AddKey(nameof(Main_Menu_Toggle), Instance.Main_Menu_Toggle.ToString());
|
|
||||||
sec.AddKey(nameof(Force_Unlock_Mouse), Instance.Force_Unlock_Mouse.ToString());
|
|
||||||
sec.AddKey(nameof(Default_Page_Limit), Instance.Default_Page_Limit.ToString());
|
|
||||||
sec.AddKey(nameof(Log_Unity_Debug), Instance.Log_Unity_Debug.ToString());
|
|
||||||
sec.AddKey(nameof(Default_Output_Path), Instance.Default_Output_Path);
|
|
||||||
sec.AddKey(nameof(Hide_On_Startup), Instance.Hide_On_Startup.ToString());
|
|
||||||
sec.AddKey(nameof(Window_Anchors), GetWindowAnchorsString());
|
|
||||||
|
|
||||||
if (!Directory.Exists(ExplorerCore.Loader.ConfigFolder))
|
|
||||||
Directory.CreateDirectory(ExplorerCore.Loader.ConfigFolder);
|
|
||||||
|
|
||||||
File.WriteAllText(INI_PATH, data.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ Window Anchors specific stuff ============== //
|
|
||||||
|
|
||||||
private static void PanelDragger_OnFinishResize()
|
|
||||||
{
|
|
||||||
Instance.Window_Anchors = GetWindowAnchorsString();
|
|
||||||
SaveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Vector4 GetWindowAnchorsVector()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var split = Window_Anchors.Split(',');
|
|
||||||
Vector4 ret = Vector4.zero;
|
|
||||||
ret.x = float.Parse(split[0]);
|
|
||||||
ret.y = float.Parse(split[1]);
|
|
||||||
ret.z = float.Parse(split[2]);
|
|
||||||
ret.w = float.Parse(split[3]);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Window_Anchors = DEFAULT_WINDOW_ANCHORS;
|
|
||||||
return GetWindowAnchorsVector();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string GetWindowAnchorsString()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var rect = PanelDragger.Instance.Panel;
|
|
||||||
return $"{rect.anchorMin.x},{rect.anchorMin.y},{rect.anchorMax.x},{rect.anchorMax.y}";
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return DEFAULT_WINDOW_ANCHORS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
22
src/Core/Config/IConfigElement.cs
Normal file
22
src/Core/Config/IConfigElement.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.Config
|
||||||
|
{
|
||||||
|
public interface IConfigElement
|
||||||
|
{
|
||||||
|
string Name { get; }
|
||||||
|
string Description { get; }
|
||||||
|
|
||||||
|
bool IsInternal { get; }
|
||||||
|
Type ElementType { get; }
|
||||||
|
|
||||||
|
object BoxedValue { get; set; }
|
||||||
|
object DefaultValue { get; }
|
||||||
|
|
||||||
|
object GetLoaderConfigValue();
|
||||||
|
|
||||||
|
void RevertToDefaultValue();
|
||||||
|
|
||||||
|
Action OnValueChangedNotify { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -6,30 +6,29 @@ using UnityExplorer.Core.Input;
|
|||||||
using BF = System.Reflection.BindingFlags;
|
using BF = System.Reflection.BindingFlags;
|
||||||
using UnityExplorer.Core.Config;
|
using UnityExplorer.Core.Config;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.UI;
|
||||||
#if ML
|
#if ML
|
||||||
using Harmony;
|
using Harmony;
|
||||||
#else
|
#else
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Utility
|
namespace UnityExplorer.Core.Input
|
||||||
{
|
{
|
||||||
public class CursorUnlocker
|
public class CursorUnlocker
|
||||||
{
|
{
|
||||||
public static bool Unlock
|
public static bool Unlock
|
||||||
{
|
{
|
||||||
get => m_forceUnlock;
|
get => m_forceUnlock;
|
||||||
set => SetForceUnlock(value);
|
set
|
||||||
|
{
|
||||||
|
m_forceUnlock = value;
|
||||||
|
UpdateCursorControl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private static bool m_forceUnlock;
|
private static bool m_forceUnlock;
|
||||||
|
|
||||||
private static void SetForceUnlock(bool unlock)
|
public static bool ShouldActuallyUnlock => UIManager.ShowMenu && Unlock;
|
||||||
{
|
|
||||||
m_forceUnlock = unlock;
|
|
||||||
UpdateCursorControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ShouldForceMouse => UIManager.ShowMenu && Unlock;
|
|
||||||
|
|
||||||
private static CursorLockMode m_lastLockMode;
|
private static CursorLockMode m_lastLockMode;
|
||||||
private static bool m_lastVisibleState;
|
private static bool m_lastVisibleState;
|
||||||
@ -43,16 +42,12 @@ namespace UnityExplorer.UI.Utility
|
|||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
ExplorerConfig.OnConfigChanged += ModConfig_OnConfigChanged;
|
|
||||||
|
|
||||||
SetupPatches();
|
SetupPatches();
|
||||||
|
|
||||||
Unlock = true;
|
UpdateCursorControl();
|
||||||
}
|
|
||||||
|
|
||||||
internal static void ModConfig_OnConfigChanged()
|
Unlock = true;
|
||||||
{
|
ConfigManager.Force_Unlock_Mouse.OnValueChanged += (bool val) => { Unlock = val; };
|
||||||
Unlock = ExplorerConfig.Instance.Force_Unlock_Mouse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetupPatches()
|
private static void SetupPatches()
|
||||||
@ -67,11 +62,9 @@ namespace UnityExplorer.UI.Utility
|
|||||||
// Get current cursor state and enable cursor
|
// Get current cursor state and enable cursor
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//m_lastLockMode = Cursor.lockState;
|
|
||||||
m_lastLockMode = (CursorLockMode?)typeof(Cursor).GetProperty("lockState", BF.Public | BF.Static)?.GetValue(null, null)
|
m_lastLockMode = (CursorLockMode?)typeof(Cursor).GetProperty("lockState", BF.Public | BF.Static)?.GetValue(null, null)
|
||||||
?? CursorLockMode.None;
|
?? CursorLockMode.None;
|
||||||
|
|
||||||
//m_lastVisibleState = Cursor.visible;
|
|
||||||
m_lastVisibleState = (bool?)typeof(Cursor).GetProperty("visible", BF.Public | BF.Static)?.GetValue(null, null)
|
m_lastVisibleState = (bool?)typeof(Cursor).GetProperty("visible", BF.Public | BF.Static)?.GetValue(null, null)
|
||||||
?? false;
|
?? false;
|
||||||
}
|
}
|
||||||
@ -105,7 +98,7 @@ namespace UnityExplorer.UI.Utility
|
|||||||
{
|
{
|
||||||
var harmony = ExplorerCore.Loader.HarmonyInstance;
|
var harmony = ExplorerCore.Loader.HarmonyInstance;
|
||||||
|
|
||||||
System.Reflection.PropertyInfo prop = type.GetProperty(property);
|
var prop = type.GetProperty(property);
|
||||||
|
|
||||||
if (setter) // setter is prefix
|
if (setter) // setter is prefix
|
||||||
{
|
{
|
||||||
@ -128,15 +121,21 @@ namespace UnityExplorer.UI.Utility
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_currentlySettingCursor = true;
|
m_currentlySettingCursor = true;
|
||||||
if (ShouldForceMouse)
|
if (ShouldActuallyUnlock)
|
||||||
{
|
{
|
||||||
Cursor.lockState = CursorLockMode.None;
|
Cursor.lockState = CursorLockMode.None;
|
||||||
Cursor.visible = true;
|
Cursor.visible = true;
|
||||||
|
|
||||||
|
if (UIManager.EventSys)
|
||||||
|
SetEventSystem();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Cursor.lockState = m_lastLockMode;
|
Cursor.lockState = m_lastLockMode;
|
||||||
Cursor.visible = m_lastVisibleState;
|
Cursor.visible = m_lastVisibleState;
|
||||||
|
|
||||||
|
if (UIManager.EventSys)
|
||||||
|
ReleaseEventSystem();
|
||||||
}
|
}
|
||||||
m_currentlySettingCursor = false;
|
m_currentlySettingCursor = false;
|
||||||
}
|
}
|
||||||
@ -202,12 +201,10 @@ namespace UnityExplorer.UI.Utility
|
|||||||
m_lastEventSystem = value;
|
m_lastEventSystem = value;
|
||||||
m_lastInputModule = value?.currentInputModule;
|
m_lastInputModule = value?.currentInputModule;
|
||||||
|
|
||||||
if (UIManager.ShowMenu)
|
if (ShouldActuallyUnlock)
|
||||||
{
|
|
||||||
value = UIManager.EventSys;
|
value = UIManager.EventSys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Force mouse to stay unlocked and visible while UnlockMouse and ShowMenu are true.
|
// Force mouse to stay unlocked and visible while UnlockMouse and ShowMenu are true.
|
||||||
// Also keep track of when anything else tries to set Cursor state, this will be the
|
// Also keep track of when anything else tries to set Cursor state, this will be the
|
||||||
@ -220,12 +217,10 @@ namespace UnityExplorer.UI.Utility
|
|||||||
{
|
{
|
||||||
m_lastLockMode = value;
|
m_lastLockMode = value;
|
||||||
|
|
||||||
if (ShouldForceMouse)
|
if (ShouldActuallyUnlock)
|
||||||
{
|
|
||||||
value = CursorLockMode.None;
|
value = CursorLockMode.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
public static void Prefix_set_visible(ref bool value)
|
public static void Prefix_set_visible(ref bool value)
|
||||||
@ -234,11 +229,9 @@ namespace UnityExplorer.UI.Utility
|
|||||||
{
|
{
|
||||||
m_lastVisibleState = value;
|
m_lastVisibleState = value;
|
||||||
|
|
||||||
if (ShouldForceMouse)
|
if (ShouldActuallyUnlock)
|
||||||
{
|
|
||||||
value = true;
|
value = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -56,6 +56,8 @@ namespace UnityExplorer.Core.Input
|
|||||||
m_inputModule = new NoInput();
|
m_inputModule = new NoInput();
|
||||||
CurrentType = InputType.None;
|
CurrentType = InputType.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CursorUnlocker.Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,138 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityExplorer.Core.Unity;
|
|
||||||
using UnityExplorer.UI;
|
|
||||||
using UnityExplorer.UI.Main;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityExplorer.Core.Inspectors.Reflection;
|
|
||||||
using UnityExplorer.Core.Runtime;
|
|
||||||
using UnityExplorer.UI.Main.Home;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors
|
|
||||||
{
|
|
||||||
public class InspectorManager
|
|
||||||
{
|
|
||||||
public static InspectorManager Instance { get; private set; }
|
|
||||||
|
|
||||||
internal static InspectorManagerUI UI;
|
|
||||||
|
|
||||||
public InspectorManager()
|
|
||||||
{
|
|
||||||
Instance = this;
|
|
||||||
|
|
||||||
UI = new InspectorManagerUI();
|
|
||||||
UI.ConstructInspectorPane();
|
|
||||||
}
|
|
||||||
|
|
||||||
public InspectorBase m_activeInspector;
|
|
||||||
public readonly List<InspectorBase> m_currentInspectors = new List<InspectorBase>();
|
|
||||||
|
|
||||||
public void Update()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_currentInspectors.Count; i++)
|
|
||||||
{
|
|
||||||
if (i >= m_currentInspectors.Count)
|
|
||||||
break;
|
|
||||||
|
|
||||||
m_currentInspectors[i].Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Inspect(object obj, CacheObjectBase parentMember = null)
|
|
||||||
{
|
|
||||||
obj = ReflectionProvider.Instance.Cast(obj, ReflectionProvider.Instance.GetActualType(obj));
|
|
||||||
|
|
||||||
UnityEngine.Object unityObj = obj as UnityEngine.Object;
|
|
||||||
|
|
||||||
if (obj.IsNullOrDestroyed(false))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if currently inspecting this object
|
|
||||||
foreach (InspectorBase tab in m_currentInspectors)
|
|
||||||
{
|
|
||||||
if (ReferenceEquals(obj, tab.Target))
|
|
||||||
{
|
|
||||||
SetInspectorTab(tab);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if CPP
|
|
||||||
else if (unityObj && tab.Target is UnityEngine.Object uTabObj)
|
|
||||||
{
|
|
||||||
if (unityObj.m_CachedPtr == uTabObj.m_CachedPtr)
|
|
||||||
{
|
|
||||||
SetInspectorTab(tab);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
InspectorBase inspector;
|
|
||||||
if (obj is GameObject go)
|
|
||||||
inspector = new GameObjectInspector(go);
|
|
||||||
else
|
|
||||||
inspector = new InstanceInspector(obj);
|
|
||||||
|
|
||||||
if (inspector is ReflectionInspector ri)
|
|
||||||
ri.ParentMember = parentMember;
|
|
||||||
|
|
||||||
m_currentInspectors.Add(inspector);
|
|
||||||
SetInspectorTab(inspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Inspect(Type type)
|
|
||||||
{
|
|
||||||
if (type == null)
|
|
||||||
{
|
|
||||||
ExplorerCore.LogWarning("The provided type was null!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var tab in m_currentInspectors.Where(x => x is StaticInspector))
|
|
||||||
{
|
|
||||||
if (ReferenceEquals(tab.Target as Type, type))
|
|
||||||
{
|
|
||||||
SetInspectorTab(tab);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var inspector = new StaticInspector(type);
|
|
||||||
|
|
||||||
m_currentInspectors.Add(inspector);
|
|
||||||
SetInspectorTab(inspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetInspectorTab(InspectorBase inspector)
|
|
||||||
{
|
|
||||||
MainMenu.Instance.SetPage(HomePage.Instance);
|
|
||||||
|
|
||||||
if (m_activeInspector == inspector)
|
|
||||||
return;
|
|
||||||
|
|
||||||
UnsetInspectorTab();
|
|
||||||
|
|
||||||
m_activeInspector = inspector;
|
|
||||||
inspector.SetActive();
|
|
||||||
|
|
||||||
UI.OnSetInspectorTab(inspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UnsetInspectorTab()
|
|
||||||
{
|
|
||||||
if (m_activeInspector == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_activeInspector.SetInactive();
|
|
||||||
|
|
||||||
UI.OnUnsetInspectorTab();
|
|
||||||
|
|
||||||
m_activeInspector = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityExplorer.UI;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityExplorer.Core.Runtime;
|
|
||||||
using UnityExplorer.Core.Unity;
|
|
||||||
using UnityExplorer.UI.Main.Home.Inspectors;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors
|
|
||||||
{
|
|
||||||
public class GameObjectInspector : InspectorBase
|
|
||||||
{
|
|
||||||
public override string TabLabel => $" <color=cyan>[G]</color> {TargetGO?.name}";
|
|
||||||
|
|
||||||
public static GameObjectInspector ActiveInstance { get; private set; }
|
|
||||||
|
|
||||||
public GameObject TargetGO;
|
|
||||||
|
|
||||||
public GameObjectInspectorUI UIModule;
|
|
||||||
|
|
||||||
// sub modules
|
|
||||||
internal static ChildList s_childList;
|
|
||||||
internal static ComponentList s_compList;
|
|
||||||
internal static GameObjectControls s_controls;
|
|
||||||
|
|
||||||
internal static bool m_UIConstructed;
|
|
||||||
|
|
||||||
public GameObjectInspector(GameObject target) : base(target)
|
|
||||||
{
|
|
||||||
ActiveInstance = this;
|
|
||||||
|
|
||||||
TargetGO = target;
|
|
||||||
|
|
||||||
if (!TargetGO)
|
|
||||||
{
|
|
||||||
ExplorerCore.LogWarning("Target GameObject is null!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// one UI is used for all gameobject inspectors. no point recreating it.
|
|
||||||
if (!m_UIConstructed)
|
|
||||||
{
|
|
||||||
m_UIConstructed = true;
|
|
||||||
|
|
||||||
s_childList = new ChildList();
|
|
||||||
s_compList = new ComponentList();
|
|
||||||
s_controls = new GameObjectControls();
|
|
||||||
|
|
||||||
UIModule.ConstructUI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetActive()
|
|
||||||
{
|
|
||||||
base.SetActive();
|
|
||||||
ActiveInstance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetInactive()
|
|
||||||
{
|
|
||||||
base.SetInactive();
|
|
||||||
ActiveInstance = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ChangeInspectorTarget(GameObject newTarget)
|
|
||||||
{
|
|
||||||
if (!newTarget)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.Target = this.TargetGO = newTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update
|
|
||||||
|
|
||||||
public override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
if (m_pendingDestroy || !this.IsActive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
UIModule.RefreshTopInfo();
|
|
||||||
|
|
||||||
s_childList.RefreshChildObjectList();
|
|
||||||
|
|
||||||
s_compList.RefreshComponentList();
|
|
||||||
|
|
||||||
s_controls.RefreshControls();
|
|
||||||
|
|
||||||
if (GameObjectControls.s_sliderChangedWanted)
|
|
||||||
GameObjectControls.UpdateSliderControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CreateUIModule()
|
|
||||||
{
|
|
||||||
base.BaseUI = UIModule = new GameObjectInspectorUI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,184 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.EventSystems;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityExplorer.Core;
|
|
||||||
using UnityExplorer.Core.Unity;
|
|
||||||
using UnityExplorer.Core.Input;
|
|
||||||
using UnityExplorer.Core.Runtime;
|
|
||||||
using UnityExplorer.UI;
|
|
||||||
using UnityExplorer.UI.Main;
|
|
||||||
using UnityExplorer.UI.Main.Home.Inspectors;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors
|
|
||||||
{
|
|
||||||
public class InspectUnderMouse
|
|
||||||
{
|
|
||||||
public enum MouseInspectMode
|
|
||||||
{
|
|
||||||
World,
|
|
||||||
UI
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool Enabled { get; set; }
|
|
||||||
|
|
||||||
public static MouseInspectMode Mode { get; set; }
|
|
||||||
|
|
||||||
private static GameObject s_lastHit;
|
|
||||||
private static Vector3 s_lastMousePos;
|
|
||||||
|
|
||||||
internal static MouseInspectorUI UI;
|
|
||||||
|
|
||||||
static InspectUnderMouse()
|
|
||||||
{
|
|
||||||
UI = new MouseInspectorUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void StartInspect()
|
|
||||||
{
|
|
||||||
Enabled = true;
|
|
||||||
MainMenu.Instance.MainPanel.SetActive(false);
|
|
||||||
|
|
||||||
UI.s_UIContent.SetActive(true);
|
|
||||||
|
|
||||||
// recache Graphic Raycasters each time we start
|
|
||||||
var casters = RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(GraphicRaycaster));
|
|
||||||
m_gCasters = new GraphicRaycaster[casters.Length];
|
|
||||||
for (int i = 0; i < casters.Length; i++)
|
|
||||||
{
|
|
||||||
m_gCasters[i] = casters[i].Cast(typeof(GraphicRaycaster)) as GraphicRaycaster;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void StopInspect()
|
|
||||||
{
|
|
||||||
Enabled = false;
|
|
||||||
MainMenu.Instance.MainPanel.SetActive(true);
|
|
||||||
UI.s_UIContent.SetActive(false);
|
|
||||||
|
|
||||||
ClearHitData();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static GraphicRaycaster[] m_gCasters;
|
|
||||||
|
|
||||||
public static void UpdateInspect()
|
|
||||||
{
|
|
||||||
if (InputManager.GetKeyDown(KeyCode.Escape))
|
|
||||||
{
|
|
||||||
StopInspect();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var mousePos = InputManager.MousePosition;
|
|
||||||
|
|
||||||
if (mousePos != s_lastMousePos)
|
|
||||||
UpdatePosition(mousePos);
|
|
||||||
|
|
||||||
if (!UnityHelper.MainCamera)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// actual inspect raycast
|
|
||||||
|
|
||||||
switch (Mode)
|
|
||||||
{
|
|
||||||
case MouseInspectMode.UI:
|
|
||||||
RaycastUI(mousePos); break;
|
|
||||||
case MouseInspectMode.World:
|
|
||||||
RaycastWorld(mousePos); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void OnHitGameObject(GameObject obj)
|
|
||||||
{
|
|
||||||
if (obj != s_lastHit)
|
|
||||||
{
|
|
||||||
s_lastHit = obj;
|
|
||||||
UI.s_objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
|
|
||||||
UI.s_objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InputManager.GetMouseButtonDown(0))
|
|
||||||
{
|
|
||||||
StopInspect();
|
|
||||||
InspectorManager.Instance.Inspect(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void RaycastWorld(Vector2 mousePos)
|
|
||||||
{
|
|
||||||
var ray = UnityHelper.MainCamera.ScreenPointToRay(mousePos);
|
|
||||||
Physics.Raycast(ray, out RaycastHit hit, 1000f);
|
|
||||||
|
|
||||||
if (hit.transform)
|
|
||||||
{
|
|
||||||
var obj = hit.transform.gameObject;
|
|
||||||
OnHitGameObject(obj);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (s_lastHit)
|
|
||||||
ClearHitData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void RaycastUI(Vector2 mousePos)
|
|
||||||
{
|
|
||||||
var ped = new PointerEventData(null)
|
|
||||||
{
|
|
||||||
position = mousePos
|
|
||||||
};
|
|
||||||
|
|
||||||
#if MONO
|
|
||||||
var list = new List<RaycastResult>();
|
|
||||||
#else
|
|
||||||
var list = new Il2CppSystem.Collections.Generic.List<RaycastResult>();
|
|
||||||
#endif
|
|
||||||
foreach (var gr in m_gCasters)
|
|
||||||
{
|
|
||||||
gr.Raycast(ped, list);
|
|
||||||
|
|
||||||
if (list.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var hit in list)
|
|
||||||
{
|
|
||||||
if (hit.gameObject)
|
|
||||||
{
|
|
||||||
var obj = hit.gameObject;
|
|
||||||
|
|
||||||
OnHitGameObject(obj);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (s_lastHit)
|
|
||||||
ClearHitData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void UpdatePosition(Vector2 mousePos)
|
|
||||||
{
|
|
||||||
s_lastMousePos = mousePos;
|
|
||||||
|
|
||||||
var inversePos = UIManager.CanvasRoot.transform.InverseTransformPoint(mousePos);
|
|
||||||
|
|
||||||
UI.s_mousePosLabel.text = $"<color=grey>Mouse Position:</color> {mousePos.ToString()}";
|
|
||||||
|
|
||||||
float yFix = mousePos.y < 120 ? 80 : -80;
|
|
||||||
UI.s_UIContent.transform.localPosition = new Vector3(inversePos.x, inversePos.y + yFix, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void ClearHitData()
|
|
||||||
{
|
|
||||||
s_lastHit = null;
|
|
||||||
UI.s_objNameLabel.text = "No hits...";
|
|
||||||
UI.s_objPathLabel.text = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityExplorer.UI;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using System.IO;
|
|
||||||
using UnityExplorer.Core.Runtime;
|
|
||||||
using UnityExplorer.UI.Main.Home.Inspectors;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
|
||||||
{
|
|
||||||
public enum MemberScopes
|
|
||||||
{
|
|
||||||
All,
|
|
||||||
Instance,
|
|
||||||
Static
|
|
||||||
}
|
|
||||||
|
|
||||||
public class InstanceInspector : ReflectionInspector
|
|
||||||
{
|
|
||||||
public override string TabLabel => $" <color=cyan>[R]</color> {base.TabLabel}";
|
|
||||||
|
|
||||||
internal MemberScopes m_scopeFilter;
|
|
||||||
internal Button m_lastActiveScopeButton;
|
|
||||||
|
|
||||||
public InstanceInspector(object target) : base(target) { }
|
|
||||||
|
|
||||||
internal InstanceInspectorUI InstanceUI;
|
|
||||||
public void CreateInstanceUIModule()
|
|
||||||
{
|
|
||||||
InstanceUI = new InstanceInspectorUI(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void OnScopeFilterClicked(MemberScopes type, Button button)
|
|
||||||
{
|
|
||||||
if (m_lastActiveScopeButton)
|
|
||||||
{
|
|
||||||
var lastColors = m_lastActiveScopeButton.colors;
|
|
||||||
lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
|
|
||||||
m_lastActiveScopeButton.colors = lastColors;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_scopeFilter = type;
|
|
||||||
m_lastActiveScopeButton = button;
|
|
||||||
|
|
||||||
var colors = m_lastActiveScopeButton.colors;
|
|
||||||
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
|
|
||||||
m_lastActiveScopeButton.colors = colors;
|
|
||||||
|
|
||||||
FilterMembers(null, true);
|
|
||||||
base.ReflectionUI.m_sliderScroller.m_slider.value = 1f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,7 +11,7 @@ namespace UnityExplorer.Core
|
|||||||
{
|
{
|
||||||
public static class ReflectionUtility
|
public static class ReflectionUtility
|
||||||
{
|
{
|
||||||
public static BF CommonFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static;
|
public const BF AllFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper for IL2CPP to get the underlying true Type (Unhollowed) of the object.
|
/// Helper for IL2CPP to get the underlying true Type (Unhollowed) of the object.
|
||||||
@ -32,7 +32,7 @@ namespace UnityExplorer.Core
|
|||||||
/// <param name="obj">The object to cast</param>
|
/// <param name="obj">The object to cast</param>
|
||||||
/// <returns>The object, cast to the underlying Type if possible, otherwise the original object.</returns>
|
/// <returns>The object, cast to the underlying Type if possible, otherwise the original object.</returns>
|
||||||
public static object Cast(this object obj)
|
public static object Cast(this object obj)
|
||||||
=> Cast(obj, GetType(obj));
|
=> ReflectionProvider.Instance.Cast(obj, GetType(obj));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cast an object to a Type, if possible.
|
/// Cast an object to a Type, if possible.
|
||||||
@ -59,7 +59,10 @@ namespace UnityExplorer.Core
|
|||||||
public static bool IsDictionary(this Type t)
|
public static bool IsDictionary(this Type t)
|
||||||
=> ReflectionProvider.Instance.IsAssignableFrom(typeof(IDictionary), t);
|
=> ReflectionProvider.Instance.IsAssignableFrom(typeof(IDictionary), t);
|
||||||
|
|
||||||
public static bool LoadModule(string module)
|
/// <summary>
|
||||||
|
/// [INTERNAL] Used to load Unhollowed DLLs in IL2CPP.
|
||||||
|
/// </summary>
|
||||||
|
internal static bool LoadModule(string module)
|
||||||
=> ReflectionProvider.Instance.LoadModule(module);
|
=> ReflectionProvider.Instance.LoadModule(module);
|
||||||
|
|
||||||
// cache for GetTypeByName
|
// cache for GetTypeByName
|
||||||
@ -160,6 +163,32 @@ namespace UnityExplorer.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static Dictionary<Type, Dictionary<string, FieldInfo>> s_cachedFieldInfos = new Dictionary<Type, Dictionary<string, FieldInfo>>();
|
||||||
|
|
||||||
|
public static FieldInfo GetFieldInfo(Type type, string fieldName)
|
||||||
|
{
|
||||||
|
if (!s_cachedFieldInfos.ContainsKey(type))
|
||||||
|
s_cachedFieldInfos.Add(type, new Dictionary<string, FieldInfo>());
|
||||||
|
|
||||||
|
if (!s_cachedFieldInfos[type].ContainsKey(fieldName))
|
||||||
|
s_cachedFieldInfos[type].Add(fieldName, type.GetField(fieldName, AllFlags));
|
||||||
|
|
||||||
|
return s_cachedFieldInfos[type][fieldName];
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Dictionary<Type, Dictionary<string, PropertyInfo>> s_cachedPropInfos = new Dictionary<Type, Dictionary<string, PropertyInfo>>();
|
||||||
|
|
||||||
|
public static PropertyInfo GetPropertyInfo(Type type, string propertyName)
|
||||||
|
{
|
||||||
|
if (!s_cachedPropInfos.ContainsKey(type))
|
||||||
|
s_cachedPropInfos.Add(type, new Dictionary<string, PropertyInfo>());
|
||||||
|
|
||||||
|
if (!s_cachedPropInfos[type].ContainsKey(propertyName))
|
||||||
|
s_cachedPropInfos[type].Add(propertyName, type.GetProperty(propertyName, AllFlags));
|
||||||
|
|
||||||
|
return s_cachedPropInfos[type][propertyName];
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper to display a simple "{ExceptionType}: {Message}" of the exception, and optionally use the inner-most exception.
|
/// Helper to display a simple "{ExceptionType}: {Message}" of the exception, and optionally use the inner-most exception.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
||||||
@ -9,6 +10,9 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")]
|
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")]
|
||||||
public static class ICallManager
|
public static class ICallManager
|
||||||
{
|
{
|
||||||
|
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
|
public static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name);
|
||||||
|
|
||||||
private static readonly Dictionary<string, Delegate> iCallCache = new Dictionary<string, Delegate>();
|
private static readonly Dictionary<string, Delegate> iCallCache = new Dictionary<string, Delegate>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -26,9 +30,7 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
IntPtr ptr = il2cpp_resolve_icall(signature);
|
IntPtr ptr = il2cpp_resolve_icall(signature);
|
||||||
|
|
||||||
if (ptr == IntPtr.Zero)
|
if (ptr == IntPtr.Zero)
|
||||||
{
|
throw new MissingMethodException($"Could not find any iCall with the signature '{signature}'!");
|
||||||
throw new MissingMethodException($"Could not resolve internal call by name '{signature}'!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Delegate iCall = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
|
Delegate iCall = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
|
||||||
iCallCache.Add(signature, iCall);
|
iCallCache.Add(signature, iCall);
|
||||||
@ -36,8 +38,35 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
return (T)iCall;
|
return (T)iCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
private static readonly Dictionary<string, Delegate> s_unreliableCache = new Dictionary<string, Delegate>();
|
||||||
public static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name);
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get an iCall which may be one of multiple different signatures (ie, it changed in different Unity versions).
|
||||||
|
/// Each possible signature must have the same Type pattern, it can only vary by name.
|
||||||
|
/// </summary>
|
||||||
|
public static T GetICallUnreliable<T>(IEnumerable<string> possibleSignatures) where T : Delegate
|
||||||
|
{
|
||||||
|
// use the first possible signature as the 'key'.
|
||||||
|
string key = possibleSignatures.First();
|
||||||
|
|
||||||
|
if (s_unreliableCache.ContainsKey(key))
|
||||||
|
return (T)s_unreliableCache[key];
|
||||||
|
|
||||||
|
T iCall;
|
||||||
|
IntPtr ptr;
|
||||||
|
foreach (var sig in possibleSignatures)
|
||||||
|
{
|
||||||
|
ptr = il2cpp_resolve_icall(sig);
|
||||||
|
if (ptr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
iCall = (T)Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
|
||||||
|
s_unreliableCache.Add(key, iCall);
|
||||||
|
return iCall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MissingMethodException($"Could not find any iCall from list of provided signatures starting with '{key}'!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
156
src/Core/Runtime/Il2Cpp/Il2CppCoroutine.cs
Normal file
156
src/Core/Runtime/Il2Cpp/Il2CppCoroutine.cs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#if CPP
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnhollowerBaseLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
// CREDIT HerpDerpenstine
|
||||||
|
// https://github.com/LavaGang/MelonLoader/blob/master/MelonLoader.Support.Il2Cpp/MelonCoroutines.cs
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
||||||
|
{
|
||||||
|
public static class Il2CppCoroutine
|
||||||
|
{
|
||||||
|
private struct CoroTuple
|
||||||
|
{
|
||||||
|
public object WaitCondition;
|
||||||
|
public IEnumerator Coroutine;
|
||||||
|
}
|
||||||
|
private static readonly List<CoroTuple> ourCoroutinesStore = new List<CoroTuple>();
|
||||||
|
private static readonly List<IEnumerator> ourNextFrameCoroutines = new List<IEnumerator>();
|
||||||
|
private static readonly List<IEnumerator> ourWaitForFixedUpdateCoroutines = new List<IEnumerator>();
|
||||||
|
private static readonly List<IEnumerator> ourWaitForEndOfFrameCoroutines = new List<IEnumerator>();
|
||||||
|
|
||||||
|
private static readonly List<IEnumerator> tempList = new List<IEnumerator>();
|
||||||
|
|
||||||
|
internal static object Start(IEnumerator routine)
|
||||||
|
{
|
||||||
|
if (routine != null) ProcessNextOfCoroutine(routine);
|
||||||
|
return routine;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Stop(IEnumerator enumerator)
|
||||||
|
{
|
||||||
|
if (ourNextFrameCoroutines.Contains(enumerator)) // the coroutine is running itself
|
||||||
|
ourNextFrameCoroutines.Remove(enumerator);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int coroTupleIndex = ourCoroutinesStore.FindIndex(c => c.Coroutine == enumerator);
|
||||||
|
if (coroTupleIndex != -1) // the coroutine is waiting for a subroutine
|
||||||
|
{
|
||||||
|
object waitCondition = ourCoroutinesStore[coroTupleIndex].WaitCondition;
|
||||||
|
if (waitCondition is IEnumerator waitEnumerator)
|
||||||
|
Stop(waitEnumerator);
|
||||||
|
|
||||||
|
ourCoroutinesStore.RemoveAt(coroTupleIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessCoroList(List<IEnumerator> target)
|
||||||
|
{
|
||||||
|
if (target.Count == 0) return;
|
||||||
|
|
||||||
|
// use a temp list to make sure waits made during processing are not handled by same processing invocation
|
||||||
|
// additionally, a temp list reduces allocations compared to an array
|
||||||
|
tempList.AddRange(target);
|
||||||
|
target.Clear();
|
||||||
|
foreach (var enumerator in tempList) ProcessNextOfCoroutine(enumerator);
|
||||||
|
tempList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Process()
|
||||||
|
{
|
||||||
|
for (var i = ourCoroutinesStore.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var tuple = ourCoroutinesStore[i];
|
||||||
|
if (tuple.WaitCondition is WaitForSeconds waitForSeconds)
|
||||||
|
{
|
||||||
|
if ((waitForSeconds.m_Seconds -= Time.deltaTime) <= 0)
|
||||||
|
{
|
||||||
|
ourCoroutinesStore.RemoveAt(i);
|
||||||
|
ProcessNextOfCoroutine(tuple.Coroutine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessCoroList(ourNextFrameCoroutines);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void ProcessWaitForFixedUpdate() => ProcessCoroList(ourWaitForFixedUpdateCoroutines);
|
||||||
|
|
||||||
|
internal static void ProcessWaitForEndOfFrame() => ProcessCoroList(ourWaitForEndOfFrameCoroutines);
|
||||||
|
|
||||||
|
private static void ProcessNextOfCoroutine(IEnumerator enumerator)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!enumerator.MoveNext()) // Run the next step of the coroutine. If it's done, restore the parent routine
|
||||||
|
{
|
||||||
|
var indices = ourCoroutinesStore.Select((it, idx) => (idx, it)).Where(it => it.it.WaitCondition == enumerator).Select(it => it.idx).ToList();
|
||||||
|
for (var i = indices.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var index = indices[i];
|
||||||
|
ourNextFrameCoroutines.Add(ourCoroutinesStore[index].Coroutine);
|
||||||
|
ourCoroutinesStore.RemoveAt(index);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ExplorerCore.LogError(e.ToString());
|
||||||
|
Stop(FindOriginalCoro(enumerator)); // We want the entire coroutine hierachy to stop when an error happen
|
||||||
|
}
|
||||||
|
|
||||||
|
var next = enumerator.Current;
|
||||||
|
switch (next)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
ourNextFrameCoroutines.Add(enumerator);
|
||||||
|
return;
|
||||||
|
case WaitForFixedUpdate _:
|
||||||
|
ourWaitForFixedUpdateCoroutines.Add(enumerator);
|
||||||
|
return;
|
||||||
|
case WaitForEndOfFrame _:
|
||||||
|
ourWaitForEndOfFrameCoroutines.Add(enumerator);
|
||||||
|
return;
|
||||||
|
case WaitForSeconds _:
|
||||||
|
break; // do nothing, this one is supported in Process
|
||||||
|
case Il2CppObjectBase il2CppObjectBase:
|
||||||
|
var nextAsEnumerator = il2CppObjectBase.TryCast<Il2CppSystem.Collections.IEnumerator>();
|
||||||
|
if (nextAsEnumerator != null) // il2cpp IEnumerator also handles CustomYieldInstruction
|
||||||
|
next = new Il2CppEnumeratorWrapper(nextAsEnumerator);
|
||||||
|
else
|
||||||
|
ExplorerCore.LogWarning($"Unknown coroutine yield object of type {il2CppObjectBase} for coroutine {enumerator}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ourCoroutinesStore.Add(new CoroTuple { WaitCondition = next, Coroutine = enumerator });
|
||||||
|
|
||||||
|
if (next is IEnumerator nextCoro)
|
||||||
|
ProcessNextOfCoroutine(nextCoro);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerator FindOriginalCoro(IEnumerator enumerator)
|
||||||
|
{
|
||||||
|
int index = ourCoroutinesStore.FindIndex(ct => ct.WaitCondition == enumerator);
|
||||||
|
if (index == -1)
|
||||||
|
return enumerator;
|
||||||
|
return FindOriginalCoro(ourCoroutinesStore[index].Coroutine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Il2CppEnumeratorWrapper : IEnumerator
|
||||||
|
{
|
||||||
|
private readonly Il2CppSystem.Collections.IEnumerator il2cppEnumerator;
|
||||||
|
|
||||||
|
public Il2CppEnumeratorWrapper(Il2CppSystem.Collections.IEnumerator il2CppEnumerator) => il2cppEnumerator = il2CppEnumerator;
|
||||||
|
public bool MoveNext() => il2cppEnumerator.MoveNext();
|
||||||
|
public void Reset() => il2cppEnumerator.Reset();
|
||||||
|
public object Current => il2cppEnumerator.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -2,12 +2,18 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using BF = System.Reflection.BindingFlags;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnhollowerBaseLib;
|
using UnhollowerBaseLib;
|
||||||
using UnhollowerRuntimeLib;
|
using UnhollowerRuntimeLib;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Core.Input;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
||||||
{
|
{
|
||||||
@ -21,15 +27,37 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
|
|
||||||
public override void SetupEvents()
|
public override void SetupEvents()
|
||||||
{
|
{
|
||||||
Application.add_logMessageReceived(
|
try
|
||||||
new Action<string, string, LogType>(ExplorerCore.Instance.OnUnityLog));
|
{
|
||||||
|
//Application.add_logMessageReceived(new Action<string, string, LogType>(ExplorerCore.Instance.OnUnityLog));
|
||||||
|
|
||||||
//SceneManager.add_sceneLoaded(
|
var logType = ReflectionUtility.GetTypeByName("UnityEngine.Application+LogCallback");
|
||||||
// new Action<Scene, LoadSceneMode>(ExplorerCore.Instance.OnSceneLoaded1));
|
var castMethod = logType.GetMethod("op_Implicit", new[] { typeof(Action<string, string, LogType>) });
|
||||||
|
var addMethod = typeof(Application).GetMethod("add_logMessageReceived", BF.Static | BF.Public, null, new[] { logType }, null);
|
||||||
//SceneManager.add_activeSceneChanged(
|
addMethod.Invoke(null, new[]
|
||||||
// new Action<Scene, Scene>(ExplorerCore.Instance.OnSceneLoaded2));
|
{
|
||||||
|
castMethod.Invoke(null, new[] { new Action<string, string, LogType>(Application_logMessageReceived) })
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
ExplorerCore.LogWarning("Exception setting up Unity log listener, make sure Unity libraries have been unstripped!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
|
||||||
|
{
|
||||||
|
ExplorerCore.Log(condition, type, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void StartConsoleCoroutine(IEnumerator routine)
|
||||||
|
{
|
||||||
|
Il2CppCoroutine.Start(routine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unity API Handlers
|
||||||
|
|
||||||
|
// LayerMask.LayerToName
|
||||||
|
|
||||||
internal delegate IntPtr d_LayerToName(int layer);
|
internal delegate IntPtr d_LayerToName(int layer);
|
||||||
|
|
||||||
@ -39,27 +67,35 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
return IL2CPP.Il2CppStringToManaged(iCall.Invoke(layer));
|
return IL2CPP.Il2CppStringToManaged(iCall.Invoke(layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resources.FindObjectsOfTypeAll
|
||||||
|
|
||||||
internal delegate IntPtr d_FindObjectsOfTypeAll(IntPtr type);
|
internal delegate IntPtr d_FindObjectsOfTypeAll(IntPtr type);
|
||||||
|
|
||||||
public override UnityEngine.Object[] FindObjectsOfTypeAll(Type type)
|
public override UnityEngine.Object[] FindObjectsOfTypeAll(Type type)
|
||||||
{
|
{
|
||||||
var iCall = ICallManager.GetICall<d_FindObjectsOfTypeAll>("UnityEngine.Resources::FindObjectsOfTypeAll");
|
var iCall = ICallManager.GetICallUnreliable<d_FindObjectsOfTypeAll>(new[]
|
||||||
var cppType = Il2CppType.From(type);
|
{
|
||||||
|
"UnityEngine.Resources::FindObjectsOfTypeAll",
|
||||||
|
"UnityEngine.ResourcesAPIInternal::FindObjectsOfTypeAll" // Unity 2020+ updated to this
|
||||||
|
});
|
||||||
|
|
||||||
return new Il2CppReferenceArray<UnityEngine.Object>(iCall.Invoke(cppType.Pointer));
|
return new Il2CppReferenceArray<UnityEngine.Object>(iCall.Invoke(Il2CppType.From(type).Pointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetSceneHandle(Scene scene)
|
public override int GetSceneHandle(Scene scene)
|
||||||
=> scene.handle;
|
=> scene.handle;
|
||||||
|
|
||||||
//Scene.GetRootGameObjects();
|
// Scene.GetRootGameObjects();
|
||||||
|
|
||||||
internal delegate void d_GetRootGameObjects(int handle, IntPtr list);
|
internal delegate void d_GetRootGameObjects(int handle, IntPtr list);
|
||||||
|
|
||||||
public override GameObject[] GetRootGameObjects(Scene scene) => GetRootGameObjects(scene.handle);
|
public override GameObject[] GetRootGameObjects(Scene scene)
|
||||||
|
|
||||||
public static GameObject[] GetRootGameObjects(int handle)
|
|
||||||
{
|
{
|
||||||
|
if (!scene.isLoaded)
|
||||||
|
return new GameObject[0];
|
||||||
|
|
||||||
|
int handle = scene.handle;
|
||||||
|
|
||||||
if (handle == -1)
|
if (handle == -1)
|
||||||
return new GameObject[0];
|
return new GameObject[0];
|
||||||
|
|
||||||
@ -77,7 +113,7 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
return list.ToArray();
|
return list.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Scene.rootCount;
|
// Scene.rootCount
|
||||||
|
|
||||||
internal delegate int d_GetRootCountInternal(int handle);
|
internal delegate int d_GetRootCountInternal(int handle);
|
||||||
|
|
||||||
@ -88,10 +124,48 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
return ICallManager.GetICall<d_GetRootCountInternal>("UnityEngine.SceneManagement.Scene::GetRootCountInternal")
|
return ICallManager.GetICall<d_GetRootCountInternal>("UnityEngine.SceneManagement.Scene::GetRootCountInternal")
|
||||||
.Invoke(handle);
|
.Invoke(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool? s_doPropertiesExist;
|
||||||
|
|
||||||
|
public override ColorBlock SetColorBlock(ColorBlock colors, Color? normal = null, Color? highlighted = null, Color? pressed = null)
|
||||||
|
{
|
||||||
|
if (s_doPropertiesExist == null)
|
||||||
|
{
|
||||||
|
var prop = ReflectionUtility.GetPropertyInfo(typeof(ColorBlock), "normalColor") as PropertyInfo;
|
||||||
|
s_doPropertiesExist = prop != null && prop.CanWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
colors.colorMultiplier = 1;
|
||||||
|
|
||||||
|
object boxed = (object)colors;
|
||||||
|
|
||||||
|
if (s_doPropertiesExist == true)
|
||||||
|
{
|
||||||
|
if (normal != null)
|
||||||
|
ReflectionUtility.GetPropertyInfo(typeof(ColorBlock), "normalColor").SetValue(boxed, (Color)normal);
|
||||||
|
if (pressed != null)
|
||||||
|
ReflectionUtility.GetPropertyInfo(typeof(ColorBlock), "pressedColor").SetValue(boxed, (Color)pressed);
|
||||||
|
if (highlighted != null)
|
||||||
|
ReflectionUtility.GetPropertyInfo(typeof(ColorBlock), "highlightedColor").SetValue(boxed, (Color)highlighted);
|
||||||
|
}
|
||||||
|
else if (s_doPropertiesExist == false)
|
||||||
|
{
|
||||||
|
if (normal != null)
|
||||||
|
ReflectionUtility.GetFieldInfo(typeof(ColorBlock), "m_NormalColor").SetValue(boxed, (Color)normal);
|
||||||
|
if (pressed != null)
|
||||||
|
ReflectionUtility.GetFieldInfo(typeof(ColorBlock), "m_PressedColor").SetValue(boxed, (Color)pressed);
|
||||||
|
if (highlighted != null)
|
||||||
|
ReflectionUtility.GetFieldInfo(typeof(ColorBlock), "m_HighlightedColor").SetValue(boxed, (Color)highlighted);
|
||||||
|
}
|
||||||
|
|
||||||
|
colors = (ColorBlock)boxed;
|
||||||
|
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UnityEventExtensions
|
public static class Il2CppExtensions
|
||||||
{
|
{
|
||||||
public static void AddListener(this UnityEvent action, Action listener)
|
public static void AddListener(this UnityEvent action, Action listener)
|
||||||
{
|
{
|
||||||
@ -102,6 +176,9 @@ public static class UnityEventExtensions
|
|||||||
{
|
{
|
||||||
action.AddListener(listener);
|
action.AddListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetChildControlHeight(this HorizontalOrVerticalLayoutGroup group, bool value) => group.childControlHeight = value;
|
||||||
|
public static void SetChildControlWidth(this HorizontalOrVerticalLayoutGroup group, bool value) => group.childControlWidth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -5,7 +5,6 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnhollowerBaseLib;
|
using UnhollowerBaseLib;
|
||||||
using UnityExplorer.Core.Unity;
|
|
||||||
using UnhollowerRuntimeLib;
|
using UnhollowerRuntimeLib;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -109,6 +108,7 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
|
|
||||||
Type ret = Type.GetType(name);
|
Type ret = Type.GetType(name);
|
||||||
|
|
||||||
|
// Thanks to Slaynash for this deobfuscation snippet!
|
||||||
if (ret == null)
|
if (ret == null)
|
||||||
{
|
{
|
||||||
string baseName = cppType.FullName;
|
string baseName = cppType.FullName;
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
#if MONO
|
#if MONO
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.Core.CSharp;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Runtime.Mono
|
namespace UnityExplorer.Core.Runtime.Mono
|
||||||
{
|
{
|
||||||
@ -20,9 +24,17 @@ namespace UnityExplorer.Core.Runtime.Mono
|
|||||||
|
|
||||||
public override void SetupEvents()
|
public override void SetupEvents()
|
||||||
{
|
{
|
||||||
Application.logMessageReceived += ExplorerCore.Instance.OnUnityLog;
|
Application.logMessageReceived += Application_logMessageReceived;
|
||||||
//SceneManager.sceneLoaded += ExplorerCore.Instance.OnSceneLoaded1;
|
}
|
||||||
//SceneManager.activeSceneChanged += ExplorerCore.Instance.OnSceneLoaded2;
|
|
||||||
|
private void Application_logMessageReceived(string condition, string stackTrace, LogType type)
|
||||||
|
{
|
||||||
|
ExplorerCore.Log(condition, type, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void StartConsoleCoroutine(IEnumerator routine)
|
||||||
|
{
|
||||||
|
DummyBehaviour.Instance.StartCoroutine(routine);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string LayerToName(int layer)
|
public override string LayerToName(int layer)
|
||||||
@ -31,7 +43,7 @@ namespace UnityExplorer.Core.Runtime.Mono
|
|||||||
public override UnityEngine.Object[] FindObjectsOfTypeAll(Type type)
|
public override UnityEngine.Object[] FindObjectsOfTypeAll(Type type)
|
||||||
=> Resources.FindObjectsOfTypeAll(type);
|
=> Resources.FindObjectsOfTypeAll(type);
|
||||||
|
|
||||||
private static readonly FieldInfo fi_Scene_handle = typeof(Scene).GetField("m_Handle", ReflectionUtility.CommonFlags);
|
private static readonly FieldInfo fi_Scene_handle = typeof(Scene).GetField("m_Handle", ReflectionUtility.AllFlags);
|
||||||
|
|
||||||
public override int GetSceneHandle(Scene scene)
|
public override int GetSceneHandle(Scene scene)
|
||||||
{
|
{
|
||||||
@ -40,6 +52,9 @@ namespace UnityExplorer.Core.Runtime.Mono
|
|||||||
|
|
||||||
public override GameObject[] GetRootGameObjects(Scene scene)
|
public override GameObject[] GetRootGameObjects(Scene scene)
|
||||||
{
|
{
|
||||||
|
if (!scene.isLoaded)
|
||||||
|
return new GameObject[0];
|
||||||
|
|
||||||
return scene.GetRootGameObjects();
|
return scene.GetRootGameObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +62,58 @@ namespace UnityExplorer.Core.Runtime.Mono
|
|||||||
{
|
{
|
||||||
return scene.rootCount;
|
return scene.rootCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ColorBlock SetColorBlock(ColorBlock colors, Color? normal = null, Color? highlighted = null, Color? pressed = null)
|
||||||
|
{
|
||||||
|
if (normal != null)
|
||||||
|
colors.normalColor = (Color)normal;
|
||||||
|
|
||||||
|
if (highlighted != null)
|
||||||
|
colors.highlightedColor = (Color)highlighted;
|
||||||
|
|
||||||
|
if (pressed != null)
|
||||||
|
colors.pressedColor = (Color)pressed;
|
||||||
|
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MonoExtensions
|
||||||
|
{
|
||||||
|
public static void AddListener(this UnityEvent _event, Action listener)
|
||||||
|
{
|
||||||
|
_event.AddListener(new UnityAction(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddListener<T>(this UnityEvent<T> _event, Action<T> listener)
|
||||||
|
{
|
||||||
|
_event.AddListener(new UnityAction<T>(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Clear(this StringBuilder sb)
|
||||||
|
{
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PropertyInfo pi_childControlHeight;
|
||||||
|
|
||||||
|
public static void SetChildControlHeight(this HorizontalOrVerticalLayoutGroup group, bool value)
|
||||||
|
{
|
||||||
|
if (pi_childControlHeight == null)
|
||||||
|
pi_childControlHeight = group.GetType().GetProperty("childControlHeight");
|
||||||
|
|
||||||
|
pi_childControlHeight?.SetValue(group, value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PropertyInfo pi_childControlWidth;
|
||||||
|
|
||||||
|
public static void SetChildControlWidth(this HorizontalOrVerticalLayoutGroup group, bool value)
|
||||||
|
{
|
||||||
|
if (pi_childControlWidth == null)
|
||||||
|
pi_childControlWidth = group.GetType().GetProperty("childControlWidth");
|
||||||
|
|
||||||
|
pi_childControlWidth?.SetValue(group, value, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,9 +52,9 @@ namespace UnityExplorer.Core.Runtime.Mono
|
|||||||
private static MethodInfo GetEncodeToPNGMethod()
|
private static MethodInfo GetEncodeToPNGMethod()
|
||||||
{
|
{
|
||||||
if (ReflectionUtility.GetTypeByName("UnityEngine.ImageConversion") is Type imageConversion)
|
if (ReflectionUtility.GetTypeByName("UnityEngine.ImageConversion") is Type imageConversion)
|
||||||
return m_encodeToPNGMethod = imageConversion.GetMethod("EncodeToPNG", ReflectionUtility.CommonFlags);
|
return m_encodeToPNGMethod = imageConversion.GetMethod("EncodeToPNG", ReflectionUtility.AllFlags);
|
||||||
|
|
||||||
var method = typeof(Texture2D).GetMethod("EncodeToPNG", ReflectionUtility.CommonFlags);
|
var method = typeof(Texture2D).GetMethod("EncodeToPNG", ReflectionUtility.AllFlags);
|
||||||
if (method != null)
|
if (method != null)
|
||||||
return m_encodeToPNGMethod = method;
|
return m_encodeToPNGMethod = method;
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Runtime
|
namespace UnityExplorer.Core.Runtime
|
||||||
{
|
{
|
||||||
@ -36,6 +38,8 @@ namespace UnityExplorer.Core.Runtime
|
|||||||
|
|
||||||
public abstract void SetupEvents();
|
public abstract void SetupEvents();
|
||||||
|
|
||||||
|
public abstract void StartConsoleCoroutine(IEnumerator routine);
|
||||||
|
|
||||||
// Unity API handlers
|
// Unity API handlers
|
||||||
|
|
||||||
public abstract string LayerToName(int layer);
|
public abstract string LayerToName(int layer);
|
||||||
@ -47,5 +51,7 @@ namespace UnityExplorer.Core.Runtime
|
|||||||
public abstract GameObject[] GetRootGameObjects(Scene scene);
|
public abstract GameObject[] GetRootGameObjects(Scene scene);
|
||||||
|
|
||||||
public abstract int GetRootCount(Scene scene);
|
public abstract int GetRootCount(Scene scene);
|
||||||
|
|
||||||
|
public abstract ColorBlock SetColorBlock(ColorBlock colors, Color? normal = null, Color? highlighted = null, Color? pressed = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace UnityExplorer.Core.Runtime
|
|||||||
{
|
{
|
||||||
Color[] pixels;
|
Color[] pixels;
|
||||||
|
|
||||||
if (IsReadable(orig))
|
if (!IsReadable(orig))
|
||||||
orig = ForceReadTexture(orig);
|
orig = ForceReadTexture(orig);
|
||||||
|
|
||||||
pixels = orig.GetPixels((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
|
pixels = orig.GetPixels((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
|
||||||
|
@ -1,204 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityExplorer.UI;
|
|
||||||
using UnityExplorer.UI.Main;
|
|
||||||
using UnityExplorer.UI.Reusable;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityExplorer.Core.Runtime;
|
|
||||||
using UnityExplorer.UI.Main.Home;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors
|
|
||||||
{
|
|
||||||
public class SceneExplorer
|
|
||||||
{
|
|
||||||
public static SceneExplorer Instance;
|
|
||||||
|
|
||||||
public static SceneExplorerUI UI;
|
|
||||||
|
|
||||||
internal static Action OnToggleShow;
|
|
||||||
|
|
||||||
public SceneExplorer()
|
|
||||||
{
|
|
||||||
Instance = this;
|
|
||||||
|
|
||||||
UI = new SceneExplorerUI();
|
|
||||||
UI.ConstructScenePane();
|
|
||||||
}
|
|
||||||
|
|
||||||
private const float UPDATE_INTERVAL = 1f;
|
|
||||||
private float m_timeOfLastSceneUpdate;
|
|
||||||
|
|
||||||
// private int m_currentSceneHandle = -1;
|
|
||||||
public static Scene DontDestroyScene => DontDestroyObject.scene;
|
|
||||||
internal Scene m_currentScene;
|
|
||||||
internal Scene[] m_currentScenes = new Scene[0];
|
|
||||||
|
|
||||||
internal GameObject[] m_allObjects = new GameObject[0];
|
|
||||||
|
|
||||||
internal GameObject m_selectedSceneObject;
|
|
||||||
internal int m_lastCount;
|
|
||||||
|
|
||||||
internal static GameObject DontDestroyObject
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!s_dontDestroyObject)
|
|
||||||
{
|
|
||||||
s_dontDestroyObject = new GameObject("DontDestroyMe");
|
|
||||||
GameObject.DontDestroyOnLoad(s_dontDestroyObject);
|
|
||||||
}
|
|
||||||
return s_dontDestroyObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static GameObject s_dontDestroyObject;
|
|
||||||
|
|
||||||
public void Init()
|
|
||||||
{
|
|
||||||
RefreshSceneSelector();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update()
|
|
||||||
{
|
|
||||||
if (SceneExplorerUI.Hiding || Time.realtimeSinceStartup - m_timeOfLastSceneUpdate < UPDATE_INTERVAL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefreshSceneSelector();
|
|
||||||
|
|
||||||
if (!m_selectedSceneObject)
|
|
||||||
{
|
|
||||||
if (m_currentScene != default)
|
|
||||||
{
|
|
||||||
var rootObjects = RuntimeProvider.Instance.GetRootGameObjects(m_currentScene);
|
|
||||||
SetSceneObjectList(rootObjects);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RefreshSelectedSceneObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RefreshSceneSelector()
|
|
||||||
{
|
|
||||||
var newNames = new List<string>();
|
|
||||||
var newScenes = new List<Scene>();
|
|
||||||
|
|
||||||
if (m_currentScenes == null)
|
|
||||||
m_currentScenes = new Scene[0];
|
|
||||||
|
|
||||||
bool anyChange = SceneManager.sceneCount != m_currentScenes.Length - 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
||||||
{
|
|
||||||
Scene scene = SceneManager.GetSceneAt(i);
|
|
||||||
|
|
||||||
if (scene == default)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int handle = RuntimeProvider.Instance.GetSceneHandle(scene);
|
|
||||||
|
|
||||||
if (!anyChange && !m_currentScenes.Any(it => handle == RuntimeProvider.Instance.GetSceneHandle(it)))
|
|
||||||
anyChange = true;
|
|
||||||
|
|
||||||
newScenes.Add(scene);
|
|
||||||
newNames.Add(scene.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (anyChange)
|
|
||||||
{
|
|
||||||
newNames.Add("DontDestroyOnLoad");
|
|
||||||
newScenes.Add(DontDestroyScene);
|
|
||||||
m_currentScenes = newScenes.ToArray();
|
|
||||||
|
|
||||||
UI.OnActiveScenesChanged(newNames);
|
|
||||||
|
|
||||||
SetTargetScene(newScenes[0]);
|
|
||||||
|
|
||||||
SearchPage.Instance.OnSceneChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetTargetScene(int index)
|
|
||||||
=> SetTargetScene(m_currentScenes[index]);
|
|
||||||
|
|
||||||
public void SetTargetScene(Scene scene)
|
|
||||||
{
|
|
||||||
if (scene == default)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_currentScene = scene;
|
|
||||||
var rootObjs = RuntimeProvider.Instance.GetRootGameObjects(scene);
|
|
||||||
SetSceneObjectList(rootObjs);
|
|
||||||
|
|
||||||
m_selectedSceneObject = null;
|
|
||||||
|
|
||||||
UI.OnSceneSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetSceneObjectParent()
|
|
||||||
{
|
|
||||||
if (!m_selectedSceneObject || !m_selectedSceneObject.transform.parent?.gameObject)
|
|
||||||
{
|
|
||||||
m_selectedSceneObject = null;
|
|
||||||
SetTargetScene(m_currentScene);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetTargetObject(m_selectedSceneObject.transform.parent.gameObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetTargetObject(GameObject obj)
|
|
||||||
{
|
|
||||||
if (!obj)
|
|
||||||
return;
|
|
||||||
|
|
||||||
UI.OnGameObjectSelected(obj);
|
|
||||||
|
|
||||||
m_selectedSceneObject = obj;
|
|
||||||
|
|
||||||
RefreshSelectedSceneObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RefreshSelectedSceneObject()
|
|
||||||
{
|
|
||||||
GameObject[] list = new GameObject[m_selectedSceneObject.transform.childCount];
|
|
||||||
for (int i = 0; i < m_selectedSceneObject.transform.childCount; i++)
|
|
||||||
{
|
|
||||||
list[i] = m_selectedSceneObject.transform.GetChild(i).gameObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSceneObjectList(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetSceneObjectList(GameObject[] objects)
|
|
||||||
{
|
|
||||||
m_allObjects = objects;
|
|
||||||
RefreshSceneObjectList();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void RefreshSceneObjectList()
|
|
||||||
{
|
|
||||||
m_timeOfLastSceneUpdate = Time.realtimeSinceStartup;
|
|
||||||
|
|
||||||
UI.RefreshSceneObjectList(m_allObjects, out int newCount);
|
|
||||||
|
|
||||||
m_lastCount = newCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void InspectSelectedGameObject()
|
|
||||||
{
|
|
||||||
InspectorManager.Instance.Inspect(Instance.m_selectedSceneObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void InvokeOnToggleShow()
|
|
||||||
{
|
|
||||||
OnToggleShow?.Invoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace UnityExplorer.Search
|
namespace UnityExplorer.Core.Search
|
||||||
{
|
{
|
||||||
internal enum ChildFilter
|
internal enum ChildFilter
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace UnityExplorer.Search
|
namespace UnityExplorer.Core.Search
|
||||||
{
|
{
|
||||||
internal enum SceneFilter
|
internal enum SceneFilter
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace UnityExplorer.Search
|
namespace UnityExplorer.Core.Search
|
||||||
{
|
{
|
||||||
internal enum SearchContext
|
internal enum SearchContext
|
||||||
{
|
{
|
||||||
|
@ -4,11 +4,11 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityExplorer.Core;
|
|
||||||
using UnityExplorer.Core.Runtime;
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.UI.Main;
|
using UnityExplorer.UI.Main;
|
||||||
|
using UnityExplorer.UI.Main.Search;
|
||||||
|
|
||||||
namespace UnityExplorer.Search
|
namespace UnityExplorer.Core.Search
|
||||||
{
|
{
|
||||||
public static class SearchProvider
|
public static class SearchProvider
|
||||||
{
|
{
|
||||||
|
@ -1,290 +0,0 @@
|
|||||||
//using System.Collections;
|
|
||||||
//using System.Collections.Generic;
|
|
||||||
//using UnityExplorer.UI;
|
|
||||||
//using UnityEngine;
|
|
||||||
//using System;
|
|
||||||
//using System.Runtime.InteropServices;
|
|
||||||
//using System.Text;
|
|
||||||
//using UnityExplorer.Core.Runtime;
|
|
||||||
|
|
||||||
//namespace UnityExplorer.Core.Tests
|
|
||||||
//{
|
|
||||||
// internal enum TestByteEnum : byte
|
|
||||||
// {
|
|
||||||
// One,
|
|
||||||
// Two,
|
|
||||||
// Three,
|
|
||||||
// TwoFiftyFive = 255,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public static class StaticTestClass
|
|
||||||
// {
|
|
||||||
// public static int StaticProperty => 5;
|
|
||||||
// public static int StaticField = 69;
|
|
||||||
// public static List<string> StaticList = new List<string>
|
|
||||||
// {
|
|
||||||
// "one",
|
|
||||||
// "two",
|
|
||||||
// "three",
|
|
||||||
// };
|
|
||||||
// public static void StaticMethod() { }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public class TestClass
|
|
||||||
// {
|
|
||||||
// internal static TestByteEnum testingByte = TestByteEnum.One;
|
|
||||||
|
|
||||||
// public string AAALongString = @"1
|
|
||||||
//2
|
|
||||||
//3
|
|
||||||
//4
|
|
||||||
//5";
|
|
||||||
|
|
||||||
// public Vector2 AATestVector2 = new Vector2(1, 2);
|
|
||||||
// public Vector3 AATestVector3 = new Vector3(1, 2, 3);
|
|
||||||
// public Vector4 AATestVector4 = new Vector4(1, 2, 3, 4);
|
|
||||||
// public Rect AATestRect = new Rect(1, 2, 3, 4);
|
|
||||||
// public Color AATestColor = new Color(0.1f, 0.2f, 0.3f, 0.4f);
|
|
||||||
|
|
||||||
// public bool ATestBoolMethod() => false;
|
|
||||||
|
|
||||||
// public bool this[int index]
|
|
||||||
// {
|
|
||||||
// get => index % 2 == 0;
|
|
||||||
// set => m_thisBool = value;
|
|
||||||
// }
|
|
||||||
// internal bool m_thisBool;
|
|
||||||
|
|
||||||
// static int testInt;
|
|
||||||
// public static List<string> ExceptionList
|
|
||||||
// {
|
|
||||||
// get
|
|
||||||
// {
|
|
||||||
// testInt++;
|
|
||||||
// if (testInt % 2 == 0)
|
|
||||||
// throw new Exception("its even");
|
|
||||||
// else
|
|
||||||
// return new List<string> { "one" };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static bool abool;
|
|
||||||
// public static bool ATestExceptionBool
|
|
||||||
// {
|
|
||||||
// get
|
|
||||||
// {
|
|
||||||
// abool = !abool;
|
|
||||||
// if (!abool)
|
|
||||||
// throw new Exception("false");
|
|
||||||
// else
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public static string ExceptionString => throw new NotImplementedException();
|
|
||||||
|
|
||||||
// public static string ANullString = null;
|
|
||||||
// public static float ATestFloat = 420.69f;
|
|
||||||
// public static int ATestInt = -1;
|
|
||||||
// public static string ATestString = "hello world";
|
|
||||||
// public static uint ATestUInt = 1u;
|
|
||||||
// public static byte ATestByte = 255;
|
|
||||||
// public static ulong AReadonlyUlong = 82934UL;
|
|
||||||
|
|
||||||
// public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
|
|
||||||
// private static TestClass m_instance;
|
|
||||||
|
|
||||||
// public object AmbigObject;
|
|
||||||
|
|
||||||
// public List<List<List<string>>> ANestedNestedList = new List<List<List<string>>>
|
|
||||||
// {
|
|
||||||
// new List<List<string>>
|
|
||||||
// {
|
|
||||||
// new List<string>
|
|
||||||
// {
|
|
||||||
// "one",
|
|
||||||
// "two",
|
|
||||||
// },
|
|
||||||
// new List<string>
|
|
||||||
// {
|
|
||||||
// "three",
|
|
||||||
// "four"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// new List<List<string>>
|
|
||||||
// {
|
|
||||||
// new List<string>
|
|
||||||
// {
|
|
||||||
// "five",
|
|
||||||
// "six"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// public static bool SetOnlyProperty
|
|
||||||
// {
|
|
||||||
// set => m_setOnlyProperty = value;
|
|
||||||
// }
|
|
||||||
// private static bool m_setOnlyProperty;
|
|
||||||
// public static bool ReadSetOnlyProperty => m_setOnlyProperty;
|
|
||||||
|
|
||||||
// public Texture2D TestTexture;
|
|
||||||
// public static Sprite TestSprite;
|
|
||||||
|
|
||||||
//#if CPP
|
|
||||||
// public static Il2CppSystem.Collections.Generic.HashSet<string> CppHashSetTest;
|
|
||||||
// public static Il2CppSystem.Collections.Generic.List<string> CppStringTest;
|
|
||||||
// public static Il2CppSystem.Collections.IList CppIList;
|
|
||||||
// //public static Il2CppSystem.Collections.Generic.Dictionary<string, string> CppDictTest;
|
|
||||||
// //public static Il2CppSystem.Collections.Generic.Dictionary<int, float> CppDictTest2;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
// public TestClass()
|
|
||||||
// {
|
|
||||||
// int a = 0;
|
|
||||||
// foreach (var list in ANestedNestedList)
|
|
||||||
// {
|
|
||||||
// foreach (var list2 in list)
|
|
||||||
// {
|
|
||||||
// for (int i = 0; i < 33; i++)
|
|
||||||
// list2.Add(a++.ToString());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//#if CPP
|
|
||||||
// //TextureSpriteTest();
|
|
||||||
|
|
||||||
// CppHashSetTest = new Il2CppSystem.Collections.Generic.HashSet<string>();
|
|
||||||
// CppHashSetTest.Add("1");
|
|
||||||
// CppHashSetTest.Add("2");
|
|
||||||
// CppHashSetTest.Add("3");
|
|
||||||
|
|
||||||
// CppStringTest = new Il2CppSystem.Collections.Generic.List<string>();
|
|
||||||
// CppStringTest.Add("1");
|
|
||||||
// CppStringTest.Add("2");
|
|
||||||
|
|
||||||
// //CppDictTest = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
|
|
||||||
// //CppDictTest.Add("key1", "value1");
|
|
||||||
// //CppDictTest.Add("key2", "value2");
|
|
||||||
// //CppDictTest.Add("key3", "value3");
|
|
||||||
|
|
||||||
// //CppDictTest2 = new Il2CppSystem.Collections.Generic.Dictionary<int, float>();
|
|
||||||
// //CppDictTest2.Add(0, 0.5f);
|
|
||||||
// //CppDictTest2.Add(1, 0.5f);
|
|
||||||
// //CppDictTest2.Add(2, 0.5f);
|
|
||||||
//#endif
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //private void TextureSpriteTest()
|
|
||||||
// //{
|
|
||||||
// // TestTexture = new Texture2D(32, 32, TextureFormat.ARGB32, false)
|
|
||||||
// // {
|
|
||||||
// // name = "TestTexture"
|
|
||||||
// // };
|
|
||||||
// // TestSprite = TextureUtilProvider.Instance.CreateSprite(TestTexture);
|
|
||||||
|
|
||||||
// // GameObject.DontDestroyOnLoad(TestTexture);
|
|
||||||
// // GameObject.DontDestroyOnLoad(TestSprite);
|
|
||||||
|
|
||||||
// // // test loading a tex from file
|
|
||||||
// // if (System.IO.File.Exists(@"D:\Downloads\test.png"))
|
|
||||||
// // {
|
|
||||||
// // var dataToLoad = System.IO.File.ReadAllBytes(@"D:\Downloads\test.png");
|
|
||||||
// // ExplorerCore.Log($"Tex load success: {TestTexture.LoadImage(dataToLoad, false)}");
|
|
||||||
// // }
|
|
||||||
// //}
|
|
||||||
|
|
||||||
// //public static string TestRefInOutGeneric<T>(ref string arg0, in int arg1, out string arg2) where T : Component
|
|
||||||
// //{
|
|
||||||
// // arg2 = "this is arg2";
|
|
||||||
|
|
||||||
// // return $"T: '{typeof(T).FullName}', ref arg0: '{arg0}', in arg1: '{arg1}', out arg2: '{arg2}'";
|
|
||||||
// //}
|
|
||||||
|
|
||||||
// // test a non-generic dictionary
|
|
||||||
|
|
||||||
// public Hashtable TestNonGenericDict()
|
|
||||||
// {
|
|
||||||
// return new Hashtable
|
|
||||||
// {
|
|
||||||
// { "One", 1 },
|
|
||||||
// { "Two", 2 },
|
|
||||||
// { "Three", 3 },
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // test HashSets
|
|
||||||
|
|
||||||
// public static HashSet<string> HashSetTest = new HashSet<string>
|
|
||||||
// {
|
|
||||||
// "One",
|
|
||||||
// "Two",
|
|
||||||
// "Three"
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
// // Test indexed parameter
|
|
||||||
|
|
||||||
// public string this[int arg0, string arg1]
|
|
||||||
// {
|
|
||||||
// get
|
|
||||||
// {
|
|
||||||
// return $"arg0: {arg0}, arg1: {arg1}";
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Test basic list
|
|
||||||
|
|
||||||
// public static List<string> TestList = new List<string>
|
|
||||||
// {
|
|
||||||
// "1",
|
|
||||||
// "2",
|
|
||||||
// "3",
|
|
||||||
// "etc..."
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Test a nested dictionary
|
|
||||||
|
|
||||||
// public static Dictionary<int, Dictionary<string, int>> NestedDictionary = new Dictionary<int, Dictionary<string, int>>
|
|
||||||
// {
|
|
||||||
// {
|
|
||||||
// 1,
|
|
||||||
// new Dictionary<string, int>
|
|
||||||
// {
|
|
||||||
// {
|
|
||||||
// "Sub 1", 123
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "Sub 2", 456
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// 2,
|
|
||||||
// new Dictionary<string, int>
|
|
||||||
// {
|
|
||||||
// {
|
|
||||||
// "Sub 3", 789
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// "Sub 4", 000
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Test a basic method
|
|
||||||
|
|
||||||
// public static Color TestMethod(float r, float g, float b, float a)
|
|
||||||
// {
|
|
||||||
// return new Color(r, g, b, a);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // A method with default arguments
|
|
||||||
|
|
||||||
// public static Vector3 TestDefaultArgs(float arg0, float arg1, float arg2 = 5.0f)
|
|
||||||
// {
|
|
||||||
// return new Vector3(arg0, arg1, arg2);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
@ -1,46 +0,0 @@
|
|||||||
using System.Globalization;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Unity
|
|
||||||
{
|
|
||||||
public static class ColorHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Converts Color to 6-digit RGB hex code (without # symbol). Eg, RGBA(1,0,0,1) -> FF0000
|
|
||||||
/// </summary>
|
|
||||||
public static string ToHex(this Color color)
|
|
||||||
{
|
|
||||||
byte r = (byte)Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255);
|
|
||||||
byte g = (byte)Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255);
|
|
||||||
byte b = (byte)Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255);
|
|
||||||
|
|
||||||
return $"{r:X2}{g:X2}{b:X2}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Assumes the string is a 6-digit RGB Hex color code, which it will parse into a UnityEngine.Color.
|
|
||||||
/// Eg, FF0000 -> RGBA(1,0,0,1)
|
|
||||||
/// </summary>
|
|
||||||
public static Color ToColor(this string _string)
|
|
||||||
{
|
|
||||||
_string = _string.Replace("#", "");
|
|
||||||
|
|
||||||
if (_string.Length != 6)
|
|
||||||
return Color.magenta;
|
|
||||||
|
|
||||||
var r = byte.Parse(_string.Substring(0, 2), NumberStyles.HexNumber);
|
|
||||||
var g = byte.Parse(_string.Substring(2, 2), NumberStyles.HexNumber);
|
|
||||||
var b = byte.Parse(_string.Substring(4, 2), NumberStyles.HexNumber);
|
|
||||||
|
|
||||||
var color = new Color
|
|
||||||
{
|
|
||||||
r = (float)(r / (decimal)255),
|
|
||||||
g = (float)(g / (decimal)255),
|
|
||||||
b = (float)(b / (decimal)255),
|
|
||||||
a = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Unity
|
|
||||||
{
|
|
||||||
public static class UnityHelper
|
|
||||||
{
|
|
||||||
private static Camera m_mainCamera;
|
|
||||||
|
|
||||||
public static Camera MainCamera
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!m_mainCamera)
|
|
||||||
{
|
|
||||||
m_mainCamera = Camera.main;
|
|
||||||
}
|
|
||||||
return m_mainCamera;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = true)
|
|
||||||
{
|
|
||||||
var unityObj = obj as Object;
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
if (!suppressWarning)
|
|
||||||
ExplorerCore.LogWarning("The target instance is null!");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (obj is Object)
|
|
||||||
{
|
|
||||||
if (!unityObj)
|
|
||||||
{
|
|
||||||
if (!suppressWarning)
|
|
||||||
ExplorerCore.LogWarning("The target UnityEngine.Object was destroyed!");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ToStringLong(this Vector3 vec)
|
|
||||||
{
|
|
||||||
return $"{vec.x:F3}, {vec.y:F3}, {vec.z:F3}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetTransformPath(this Transform t, bool includeThisName = false)
|
|
||||||
{
|
|
||||||
string path = includeThisName ? t.transform.name : "";
|
|
||||||
|
|
||||||
while (t.parent != null)
|
|
||||||
{
|
|
||||||
t = t.parent;
|
|
||||||
path = $"{t.name}/{path}";
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
103
src/Core/Unity/UnityHelpers.cs
Normal file
103
src/Core/Unity/UnityHelpers.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Core.Unity
|
||||||
|
{
|
||||||
|
public static class UnityHelpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Check if an object is null, and if it's a UnityEngine.Object then also check if it was destroyed.
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = true)
|
||||||
|
{
|
||||||
|
var unityObj = obj as Object;
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
if (!suppressWarning)
|
||||||
|
ExplorerCore.LogWarning("The target instance is null!");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (obj is Object)
|
||||||
|
{
|
||||||
|
if (!unityObj)
|
||||||
|
{
|
||||||
|
if (!suppressWarning)
|
||||||
|
ExplorerCore.LogWarning("The target UnityEngine.Object was destroyed!");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Print a nice {X, Y, Z} output of the Vector3, formatted to 3 decimal places.
|
||||||
|
/// </summary>
|
||||||
|
public static string ToStringPretty(this Vector3 vec)
|
||||||
|
{
|
||||||
|
return $"{vec.x:F3}, {vec.y:F3}, {vec.z:F3}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the full Transform heirarchy path for this provided Transform.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetTransformPath(this Transform transform, bool includeSelf = false)
|
||||||
|
{
|
||||||
|
string path = includeSelf
|
||||||
|
? transform.transform.name
|
||||||
|
: "";
|
||||||
|
|
||||||
|
while (transform.parent)
|
||||||
|
{
|
||||||
|
transform = transform.parent;
|
||||||
|
path = $"{transform.name}/{path}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts Color to 6-digit RGB hex code (without # symbol). Eg, RGBA(1,0,0,1) -> FF0000
|
||||||
|
/// </summary>
|
||||||
|
public static string ToHex(this Color color)
|
||||||
|
{
|
||||||
|
byte r = (byte)Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255);
|
||||||
|
byte g = (byte)Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255);
|
||||||
|
byte b = (byte)Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255);
|
||||||
|
|
||||||
|
return $"{r:X2}{g:X2}{b:X2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Assumes the string is a 6-digit RGB Hex color code, which it will parse into a UnityEngine.Color.
|
||||||
|
/// Eg, FF0000 -> RGBA(1,0,0,1)
|
||||||
|
/// </summary>
|
||||||
|
public static Color ToColor(this string _string)
|
||||||
|
{
|
||||||
|
_string = _string.Replace("#", "");
|
||||||
|
|
||||||
|
if (_string.Length != 6)
|
||||||
|
return Color.magenta;
|
||||||
|
|
||||||
|
var r = byte.Parse(_string.Substring(0, 2), NumberStyles.HexNumber);
|
||||||
|
var g = byte.Parse(_string.Substring(2, 2), NumberStyles.HexNumber);
|
||||||
|
var b = byte.Parse(_string.Substring(4, 2), NumberStyles.HexNumber);
|
||||||
|
|
||||||
|
var color = new Color
|
||||||
|
{
|
||||||
|
r = (float)(r / (decimal)255),
|
||||||
|
g = (float)(g / (decimal)255),
|
||||||
|
b = (float)(b / (decimal)255),
|
||||||
|
a = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,126 +1,93 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
using UnityExplorer.Core.Config;
|
using UnityExplorer.Core.Config;
|
||||||
using UnityExplorer.Core.Unity;
|
|
||||||
using UnityExplorer.Core.Input;
|
using UnityExplorer.Core.Input;
|
||||||
using UnityExplorer.Core.Inspectors;
|
|
||||||
using UnityExplorer.Core.Runtime;
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Main;
|
using UnityExplorer.UI.Main;
|
||||||
using UnityExplorer.UI.Utility;
|
|
||||||
|
|
||||||
namespace UnityExplorer
|
namespace UnityExplorer
|
||||||
{
|
{
|
||||||
public class ExplorerCore
|
public class ExplorerCore
|
||||||
{
|
{
|
||||||
public const string NAME = "UnityExplorer";
|
public const string NAME = "UnityExplorer";
|
||||||
public const string VERSION = "3.2.4";
|
public const string VERSION = "3.3.3";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
public const string GUID = "com.sinai.unityexplorer";
|
public const string GUID = "com.sinai.unityexplorer";
|
||||||
|
|
||||||
public static ExplorerCore Instance { get; private set; }
|
public static ExplorerCore Instance { get; private set; }
|
||||||
|
|
||||||
public static IExplorerLoader Loader =>
|
public static IExplorerLoader Loader { get; private set; }
|
||||||
#if ML
|
|
||||||
ExplorerMelonMod.Instance;
|
|
||||||
#elif BIE
|
|
||||||
ExplorerBepInPlugin.Instance;
|
|
||||||
#elif STANDALONE
|
|
||||||
ExplorerStandalone.Instance;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static string EXPLORER_FOLDER => Loader.ExplorerFolder;
|
// Prevent using ctor, must use Init method.
|
||||||
|
private ExplorerCore() { }
|
||||||
|
|
||||||
public ExplorerCore()
|
public static void Init(IExplorerLoader loader)
|
||||||
{
|
{
|
||||||
if (Instance != null)
|
if (Instance != null)
|
||||||
{
|
{
|
||||||
Log("An instance of Explorer is already active!");
|
Log("An instance of UnityExplorer is already active!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance = this;
|
Loader = loader;
|
||||||
|
Instance = new ExplorerCore();
|
||||||
|
|
||||||
|
if (!Directory.Exists(Loader.ExplorerFolder))
|
||||||
|
Directory.CreateDirectory(Loader.ExplorerFolder);
|
||||||
|
|
||||||
|
ConfigManager.Init(Loader.ConfigHandler);
|
||||||
|
|
||||||
RuntimeProvider.Init();
|
RuntimeProvider.Init();
|
||||||
|
|
||||||
if (!Directory.Exists(EXPLORER_FOLDER))
|
|
||||||
Directory.CreateDirectory(EXPLORER_FOLDER);
|
|
||||||
|
|
||||||
ExplorerConfig.OnLoad();
|
|
||||||
|
|
||||||
InputManager.Init();
|
InputManager.Init();
|
||||||
|
|
||||||
CursorUnlocker.Init();
|
UIManager.Init();
|
||||||
|
|
||||||
UIManager.ShowMenu = true;
|
|
||||||
|
|
||||||
Log($"{NAME} {VERSION} initialized.");
|
Log($"{NAME} {VERSION} initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
UIManager.CheckUIInit();
|
|
||||||
|
|
||||||
if (InspectUnderMouse.Enabled)
|
|
||||||
InspectUnderMouse.UpdateInspect();
|
|
||||||
else
|
|
||||||
UIManager.Update();
|
UIManager.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnUnityLog(string message, string stackTrace, LogType type)
|
public static void Log(object message)
|
||||||
|
=> Log(message, LogType.Log, false);
|
||||||
|
|
||||||
|
public static void LogWarning(object message)
|
||||||
|
=> Log(message, LogType.Warning, false);
|
||||||
|
|
||||||
|
public static void LogError(object message)
|
||||||
|
=> Log(message, LogType.Error, false);
|
||||||
|
|
||||||
|
internal static void Log(object message, LogType logType, bool isFromUnity = false)
|
||||||
{
|
{
|
||||||
if (!DebugConsole.LogUnity)
|
if (isFromUnity && !ConfigManager.Log_Unity_Debug.Value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
message = $"[UNITY] {message}";
|
string log = message?.ToString() ?? "";
|
||||||
|
|
||||||
switch (type)
|
switch (logType)
|
||||||
{
|
{
|
||||||
case LogType.Assert:
|
case LogType.Assert:
|
||||||
case LogType.Log:
|
case LogType.Log:
|
||||||
Log(message, true);
|
Loader.OnLogMessage(log);
|
||||||
|
DebugConsole.Log(log, Color.white);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LogType.Warning:
|
case LogType.Warning:
|
||||||
LogWarning(message, true);
|
Loader.OnLogWarning(log);
|
||||||
|
DebugConsole.Log(log, Color.yellow);
|
||||||
break;
|
break;
|
||||||
case LogType.Exception:
|
|
||||||
case LogType.Error:
|
case LogType.Error:
|
||||||
LogError(message, true);
|
case LogType.Exception:
|
||||||
|
Loader.OnLogError(log);
|
||||||
|
DebugConsole.Log(log, Color.red);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Log(object message, bool unity = false)
|
|
||||||
{
|
|
||||||
DebugConsole.Log(message?.ToString());
|
|
||||||
|
|
||||||
if (unity)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Loader.OnLogMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LogWarning(object message, bool unity = false)
|
|
||||||
{
|
|
||||||
DebugConsole.Log(message?.ToString(), "FFFF00");
|
|
||||||
|
|
||||||
if (unity)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Loader.OnLogWarning(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LogError(object message, bool unity = false)
|
|
||||||
{
|
|
||||||
DebugConsole.Log(message?.ToString(), "FF0000");
|
|
||||||
|
|
||||||
if (unity)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Loader.OnLogError(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Target Name="ILRepacker" AfterTargets="Build">
|
|
||||||
|
|
||||||
|
<Target Name="ILRepacker" AfterTargets="Build">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<InputAssemblies Include="$(OutputPath)$(AssemblyName).dll" />
|
<InputAssemblies Include="$(OutputPath)$(AssemblyName).dll" />
|
||||||
<InputAssemblies Include="..\lib\mcs.dll" />
|
<InputAssemblies Include="..\lib\mcs.dll" />
|
||||||
<InputAssemblies Include="..\lib\INIFileParser.dll" />
|
<InputAssemblies Include="..\lib\INIFileParser.dll" Condition="'$(IsStandalone)' == 'true'"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ILRepack
|
<ILRepack
|
||||||
Parallel="true"
|
Parallel="true"
|
||||||
Internalize="true"
|
Internalize="true"
|
||||||
@ -15,8 +14,7 @@
|
|||||||
LibraryPath="..\lib\"
|
LibraryPath="..\lib\"
|
||||||
InputAssemblies="@(InputAssemblies)"
|
InputAssemblies="@(InputAssemblies)"
|
||||||
TargetKind="Dll"
|
TargetKind="Dll"
|
||||||
OutputFile="$(OutputPath)$(AssemblyName).dll"
|
OutputFile="$(OutputPath)$(AssemblyName).dll" />
|
||||||
/>
|
|
||||||
|
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
69
src/Loader/BIE/BepInExConfigHandler.cs
Normal file
69
src/Loader/BIE/BepInExConfigHandler.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#if BIE
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Loader.BIE
|
||||||
|
{
|
||||||
|
public class BepInExConfigHandler : ConfigHandler
|
||||||
|
{
|
||||||
|
private ConfigFile Config => ExplorerBepInPlugin.Instance.Config;
|
||||||
|
|
||||||
|
private const string CTG_NAME = "UnityExplorer";
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
// Not necessary
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RegisterConfigElement<T>(ConfigElement<T> config)
|
||||||
|
{
|
||||||
|
var entry = Config.Bind(CTG_NAME, config.Name, config.Value, config.Description);
|
||||||
|
|
||||||
|
entry.SettingChanged += (object o, EventArgs e) =>
|
||||||
|
{
|
||||||
|
config.Value = entry.Value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override T GetConfigValue<T>(ConfigElement<T> element)
|
||||||
|
{
|
||||||
|
if (Config.TryGetEntry(CTG_NAME, element.Name, out ConfigEntry<T> configEntry))
|
||||||
|
return configEntry.Value;
|
||||||
|
else
|
||||||
|
throw new Exception("Could not get config entry '" + element.Name + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetConfigValue<T>(ConfigElement<T> element, T value)
|
||||||
|
{
|
||||||
|
if (Config.TryGetEntry(CTG_NAME, element.Name, out ConfigEntry<T> configEntry))
|
||||||
|
configEntry.Value = value;
|
||||||
|
else
|
||||||
|
ExplorerCore.Log("Could not get config entry '" + element.Name + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadConfig()
|
||||||
|
{
|
||||||
|
foreach (var entry in ConfigManager.ConfigElements)
|
||||||
|
{
|
||||||
|
var key = entry.Key;
|
||||||
|
var def = new ConfigDefinition(CTG_NAME, key);
|
||||||
|
if (Config.ContainsKey(def) && Config[def] is ConfigEntryBase configEntry)
|
||||||
|
{
|
||||||
|
var config = entry.Value;
|
||||||
|
config.BoxedValue = configEntry.BoxedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SaveConfig()
|
||||||
|
{
|
||||||
|
// not required
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
106
src/Loader/BIE/ExplorerBepInPlugin.cs
Normal file
106
src/Loader/BIE/ExplorerBepInPlugin.cs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#if BIE
|
||||||
|
using BepInEx;
|
||||||
|
using BepInEx.Logging;
|
||||||
|
using HarmonyLib;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
using UnityExplorer.Loader.BIE;
|
||||||
|
using UnityEngine;
|
||||||
|
#if CPP
|
||||||
|
using BepInEx.IL2CPP;
|
||||||
|
using UnhollowerRuntimeLib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace UnityExplorer
|
||||||
|
{
|
||||||
|
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
|
||||||
|
|
||||||
|
public class ExplorerBepInPlugin :
|
||||||
|
#if MONO
|
||||||
|
BaseUnityPlugin
|
||||||
|
#else
|
||||||
|
BasePlugin
|
||||||
|
#endif
|
||||||
|
, IExplorerLoader
|
||||||
|
{
|
||||||
|
public static ExplorerBepInPlugin Instance;
|
||||||
|
|
||||||
|
public ManualLogSource LogSource
|
||||||
|
#if MONO
|
||||||
|
=> Logger;
|
||||||
|
#else
|
||||||
|
=> Log;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public ConfigHandler ConfigHandler => _configHandler;
|
||||||
|
private BepInExConfigHandler _configHandler;
|
||||||
|
|
||||||
|
public Harmony HarmonyInstance => s_harmony;
|
||||||
|
private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
|
||||||
|
|
||||||
|
public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
|
||||||
|
public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
|
||||||
|
|
||||||
|
public Action<object> OnLogMessage => LogSource.LogMessage;
|
||||||
|
public Action<object> OnLogWarning => LogSource.LogWarning;
|
||||||
|
public Action<object> OnLogError => LogSource.LogError;
|
||||||
|
|
||||||
|
// Init common to Mono and Il2Cpp
|
||||||
|
internal void UniversalInit()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
_configHandler = new BepInExConfigHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MONO // Mono-specific
|
||||||
|
internal void Awake()
|
||||||
|
{
|
||||||
|
UniversalInit();
|
||||||
|
ExplorerCore.Init(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
ExplorerCore.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // Il2Cpp-specific
|
||||||
|
public override void Load()
|
||||||
|
{
|
||||||
|
UniversalInit();
|
||||||
|
|
||||||
|
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
|
||||||
|
|
||||||
|
var obj = new GameObject(
|
||||||
|
"ExplorerBehaviour",
|
||||||
|
new Il2CppSystem.Type[] { Il2CppType.Of<ExplorerBehaviour>() }
|
||||||
|
);
|
||||||
|
obj.hideFlags = HideFlags.HideAndDontSave;
|
||||||
|
GameObject.DontDestroyOnLoad(obj);
|
||||||
|
|
||||||
|
ExplorerCore.Init(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy.
|
||||||
|
public class ExplorerBehaviour : MonoBehaviour
|
||||||
|
{
|
||||||
|
public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
|
||||||
|
|
||||||
|
internal void Awake()
|
||||||
|
{
|
||||||
|
Instance.LogSource.LogMessage("ExplorerBehaviour.Awake");
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
ExplorerCore.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -1,41 +0,0 @@
|
|||||||
#if BIE5
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using BepInEx;
|
|
||||||
using BepInEx.Logging;
|
|
||||||
using HarmonyLib;
|
|
||||||
|
|
||||||
namespace UnityExplorer
|
|
||||||
{
|
|
||||||
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
|
|
||||||
public class ExplorerBepInPlugin : BaseUnityPlugin, IExplorerLoader
|
|
||||||
{
|
|
||||||
public static ExplorerBepInPlugin Instance;
|
|
||||||
|
|
||||||
public static ManualLogSource Logging => Instance?.Logger;
|
|
||||||
|
|
||||||
public Harmony HarmonyInstance => s_harmony;
|
|
||||||
private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
|
|
||||||
|
|
||||||
public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
|
|
||||||
public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
|
|
||||||
|
|
||||||
public Action<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
|
|
||||||
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
|
|
||||||
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
|
|
||||||
|
|
||||||
internal void Awake()
|
|
||||||
{
|
|
||||||
Instance = this;
|
|
||||||
|
|
||||||
new ExplorerCore();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Update()
|
|
||||||
{
|
|
||||||
ExplorerCore.Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,104 +0,0 @@
|
|||||||
#if BIE6
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using BepInEx;
|
|
||||||
using BepInEx.Logging;
|
|
||||||
using HarmonyLib;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityExplorer.UI.Main;
|
|
||||||
#if CPP
|
|
||||||
using UnhollowerRuntimeLib;
|
|
||||||
using BepInEx.IL2CPP;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace UnityExplorer
|
|
||||||
{
|
|
||||||
#if MONO
|
|
||||||
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
|
|
||||||
public class ExplorerBepInPlugin : BaseUnityPlugin, IExplorerLoader
|
|
||||||
{
|
|
||||||
public static ExplorerBepInPlugin Instance;
|
|
||||||
|
|
||||||
public static ManualLogSource Logging => Instance?.Logger;
|
|
||||||
|
|
||||||
public Harmony HarmonyInstance => s_harmony;
|
|
||||||
private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
|
|
||||||
|
|
||||||
public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
|
|
||||||
public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
|
|
||||||
|
|
||||||
public Action<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
|
|
||||||
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
|
|
||||||
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
|
|
||||||
|
|
||||||
internal void Awake()
|
|
||||||
{
|
|
||||||
Instance = this;
|
|
||||||
|
|
||||||
new ExplorerCore();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Update()
|
|
||||||
{
|
|
||||||
ExplorerCore.Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CPP
|
|
||||||
[BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)]
|
|
||||||
public class ExplorerBepInPlugin : BasePlugin, IExplorerLoader
|
|
||||||
{
|
|
||||||
public static ExplorerBepInPlugin Instance;
|
|
||||||
|
|
||||||
public static ManualLogSource Logging => Instance?.Log;
|
|
||||||
|
|
||||||
public Harmony HarmonyInstance => s_harmony;
|
|
||||||
private static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
|
|
||||||
|
|
||||||
public string ExplorerFolder => Path.Combine(Paths.PluginPath, ExplorerCore.NAME);
|
|
||||||
public string ConfigFolder => Path.Combine(Paths.ConfigPath, ExplorerCore.NAME);
|
|
||||||
|
|
||||||
public Action<object> OnLogMessage => (object log) => { Logging?.LogMessage(log?.ToString() ?? ""); };
|
|
||||||
public Action<object> OnLogWarning => (object log) => { Logging?.LogWarning(log?.ToString() ?? ""); };
|
|
||||||
public Action<object> OnLogError => (object log) => { Logging?.LogError(log?.ToString() ?? ""); };
|
|
||||||
|
|
||||||
// Init
|
|
||||||
public override void Load()
|
|
||||||
{
|
|
||||||
Instance = this;
|
|
||||||
|
|
||||||
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
|
|
||||||
|
|
||||||
var obj = new GameObject(
|
|
||||||
"ExplorerBehaviour",
|
|
||||||
new Il2CppSystem.Type[] { Il2CppType.Of<ExplorerBehaviour>() }
|
|
||||||
);
|
|
||||||
obj.hideFlags = HideFlags.HideAndDontSave;
|
|
||||||
GameObject.DontDestroyOnLoad(obj);
|
|
||||||
|
|
||||||
new ExplorerCore();
|
|
||||||
}
|
|
||||||
|
|
||||||
// BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy.
|
|
||||||
public class ExplorerBehaviour : MonoBehaviour
|
|
||||||
{
|
|
||||||
public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
|
|
||||||
|
|
||||||
internal void Awake()
|
|
||||||
{
|
|
||||||
Logging.LogMessage("ExplorerBehaviour.Awake");
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Update()
|
|
||||||
{
|
|
||||||
ExplorerCore.Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,39 +0,0 @@
|
|||||||
#if ML
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using MelonLoader;
|
|
||||||
|
|
||||||
namespace UnityExplorer
|
|
||||||
{
|
|
||||||
public class ExplorerMelonMod : MelonMod, IExplorerLoader
|
|
||||||
{
|
|
||||||
public static ExplorerMelonMod Instance;
|
|
||||||
|
|
||||||
public string ExplorerFolder => Path.Combine("Mods", ExplorerCore.NAME);
|
|
||||||
public string ConfigFolder => ExplorerFolder;
|
|
||||||
|
|
||||||
public Action<object> OnLogMessage => (object log) => { MelonLogger.Msg(log?.ToString() ?? ""); };
|
|
||||||
public Action<object> OnLogWarning => (object log) => { MelonLogger.Warning(log?.ToString() ?? ""); };
|
|
||||||
public Action<object> OnLogError => (object log) => { MelonLogger.Error(log?.ToString() ?? ""); };
|
|
||||||
|
|
||||||
public Harmony.HarmonyInstance HarmonyInstance => Instance.Harmony;
|
|
||||||
|
|
||||||
public override void OnApplicationStart()
|
|
||||||
{
|
|
||||||
Instance = this;
|
|
||||||
|
|
||||||
new ExplorerCore();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnUpdate()
|
|
||||||
{
|
|
||||||
ExplorerCore.Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
//public override void OnSceneWasLoaded(int buildIndex, string sceneName)
|
|
||||||
//{
|
|
||||||
// ExplorerCore.Instance.OnSceneLoaded();
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
|
||||||
namespace UnityExplorer
|
namespace UnityExplorer
|
||||||
{
|
{
|
||||||
@ -10,6 +11,7 @@ namespace UnityExplorer
|
|||||||
string ExplorerFolder { get; }
|
string ExplorerFolder { get; }
|
||||||
|
|
||||||
string ConfigFolder { get; }
|
string ConfigFolder { get; }
|
||||||
|
ConfigHandler ConfigHandler { get; }
|
||||||
|
|
||||||
Action<object> OnLogMessage { get; }
|
Action<object> OnLogMessage { get; }
|
||||||
Action<object> OnLogWarning { get; }
|
Action<object> OnLogWarning { get; }
|
||||||
|
45
src/Loader/ML/ExplorerMelonMod.cs
Normal file
45
src/Loader/ML/ExplorerMelonMod.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#if ML
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using MelonLoader;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityExplorer;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
using UnityExplorer.Loader.ML;
|
||||||
|
|
||||||
|
[assembly: MelonInfo(typeof(ExplorerMelonMod), ExplorerCore.NAME, ExplorerCore.VERSION, ExplorerCore.AUTHOR)]
|
||||||
|
[assembly: MelonGame(null, null)]
|
||||||
|
|
||||||
|
namespace UnityExplorer
|
||||||
|
{
|
||||||
|
public class ExplorerMelonMod : MelonMod, IExplorerLoader
|
||||||
|
{
|
||||||
|
public static ExplorerMelonMod Instance;
|
||||||
|
|
||||||
|
public string ExplorerFolder => Path.Combine("Mods", ExplorerCore.NAME);
|
||||||
|
public string ConfigFolder => ExplorerFolder;
|
||||||
|
|
||||||
|
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 Harmony.HarmonyInstance HarmonyInstance => Instance.Harmony;
|
||||||
|
|
||||||
|
public override void OnApplicationStart()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
_configHandler = new MelonLoaderConfigHandler();
|
||||||
|
|
||||||
|
ExplorerCore.Init(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnUpdate()
|
||||||
|
{
|
||||||
|
ExplorerCore.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
103
src/Loader/ML/MelonLoaderConfigHandler.cs
Normal file
103
src/Loader/ML/MelonLoaderConfigHandler.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#if ML
|
||||||
|
using MelonLoader;
|
||||||
|
using MelonLoader.Tomlyn.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Loader.ML
|
||||||
|
{
|
||||||
|
public class MelonLoaderConfigHandler : ConfigHandler
|
||||||
|
{
|
||||||
|
internal const string CTG_NAME = "UnityExplorer";
|
||||||
|
|
||||||
|
internal MelonPreferences_Category prefCategory;
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
prefCategory = MelonPreferences.CreateCategory(CTG_NAME, $"{CTG_NAME} Settings");
|
||||||
|
|
||||||
|
MelonPreferences.Mapper.RegisterMapper(KeycodeReader, KeycodeWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadConfig()
|
||||||
|
{
|
||||||
|
foreach (var entry in ConfigManager.ConfigElements)
|
||||||
|
{
|
||||||
|
var key = entry.Key;
|
||||||
|
if (prefCategory.GetEntry(key) is MelonPreferences_Entry)
|
||||||
|
{
|
||||||
|
var config = entry.Value;
|
||||||
|
config.BoxedValue = config.GetLoaderConfigValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RegisterConfigElement<T>(ConfigElement<T> config)
|
||||||
|
{
|
||||||
|
var entry = prefCategory.CreateEntry(config.Name, config.Value, null, config.IsInternal) as MelonPreferences_Entry<T>;
|
||||||
|
|
||||||
|
entry.OnValueChangedUntyped += () =>
|
||||||
|
{
|
||||||
|
if ((entry.Value == null && config.Value == null) || config.Value.Equals(entry.Value))
|
||||||
|
return;
|
||||||
|
|
||||||
|
config.Value = entry.Value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetConfigValue<T>(ConfigElement<T> config, T value)
|
||||||
|
{
|
||||||
|
if (prefCategory.GetEntry<T>(config.Name) is MelonPreferences_Entry<T> entry)
|
||||||
|
{
|
||||||
|
entry.Value = value;
|
||||||
|
entry.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override T GetConfigValue<T>(ConfigElement<T> config)
|
||||||
|
{
|
||||||
|
if (prefCategory.GetEntry<T>(config.Name) is MelonPreferences_Entry<T> entry)
|
||||||
|
return entry.Value;
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnAnyConfigChanged()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SaveConfig()
|
||||||
|
{
|
||||||
|
MelonPreferences.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KeyCode KeycodeReader(TomlObject value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
KeyCode kc = (KeyCode)Enum.Parse(typeof(KeyCode), (value as TomlString).Value);
|
||||||
|
|
||||||
|
if (kc == default)
|
||||||
|
throw new Exception();
|
||||||
|
|
||||||
|
return kc;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return KeyCode.F7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TomlObject KeycodeWriter(KeyCode value)
|
||||||
|
{
|
||||||
|
return MelonPreferences.Mapper.ToToml(value.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -4,6 +4,8 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
using UnityExplorer.Loader.STANDALONE;
|
||||||
#if CPP
|
#if CPP
|
||||||
using UnhollowerRuntimeLib;
|
using UnhollowerRuntimeLib;
|
||||||
#endif
|
#endif
|
||||||
@ -13,20 +15,27 @@ namespace UnityExplorer
|
|||||||
public class ExplorerStandalone : IExplorerLoader
|
public class ExplorerStandalone : IExplorerLoader
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Call this to initialize UnityExplorer. Optionally, also subscribe to the 'OnLog' event to handle logging.
|
/// Call this to initialize UnityExplorer without adding a log listener.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The new (or active, if one exists) instance of ExplorerStandalone.</returns>
|
/// <returns>The new (or active, if one exists) instance of ExplorerStandalone.</returns>
|
||||||
public static ExplorerStandalone CreateInstance()
|
public static ExplorerStandalone CreateInstance()
|
||||||
|
=> CreateInstance(null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call this to initialize UnityExplorer and add a listener for UnityExplorer's log messages.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logListener">Your log listener to handle UnityExplorer logs.</param>
|
||||||
|
/// <returns>The new (or active, if one exists) instance of ExplorerStandalone.</returns>
|
||||||
|
public static ExplorerStandalone CreateInstance(Action<string, LogType> logListener)
|
||||||
{
|
{
|
||||||
if (Instance != null)
|
if (Instance != null)
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
||||||
return new ExplorerStandalone();
|
OnLog += logListener;
|
||||||
}
|
|
||||||
|
|
||||||
private ExplorerStandalone()
|
var instance = new ExplorerStandalone();
|
||||||
{
|
instance.Init();
|
||||||
Init();
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExplorerStandalone Instance { get; private set; }
|
public static ExplorerStandalone Instance { get; private set; }
|
||||||
@ -39,6 +48,9 @@ namespace UnityExplorer
|
|||||||
public Harmony HarmonyInstance => s_harmony;
|
public Harmony HarmonyInstance => s_harmony;
|
||||||
public static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
|
public static readonly Harmony s_harmony = new Harmony(ExplorerCore.GUID);
|
||||||
|
|
||||||
|
public ConfigHandler ConfigHandler => _configHandler;
|
||||||
|
private StandaloneConfigHandler _configHandler;
|
||||||
|
|
||||||
public string ExplorerFolder
|
public string ExplorerFolder
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -70,6 +82,8 @@ namespace UnityExplorer
|
|||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
_configHandler = new StandaloneConfigHandler();
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
|
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
|
||||||
|
|
||||||
@ -84,10 +98,10 @@ namespace UnityExplorer
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
obj.hideFlags = HideFlags.HideAndDontSave;
|
|
||||||
GameObject.DontDestroyOnLoad(obj);
|
GameObject.DontDestroyOnLoad(obj);
|
||||||
|
obj.hideFlags = HideFlags.HideAndDontSave;
|
||||||
|
|
||||||
new ExplorerCore();
|
ExplorerCore.Init(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ExplorerBehaviour : MonoBehaviour
|
public class ExplorerBehaviour : MonoBehaviour
|
108
src/Loader/STANDALONE/StandaloneConfigHandler.cs
Normal file
108
src/Loader/STANDALONE/StandaloneConfigHandler.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#if STANDALONE
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
using IniParser.Parser;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace UnityExplorer.Loader.STANDALONE
|
||||||
|
{
|
||||||
|
public class StandaloneConfigHandler : ConfigHandler
|
||||||
|
{
|
||||||
|
internal static IniDataParser _parser;
|
||||||
|
internal static string INI_PATH;
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
INI_PATH = Path.Combine(ExplorerCore.Loader.ConfigFolder, "config.ini");
|
||||||
|
_parser = new IniDataParser();
|
||||||
|
_parser.Configuration.CommentString = "#";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadConfig()
|
||||||
|
{
|
||||||
|
if (!TryLoadConfig())
|
||||||
|
SaveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RegisterConfigElement<T>(ConfigElement<T> element)
|
||||||
|
{
|
||||||
|
// Not necessary
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetConfigValue<T>(ConfigElement<T> element, T value)
|
||||||
|
{
|
||||||
|
// Not necessary, just save.
|
||||||
|
SaveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override T GetConfigValue<T>(ConfigElement<T> element)
|
||||||
|
{
|
||||||
|
// Not necessary, just return the value.
|
||||||
|
return element.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryLoadConfig()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!File.Exists(INI_PATH))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string ini = File.ReadAllText(INI_PATH);
|
||||||
|
|
||||||
|
var data = _parser.Parse(ini);
|
||||||
|
|
||||||
|
foreach (var config in data.Sections["Config"])
|
||||||
|
{
|
||||||
|
if (ConfigManager.ConfigElements.TryGetValue(config.KeyName, out IConfigElement configElement))
|
||||||
|
configElement.BoxedValue = StringToConfigValue(config.Value, configElement.ElementType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public object StringToConfigValue(string value, Type elementType)
|
||||||
|
{
|
||||||
|
if (elementType == typeof(KeyCode))
|
||||||
|
return (KeyCode)Enum.Parse(typeof(KeyCode), value);
|
||||||
|
else if (elementType == typeof(bool))
|
||||||
|
return bool.Parse(value);
|
||||||
|
else if (elementType == typeof(int))
|
||||||
|
return int.Parse(value);
|
||||||
|
else
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnAnyConfigChanged()
|
||||||
|
{
|
||||||
|
SaveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SaveConfig()
|
||||||
|
{
|
||||||
|
var data = new IniParser.Model.IniData();
|
||||||
|
|
||||||
|
data.Sections.AddSection("Config");
|
||||||
|
var sec = data.Sections["Config"];
|
||||||
|
|
||||||
|
foreach (var entry in ConfigManager.ConfigElements)
|
||||||
|
sec.AddKey(entry.Key, entry.Value.BoxedValue.ToString());
|
||||||
|
|
||||||
|
if (!Directory.Exists(ExplorerCore.Loader.ConfigFolder))
|
||||||
|
Directory.CreateDirectory(ExplorerCore.Loader.ConfigFolder);
|
||||||
|
|
||||||
|
File.WriteAllText(INI_PATH, data.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -2,13 +2,6 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using UnityExplorer;
|
using UnityExplorer;
|
||||||
|
|
||||||
#if ML
|
|
||||||
using MelonLoader;
|
|
||||||
|
|
||||||
[assembly: MelonInfo(typeof(ExplorerMelonMod), "UnityExplorer", ExplorerCore.VERSION, ExplorerCore.AUTHOR)]
|
|
||||||
[assembly: MelonGame(null, null)]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
|
Binary file not shown.
BIN
src/Resources/explorerui.legacy.bundle.bak.5.3.8
Normal file
BIN
src/Resources/explorerui.legacy.bundle.bak.5.3.8
Normal file
Binary file not shown.
102
src/UI/CacheObject/CacheConfigEntry.cs
Normal file
102
src/UI/CacheObject/CacheConfigEntry.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Core.Config;
|
||||||
|
using UnityExplorer.UI.InteractiveValues;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.CacheObject
|
||||||
|
{
|
||||||
|
public class CacheConfigEntry : CacheObjectBase
|
||||||
|
{
|
||||||
|
public IConfigElement RefConfig { get; }
|
||||||
|
|
||||||
|
public override Type FallbackType => RefConfig.ElementType;
|
||||||
|
|
||||||
|
public override bool HasEvaluated => true;
|
||||||
|
public override bool HasParameters => false;
|
||||||
|
public override bool IsMember => false;
|
||||||
|
public override bool CanWrite => true;
|
||||||
|
|
||||||
|
public CacheConfigEntry(IConfigElement config, GameObject parent)
|
||||||
|
{
|
||||||
|
RefConfig = config;
|
||||||
|
|
||||||
|
m_parentContent = parent;
|
||||||
|
|
||||||
|
config.OnValueChangedNotify += () => { UpdateValue(); };
|
||||||
|
|
||||||
|
CreateIValue(config.BoxedValue, config.ElementType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CreateIValue(object value, Type fallbackType)
|
||||||
|
{
|
||||||
|
IValue = InteractiveValue.Create(value, fallbackType);
|
||||||
|
IValue.Owner = this;
|
||||||
|
IValue.m_mainContentParent = m_mainGroup;
|
||||||
|
IValue.m_subContentParent = this.m_subContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateValue()
|
||||||
|
{
|
||||||
|
IValue.Value = RefConfig.BoxedValue;
|
||||||
|
|
||||||
|
base.UpdateValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetValue()
|
||||||
|
{
|
||||||
|
RefConfig.BoxedValue = IValue.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal GameObject m_mainGroup;
|
||||||
|
|
||||||
|
internal override void ConstructUI()
|
||||||
|
{
|
||||||
|
base.ConstructUI();
|
||||||
|
|
||||||
|
m_mainGroup = UIFactory.CreateVerticalGroup(m_mainContent, "ConfigHolder", true, false, true, true, 5, new Vector4(2, 2, 2, 2));
|
||||||
|
|
||||||
|
var horiGroup = UIFactory.CreateHorizontalGroup(m_mainGroup, "ConfigEntryHolder", false, false, true, true, childAlignment: TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(horiGroup, minHeight: 30, flexibleHeight: 0);
|
||||||
|
|
||||||
|
// config entry label
|
||||||
|
|
||||||
|
var configLabel = UIFactory.CreateLabel(horiGroup, "ConfigLabel", this.RefConfig.Name, TextAnchor.MiddleLeft);
|
||||||
|
var leftRect = configLabel.GetComponent<RectTransform>();
|
||||||
|
leftRect.anchorMin = Vector2.zero;
|
||||||
|
leftRect.anchorMax = Vector2.one;
|
||||||
|
leftRect.offsetMin = Vector2.zero;
|
||||||
|
leftRect.offsetMax = Vector2.zero;
|
||||||
|
leftRect.sizeDelta = Vector2.zero;
|
||||||
|
UIFactory.SetLayoutElement(configLabel.gameObject, minWidth: 250, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||||
|
|
||||||
|
// Default button
|
||||||
|
|
||||||
|
var defaultButton = UIFactory.CreateButton(horiGroup,
|
||||||
|
"RevertDefaultButton",
|
||||||
|
"Default",
|
||||||
|
() => { RefConfig.RevertToDefaultValue(); },
|
||||||
|
new Color(0.3f, 0.3f, 0.3f));
|
||||||
|
UIFactory.SetLayoutElement(defaultButton.gameObject, minWidth: 80, minHeight: 22, flexibleWidth: 0);
|
||||||
|
|
||||||
|
// Description label
|
||||||
|
|
||||||
|
var desc = UIFactory.CreateLabel(m_mainGroup, "Description", $"<i>{RefConfig.Description}</i>", TextAnchor.MiddleLeft, Color.grey);
|
||||||
|
UIFactory.SetLayoutElement(desc.gameObject, minWidth: 250, minHeight: 20, flexibleWidth: 9999, flexibleHeight: 0);
|
||||||
|
|
||||||
|
// IValue
|
||||||
|
|
||||||
|
if (IValue != null)
|
||||||
|
{
|
||||||
|
IValue.m_mainContentParent = m_mainGroup;
|
||||||
|
IValue.m_subContentParent = this.m_subContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// makes the subcontent look nicer
|
||||||
|
m_subContent.transform.SetParent(m_mainGroup.transform, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,8 +6,9 @@ using System.Text;
|
|||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.UI.InteractiveValues;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.CacheObject
|
||||||
{
|
{
|
||||||
public class CacheEnumerated : CacheObjectBase
|
public class CacheEnumerated : CacheObjectBase
|
||||||
{
|
{
|
||||||
@ -44,18 +45,11 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
base.ConstructUI();
|
base.ConstructUI();
|
||||||
|
|
||||||
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0));
|
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, "CacheEnumeratedGroup", false, true, true, true, 0, new Vector4(0,0,5,2),
|
||||||
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
new Color(1, 1, 1, 0));
|
||||||
rowGroup.padding.left = 5;
|
|
||||||
rowGroup.padding.right = 2;
|
|
||||||
|
|
||||||
var indexLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
var indexLabel = UIFactory.CreateLabel(rowObj, "IndexLabel", $"{this.Index}:", TextAnchor.MiddleLeft);
|
||||||
var indexLayout = indexLabelObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 20, flexibleWidth: 30, minHeight: 25);
|
||||||
indexLayout.minWidth = 20;
|
|
||||||
indexLayout.flexibleWidth = 30;
|
|
||||||
indexLayout.minHeight = 25;
|
|
||||||
var indexText = indexLabelObj.GetComponent<Text>();
|
|
||||||
indexText.text = this.Index + ":";
|
|
||||||
|
|
||||||
IValue.m_mainContentParent = rowObj;
|
IValue.m_mainContentParent = rowObj;
|
||||||
}
|
}
|
@ -6,7 +6,7 @@ using System.Reflection;
|
|||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.CacheObject
|
||||||
{
|
{
|
||||||
public class CacheField : CacheMember
|
public class CacheField : CacheMember
|
||||||
{
|
{
|
@ -5,13 +5,14 @@ using System.Reflection;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Reusable;
|
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.Core.Runtime;
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
|
using UnityExplorer.UI.InteractiveValues;
|
||||||
|
using UnityExplorer.UI.Main.Home.Inspectors.Reflection;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.CacheObject
|
||||||
{
|
{
|
||||||
public abstract class CacheMember : CacheObjectBase
|
public abstract class CacheMember : CacheObjectBase
|
||||||
{
|
{
|
||||||
@ -214,75 +215,46 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
base.ConstructUI();
|
base.ConstructUI();
|
||||||
|
|
||||||
var topGroupObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0));
|
var topGroupObj = UIFactory.CreateHorizontalGroup(m_mainContent, "CacheMemberGroup", false, false, true, true, 10, new Vector4(0, 0, 3, 3),
|
||||||
|
new Color(1, 1, 1, 0));
|
||||||
|
|
||||||
m_topRowRect = topGroupObj.GetComponent<RectTransform>();
|
m_topRowRect = topGroupObj.GetComponent<RectTransform>();
|
||||||
var topLayout = topGroupObj.AddComponent<LayoutElement>();
|
|
||||||
topLayout.minHeight = 25;
|
UIFactory.SetLayoutElement(topGroupObj, minHeight: 25, flexibleHeight: 0, minWidth: 300, flexibleWidth: 5000);
|
||||||
topLayout.flexibleHeight = 0;
|
|
||||||
topLayout.minWidth = 300;
|
|
||||||
topLayout.flexibleWidth = 5000;
|
|
||||||
var topGroup = topGroupObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
topGroup.childForceExpandHeight = false;
|
|
||||||
topGroup.childForceExpandWidth = false;
|
|
||||||
topGroup.childControlHeight = true;
|
|
||||||
topGroup.childControlWidth = true;
|
|
||||||
topGroup.spacing = 10;
|
|
||||||
topGroup.padding.left = 3;
|
|
||||||
topGroup.padding.right = 3;
|
|
||||||
topGroup.padding.top = 0;
|
|
||||||
topGroup.padding.bottom = 0;
|
|
||||||
|
|
||||||
// left group
|
// left group
|
||||||
|
|
||||||
m_leftGroup = UIFactory.CreateHorizontalGroup(topGroupObj, new Color(1, 1, 1, 0));
|
m_leftGroup = UIFactory.CreateHorizontalGroup(topGroupObj, "LeftGroup", false, true, true, true, 4, default, new Color(1, 1, 1, 0));
|
||||||
var leftLayout = m_leftGroup.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(m_leftGroup, minHeight: 25, flexibleHeight: 0, minWidth: 125, flexibleWidth: 200);
|
||||||
leftLayout.minHeight = 25;
|
|
||||||
leftLayout.flexibleHeight = 0;
|
|
||||||
leftLayout.minWidth = 125;
|
|
||||||
leftLayout.flexibleWidth = 200;
|
|
||||||
var leftGroup = m_leftGroup.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
leftGroup.childForceExpandHeight = true;
|
|
||||||
leftGroup.childForceExpandWidth = false;
|
|
||||||
leftGroup.childControlHeight = true;
|
|
||||||
leftGroup.childControlWidth = true;
|
|
||||||
leftGroup.spacing = 4;
|
|
||||||
|
|
||||||
// member label
|
// member label
|
||||||
|
|
||||||
var labelObj = UIFactory.CreateLabel(m_leftGroup, TextAnchor.MiddleLeft);
|
m_memLabelText = UIFactory.CreateLabel(m_leftGroup, "MemLabelText", RichTextName, TextAnchor.MiddleLeft);
|
||||||
var leftRect = labelObj.GetComponent<RectTransform>();
|
m_memLabelText.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||||
|
var leftRect = m_memLabelText.GetComponent<RectTransform>();
|
||||||
leftRect.anchorMin = Vector2.zero;
|
leftRect.anchorMin = Vector2.zero;
|
||||||
leftRect.anchorMax = Vector2.one;
|
leftRect.anchorMax = Vector2.one;
|
||||||
leftRect.offsetMin = Vector2.zero;
|
leftRect.offsetMin = Vector2.zero;
|
||||||
leftRect.offsetMax = Vector2.zero;
|
leftRect.offsetMax = Vector2.zero;
|
||||||
leftRect.sizeDelta = Vector2.zero;
|
leftRect.sizeDelta = Vector2.zero;
|
||||||
m_leftLayout = labelObj.AddComponent<LayoutElement>();
|
m_leftLayout = m_memLabelText.gameObject.AddComponent<LayoutElement>();
|
||||||
m_leftLayout.preferredWidth = 125;
|
m_leftLayout.preferredWidth = 125;
|
||||||
m_leftLayout.minHeight = 25;
|
m_leftLayout.minHeight = 25;
|
||||||
m_leftLayout.flexibleHeight = 100;
|
m_leftLayout.flexibleHeight = 100;
|
||||||
var labelFitter = labelObj.AddComponent<ContentSizeFitter>();
|
var labelFitter = m_memLabelText.gameObject.AddComponent<ContentSizeFitter>();
|
||||||
labelFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
labelFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
labelFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
|
labelFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
m_memLabelText = labelObj.GetComponent<Text>();
|
|
||||||
m_memLabelText.horizontalOverflow = HorizontalWrapMode.Wrap;
|
|
||||||
m_memLabelText.text = this.RichTextName;
|
|
||||||
|
|
||||||
// right group
|
// right group
|
||||||
|
|
||||||
m_rightGroup = UIFactory.CreateVerticalGroup(topGroupObj, new Color(1, 1, 1, 0));
|
m_rightGroup = UIFactory.CreateVerticalGroup(topGroupObj, "RightGroup", false, true, true, true, 2, new Vector4(4,2,0,0),
|
||||||
|
new Color(1, 1, 1, 0));
|
||||||
|
|
||||||
m_rightLayout = m_rightGroup.AddComponent<LayoutElement>();
|
m_rightLayout = m_rightGroup.AddComponent<LayoutElement>();
|
||||||
m_rightLayout.minHeight = 25;
|
m_rightLayout.minHeight = 25;
|
||||||
m_rightLayout.flexibleHeight = 480;
|
m_rightLayout.flexibleHeight = 480;
|
||||||
m_rightLayout.minWidth = 125;
|
m_rightLayout.minWidth = 125;
|
||||||
m_rightLayout.flexibleWidth = 5000;
|
m_rightLayout.flexibleWidth = 5000;
|
||||||
var rightGroup = m_rightGroup.GetComponent<VerticalLayoutGroup>();
|
|
||||||
rightGroup.childForceExpandHeight = true;
|
|
||||||
rightGroup.childForceExpandWidth = false;
|
|
||||||
rightGroup.childControlHeight = true;
|
|
||||||
rightGroup.childControlWidth = true;
|
|
||||||
rightGroup.spacing = 2;
|
|
||||||
rightGroup.padding.top = 4;
|
|
||||||
rightGroup.padding.bottom = 2;
|
|
||||||
|
|
||||||
ConstructArgInput(out GameObject argsHolder);
|
ConstructArgInput(out GameObject argsHolder);
|
||||||
|
|
||||||
@ -297,28 +269,18 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
if (HasParameters)
|
if (HasParameters)
|
||||||
{
|
{
|
||||||
argsHolder = UIFactory.CreateVerticalGroup(m_rightGroup, new Color(1, 1, 1, 0));
|
argsHolder = UIFactory.CreateVerticalGroup(m_rightGroup, "ArgsHolder", true, false, true, true, 4, new Color(1, 1, 1, 0));
|
||||||
var argsGroup = argsHolder.GetComponent<VerticalLayoutGroup>();
|
|
||||||
argsGroup.spacing = 4;
|
|
||||||
|
|
||||||
if (this is CacheMethod cm && cm.GenericArgs.Length > 0)
|
if (this is CacheMethod cm && cm.GenericArgs.Length > 0)
|
||||||
{
|
|
||||||
cm.ConstructGenericArgInput(argsHolder);
|
cm.ConstructGenericArgInput(argsHolder);
|
||||||
}
|
|
||||||
|
|
||||||
// todo normal args
|
|
||||||
|
|
||||||
if (m_arguments.Length > 0)
|
if (m_arguments.Length > 0)
|
||||||
{
|
{
|
||||||
var titleObj = UIFactory.CreateLabel(argsHolder, TextAnchor.MiddleLeft);
|
UIFactory.CreateLabel(argsHolder, "ArgumentsLabel", "Arguments:", TextAnchor.MiddleLeft);
|
||||||
var titleText = titleObj.GetComponent<Text>();
|
|
||||||
titleText.text = "<b>Arguments:</b>";
|
|
||||||
|
|
||||||
for (int i = 0; i < m_arguments.Length; i++)
|
for (int i = 0; i < m_arguments.Length; i++)
|
||||||
{
|
|
||||||
AddArgRow(i, argsHolder);
|
AddArgRow(i, argsHolder);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
argsHolder.SetActive(false);
|
argsHolder.SetActive(false);
|
||||||
}
|
}
|
||||||
@ -328,30 +290,16 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
var arg = m_arguments[i];
|
var arg = m_arguments[i];
|
||||||
|
|
||||||
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
var rowObj = UIFactory.CreateHorizontalGroup(parent, "ArgRow", true, false, true, true, 4, default, new Color(1, 1, 1, 0));
|
||||||
var rowLayout = rowObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000);
|
||||||
rowLayout.minHeight = 25;
|
|
||||||
rowLayout.flexibleWidth = 5000;
|
|
||||||
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
rowGroup.childForceExpandHeight = false;
|
|
||||||
rowGroup.childForceExpandWidth = true;
|
|
||||||
rowGroup.spacing = 4;
|
|
||||||
|
|
||||||
var argLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
|
||||||
var argLabelLayout = argLabelObj.AddComponent<LayoutElement>();
|
|
||||||
argLabelLayout.minHeight = 25;
|
|
||||||
var argText = argLabelObj.GetComponent<Text>();
|
|
||||||
var argTypeTxt = SignatureHighlighter.ParseFullSyntax(arg.ParameterType, false);
|
var argTypeTxt = SignatureHighlighter.ParseFullSyntax(arg.ParameterType, false);
|
||||||
argText.text = $"{argTypeTxt} <color={SignatureHighlighter.LOCAL_ARG}>{arg.Name}</color>";
|
var argLabel = UIFactory.CreateLabel(rowObj, "ArgLabel", $"{argTypeTxt} <color={SignatureHighlighter.LOCAL_ARG}>{arg.Name}</color>",
|
||||||
|
TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(argLabel.gameObject, minHeight: 25);
|
||||||
|
|
||||||
var argInputObj = UIFactory.CreateInputField(rowObj, 14, (int)TextAnchor.MiddleLeft, 1);
|
var argInputObj = UIFactory.CreateInputField(rowObj, "ArgInput", "...", 14, (int)TextAnchor.MiddleLeft, 1);
|
||||||
var argInputLayout = argInputObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(argInputObj, flexibleWidth: 1200, preferredWidth: 150, minWidth: 20, minHeight: 25, flexibleHeight: 0);
|
||||||
argInputLayout.flexibleWidth = 1200;
|
|
||||||
argInputLayout.preferredWidth = 150;
|
|
||||||
argInputLayout.minWidth = 20;
|
|
||||||
argInputLayout.minHeight = 25;
|
|
||||||
argInputLayout.flexibleHeight = 0;
|
|
||||||
//argInputLayout.layoutPriority = 2;
|
|
||||||
|
|
||||||
var argInput = argInputObj.GetComponent<InputField>();
|
var argInput = argInputObj.GetComponent<InputField>();
|
||||||
argInput.onValueChanged.AddListener((string val) => { m_argumentInput[i] = val; });
|
argInput.onValueChanged.AddListener((string val) => { m_argumentInput[i] = val; });
|
||||||
@ -367,38 +315,28 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
if (HasParameters)
|
if (HasParameters)
|
||||||
{
|
{
|
||||||
var evalGroupObj = UIFactory.CreateHorizontalGroup(m_rightGroup, new Color(1, 1, 1, 0));
|
var evalGroupObj = UIFactory.CreateHorizontalGroup(m_rightGroup, "EvalGroup", false, false, true, true, 5,
|
||||||
var evalGroup = evalGroupObj.GetComponent<HorizontalLayoutGroup>();
|
default, new Color(1, 1, 1, 0));
|
||||||
evalGroup.childForceExpandWidth = false;
|
UIFactory.SetLayoutElement(evalGroupObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 5000);
|
||||||
evalGroup.childForceExpandHeight = false;
|
|
||||||
evalGroup.spacing = 5;
|
|
||||||
var evalGroupLayout = evalGroupObj.AddComponent<LayoutElement>();
|
|
||||||
evalGroupLayout.minHeight = 25;
|
|
||||||
evalGroupLayout.flexibleHeight = 0;
|
|
||||||
evalGroupLayout.flexibleWidth = 5000;
|
|
||||||
|
|
||||||
var evalButtonObj = UIFactory.CreateButton(evalGroupObj, new Color(0.4f, 0.4f, 0.4f));
|
var colors = new ColorBlock();
|
||||||
var evalLayout = evalButtonObj.AddComponent<LayoutElement>();
|
colors = RuntimeProvider.Instance.SetColorBlock(colors, new Color(0.4f, 0.4f, 0.4f),
|
||||||
evalLayout.minWidth = 100;
|
new Color(0.4f, 0.7f, 0.4f), new Color(0.3f, 0.3f, 0.3f));
|
||||||
evalLayout.minHeight = 22;
|
|
||||||
evalLayout.flexibleWidth = 0;
|
|
||||||
var evalText = evalButtonObj.GetComponentInChildren<Text>();
|
|
||||||
evalText.text = $"Evaluate ({ParamCount})";
|
|
||||||
|
|
||||||
var evalButton = evalButtonObj.GetComponent<Button>();
|
var evalButton = UIFactory.CreateButton(evalGroupObj,
|
||||||
var colors = evalButton.colors;
|
"EvalButton",
|
||||||
colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f);
|
$"Evaluate ({ParamCount})",
|
||||||
evalButton.colors = colors;
|
null,
|
||||||
|
colors);
|
||||||
|
|
||||||
var cancelButtonObj = UIFactory.CreateButton(evalGroupObj, new Color(0.3f, 0.3f, 0.3f));
|
UIFactory.SetLayoutElement(evalButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0);
|
||||||
var cancelLayout = cancelButtonObj.AddComponent<LayoutElement>();
|
|
||||||
cancelLayout.minWidth = 100;
|
|
||||||
cancelLayout.minHeight = 22;
|
|
||||||
cancelLayout.flexibleWidth = 0;
|
|
||||||
var cancelText = cancelButtonObj.GetComponentInChildren<Text>();
|
|
||||||
cancelText.text = "Close";
|
|
||||||
|
|
||||||
cancelButtonObj.SetActive(false);
|
var evalText = evalButton.GetComponentInChildren<Text>();
|
||||||
|
|
||||||
|
var cancelButton = UIFactory.CreateButton(evalGroupObj, "CancelButton", "Close", null, new Color(0.3f, 0.3f, 0.3f));
|
||||||
|
UIFactory.SetLayoutElement(cancelButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0);
|
||||||
|
|
||||||
|
cancelButton.gameObject.SetActive(false);
|
||||||
|
|
||||||
evalButton.onClick.AddListener(() =>
|
evalButton.onClick.AddListener(() =>
|
||||||
{
|
{
|
||||||
@ -407,11 +345,9 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
argsHolder.SetActive(true);
|
argsHolder.SetActive(true);
|
||||||
m_isEvaluating = true;
|
m_isEvaluating = true;
|
||||||
evalText.text = "Evaluate";
|
evalText.text = "Evaluate";
|
||||||
colors = evalButton.colors;
|
evalButton.colors = RuntimeProvider.Instance.SetColorBlock(evalButton.colors, new Color(0.3f, 0.6f, 0.3f));
|
||||||
colors.normalColor = new Color(0.3f, 0.6f, 0.3f);
|
|
||||||
evalButton.colors = colors;
|
|
||||||
|
|
||||||
cancelButtonObj.SetActive(true);
|
cancelButton.gameObject.SetActive(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -422,41 +358,26 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var cancelButton = cancelButtonObj.GetComponent<Button>();
|
|
||||||
cancelButton.onClick.AddListener(() =>
|
cancelButton.onClick.AddListener(() =>
|
||||||
{
|
{
|
||||||
cancelButtonObj.SetActive(false);
|
cancelButton.gameObject.SetActive(false);
|
||||||
argsHolder.SetActive(false);
|
argsHolder.SetActive(false);
|
||||||
m_isEvaluating = false;
|
m_isEvaluating = false;
|
||||||
|
|
||||||
evalText.text = $"Evaluate ({ParamCount})";
|
evalText.text = $"Evaluate ({ParamCount})";
|
||||||
colors = evalButton.colors;
|
evalButton.colors = RuntimeProvider.Instance.SetColorBlock(evalButton.colors, new Color(0.4f, 0.4f, 0.4f));
|
||||||
colors.normalColor = new Color(0.4f, 0.4f, 0.4f);
|
|
||||||
evalButton.colors = colors;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (this is CacheMethod)
|
else if (this is CacheMethod)
|
||||||
{
|
{
|
||||||
// simple method evaluate button
|
// simple method evaluate button
|
||||||
|
|
||||||
var evalButtonObj = UIFactory.CreateButton(m_rightGroup, new Color(0.3f, 0.6f, 0.3f));
|
var colors = new ColorBlock();
|
||||||
var evalLayout = evalButtonObj.AddComponent<LayoutElement>();
|
colors = RuntimeProvider.Instance.SetColorBlock(colors, new Color(0.4f, 0.4f, 0.4f),
|
||||||
evalLayout.minWidth = 100;
|
new Color(0.4f, 0.7f, 0.4f), new Color(0.3f, 0.3f, 0.3f));
|
||||||
evalLayout.minHeight = 22;
|
|
||||||
evalLayout.flexibleWidth = 0;
|
|
||||||
var evalText = evalButtonObj.GetComponentInChildren<Text>();
|
|
||||||
evalText.text = "Evaluate";
|
|
||||||
|
|
||||||
var evalButton = evalButtonObj.GetComponent<Button>();
|
var evalButton = UIFactory.CreateButton(m_rightGroup, "EvalButton", "Evaluate", () => { (this as CacheMethod).Evaluate(); }, colors);
|
||||||
var colors = evalButton.colors;
|
UIFactory.SetLayoutElement(evalButton.gameObject, minWidth: 100, minHeight: 22, flexibleWidth: 0);
|
||||||
colors.highlightedColor = new Color(0.4f, 0.7f, 0.4f);
|
|
||||||
evalButton.colors = colors;
|
|
||||||
|
|
||||||
evalButton.onClick.AddListener(OnMainEvaluateButton);
|
|
||||||
void OnMainEvaluateButton()
|
|
||||||
{
|
|
||||||
(this as CacheMethod).Evaluate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,7 +9,7 @@ using UnityExplorer.Core.Unity;
|
|||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.CacheObject
|
||||||
{
|
{
|
||||||
public class CacheMethod : CacheMember
|
public class CacheMethod : CacheMember
|
||||||
{
|
{
|
||||||
@ -130,15 +130,11 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
internal void ConstructGenericArgInput(GameObject parent)
|
internal void ConstructGenericArgInput(GameObject parent)
|
||||||
{
|
{
|
||||||
var titleObj = UIFactory.CreateLabel(parent, TextAnchor.MiddleLeft);
|
UIFactory.CreateLabel(parent, "GenericArgLabel", "Generic Arguments:", TextAnchor.MiddleLeft);
|
||||||
var titleText = titleObj.GetComponent<Text>();
|
|
||||||
titleText.text = "<b>Generic Arguments:</b>";
|
|
||||||
|
|
||||||
for (int i = 0; i < GenericArgs.Length; i++)
|
for (int i = 0; i < GenericArgs.Length; i++)
|
||||||
{
|
|
||||||
AddGenericArgRow(i, parent);
|
AddGenericArgRow(i, parent);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
internal void AddGenericArgRow(int i, GameObject parent)
|
internal void AddGenericArgRow(int i, GameObject parent)
|
||||||
{
|
{
|
||||||
@ -158,33 +154,18 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
else
|
else
|
||||||
constrainTxt = $"Any";
|
constrainTxt = $"Any";
|
||||||
|
|
||||||
var rowObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
var rowObj = UIFactory.CreateHorizontalGroup(parent, "ArgRowObj", false, true, true, true, 4, default, new Color(1, 1, 1, 0));
|
||||||
var rowLayout = rowObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 5000);
|
||||||
rowLayout.minHeight = 25;
|
|
||||||
rowLayout.flexibleWidth = 5000;
|
|
||||||
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
rowGroup.childForceExpandHeight = true;
|
|
||||||
rowGroup.spacing = 4;
|
|
||||||
|
|
||||||
var argLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
var argLabelObj = UIFactory.CreateLabel(rowObj, "ArgLabelObj", $"{constrainTxt} <color={SignatureHighlighter.CONST_VAR}>{arg.Name}</color>",
|
||||||
//var argLayout = argLabelObj.AddComponent<LayoutElement>();
|
TextAnchor.MiddleLeft);
|
||||||
//argLayout.minWidth = 20;
|
|
||||||
var argText = argLabelObj.GetComponent<Text>();
|
|
||||||
argText.text = $"{constrainTxt} <color={SignatureHighlighter.CONST_VAR}>{arg.Name}</color>";
|
|
||||||
|
|
||||||
var argInputObj = UIFactory.CreateInputField(rowObj, 14, (int)TextAnchor.MiddleLeft, 1);
|
var argInputObj = UIFactory.CreateInputField(rowObj, "ArgInput", "...", 14, (int)TextAnchor.MiddleLeft, 1);
|
||||||
var argInputLayout = argInputObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(argInputObj, flexibleWidth: 1200);
|
||||||
argInputLayout.flexibleWidth = 1200;
|
|
||||||
|
|
||||||
var argInput = argInputObj.GetComponent<InputField>();
|
var argInput = argInputObj.GetComponent<InputField>();
|
||||||
argInput.onValueChanged.AddListener((string val) => { m_genericArgInput[i] = val; });
|
argInput.onValueChanged.AddListener((string val) => { m_genericArgInput[i] = val; });
|
||||||
|
|
||||||
//var constraintLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
|
||||||
//var constraintLayout = constraintLabelObj.AddComponent<LayoutElement>();
|
|
||||||
//constraintLayout.minWidth = 60;
|
|
||||||
//constraintLayout.flexibleWidth = 100;
|
|
||||||
//var constraintText = constraintLabelObj.GetComponent<Text>();
|
|
||||||
//constraintText.text = ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
@ -4,12 +4,12 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Reusable;
|
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.UI.InteractiveValues;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.CacheObject
|
||||||
{
|
{
|
||||||
public abstract class CacheObjectBase
|
public abstract class CacheObjectBase
|
||||||
{
|
{
|
||||||
@ -86,33 +86,18 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
m_constructedUI = true;
|
m_constructedUI = true;
|
||||||
|
|
||||||
m_mainContent = UIFactory.CreateVerticalGroup(m_parentContent, new Color(0.1f, 0.1f, 0.1f));
|
m_mainContent = UIFactory.CreateVerticalGroup(m_parentContent, "CacheObjectBase.MainContent", true, true, true, true, 0, default,
|
||||||
m_mainContent.name = "CacheObjectBase.MainContent";
|
new Color(0.1f, 0.1f, 0.1f));
|
||||||
m_mainRect = m_mainContent.GetComponent<RectTransform>();
|
m_mainRect = m_mainContent.GetComponent<RectTransform>();
|
||||||
m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||||
var mainGroup = m_mainContent.GetComponent<VerticalLayoutGroup>();
|
|
||||||
mainGroup.childForceExpandWidth = true;
|
UIFactory.SetLayoutElement(m_mainContent, minHeight: 25, flexibleHeight: 9999, minWidth: 200, flexibleWidth: 5000);
|
||||||
mainGroup.childControlWidth = true;
|
|
||||||
mainGroup.childForceExpandHeight = true;
|
|
||||||
mainGroup.childControlHeight = true;
|
|
||||||
var mainLayout = m_mainContent.AddComponent<LayoutElement>();
|
|
||||||
mainLayout.minHeight = 25;
|
|
||||||
mainLayout.flexibleHeight = 9999;
|
|
||||||
mainLayout.minWidth = 200;
|
|
||||||
mainLayout.flexibleWidth = 5000;
|
|
||||||
|
|
||||||
// subcontent
|
// subcontent
|
||||||
|
|
||||||
m_subContent = UIFactory.CreateVerticalGroup(m_mainContent, new Color(0.085f, 0.085f, 0.085f));
|
m_subContent = UIFactory.CreateVerticalGroup(m_mainContent, "CacheObjectBase.SubContent", true, false, true, true, 0, default,
|
||||||
m_subContent.name = "CacheObjectBase.SubContent";
|
new Color(0.085f, 0.085f, 0.085f));
|
||||||
var subGroup = m_subContent.GetComponent<VerticalLayoutGroup>();
|
UIFactory.SetLayoutElement(m_subContent, minHeight: 30, flexibleHeight: 9999, minWidth: 125, flexibleWidth: 9000);
|
||||||
subGroup.childForceExpandWidth = true;
|
|
||||||
subGroup.childForceExpandHeight = false;
|
|
||||||
var subLayout = m_subContent.AddComponent<LayoutElement>();
|
|
||||||
subLayout.minHeight = 30;
|
|
||||||
subLayout.flexibleHeight = 9999;
|
|
||||||
subLayout.minWidth = 125;
|
|
||||||
subLayout.flexibleWidth = 9000;
|
|
||||||
|
|
||||||
m_subContent.SetActive(false);
|
m_subContent.SetActive(false);
|
||||||
|
|
@ -6,9 +6,9 @@ using System.Text;
|
|||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.UI.InteractiveValues;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.CacheObject
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
|
||||||
{
|
{
|
||||||
public enum PairTypes
|
public enum PairTypes
|
||||||
{
|
{
|
||||||
@ -50,18 +50,15 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
base.ConstructUI();
|
base.ConstructUI();
|
||||||
|
|
||||||
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0));
|
Color bgColor = this.PairType == PairTypes.Key
|
||||||
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
? new Color(0.07f, 0.07f, 0.07f)
|
||||||
rowGroup.padding.left = 5;
|
: new Color(0.1f, 0.1f, 0.1f);
|
||||||
rowGroup.padding.right = 2;
|
|
||||||
|
|
||||||
var indexLabelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
|
var rowObj = UIFactory.CreateHorizontalGroup(m_mainContent, "PairedGroup", false, false, true, true, 0, new Vector4(0,0,5,2),
|
||||||
var indexLayout = indexLabelObj.AddComponent<LayoutElement>();
|
bgColor);
|
||||||
indexLayout.minWidth = 80;
|
|
||||||
indexLayout.flexibleWidth = 30;
|
var indexLabel = UIFactory.CreateLabel(rowObj, "IndexLabel", $"{this.PairType} {this.Index}:", TextAnchor.MiddleLeft);
|
||||||
indexLayout.minHeight = 25;
|
UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 80, flexibleWidth: 30, minHeight: 25);
|
||||||
var indexText = indexLabelObj.GetComponent<Text>();
|
|
||||||
indexText.text = $"{this.PairType} {this.Index}:";
|
|
||||||
|
|
||||||
IValue.m_mainContentParent = rowObj;
|
IValue.m_mainContentParent = rowObj;
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ using UnityExplorer.UI;
|
|||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.CacheObject
|
||||||
{
|
{
|
||||||
public class CacheProperty : CacheMember
|
public class CacheProperty : CacheMember
|
||||||
{
|
{
|
@ -6,8 +6,9 @@ using UnityEngine;
|
|||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
|
using UnityExplorer.UI.CacheObject;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
public class InteractiveBool : InteractiveValue
|
public class InteractiveBool : InteractiveValue
|
||||||
{
|
{
|
||||||
@ -87,27 +88,22 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
if (Owner.CanWrite)
|
if (Owner.CanWrite)
|
||||||
{
|
{
|
||||||
var toggleObj = UIFactory.CreateToggle(m_valueContent, out m_toggle, out _, new Color(0.1f, 0.1f, 0.1f));
|
var toggleObj = UIFactory.CreateToggle(m_mainContent, "InteractiveBoolToggle", out m_toggle, out _, new Color(0.1f, 0.1f, 0.1f));
|
||||||
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(toggleObj, minWidth: 24);
|
||||||
toggleLayout.minWidth = 24;
|
|
||||||
|
|
||||||
m_toggle.onValueChanged.AddListener(OnToggleValueChanged);
|
m_toggle.onValueChanged.AddListener(OnToggleValueChanged);
|
||||||
|
|
||||||
m_baseLabel.transform.SetAsLastSibling();
|
m_baseLabel.transform.SetAsLastSibling();
|
||||||
|
|
||||||
var applyBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.2f, 0.2f, 0.2f));
|
m_applyBtn = UIFactory.CreateButton(m_mainContent,
|
||||||
var applyLayout = applyBtnObj.AddComponent<LayoutElement>();
|
"ApplyButton",
|
||||||
applyLayout.minWidth = 50;
|
"Apply",
|
||||||
applyLayout.minHeight = 25;
|
() => { Owner.SetValue(); },
|
||||||
applyLayout.flexibleWidth = 0;
|
new Color(0.2f, 0.2f, 0.2f));
|
||||||
m_applyBtn = applyBtnObj.GetComponent<Button>();
|
|
||||||
m_applyBtn.onClick.AddListener(() => { Owner.SetValue(); });
|
|
||||||
|
|
||||||
var applyText = applyBtnObj.GetComponentInChildren<Text>();
|
UIFactory.SetLayoutElement(m_applyBtn.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0);
|
||||||
applyText.text = "Apply";
|
|
||||||
|
|
||||||
toggleObj.SetActive(false);
|
toggleObj.SetActive(false);
|
||||||
applyBtnObj.SetActive(false);
|
m_applyBtn.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
168
src/UI/InteractiveValues/InteractiveColor.cs
Normal file
168
src/UI/InteractiveValues/InteractiveColor.cs
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
|
{
|
||||||
|
public class InteractiveColor : InteractiveValue
|
||||||
|
{
|
||||||
|
//~~~~~~~~~ Instance ~~~~~~~~~~
|
||||||
|
|
||||||
|
public InteractiveColor(object value, Type valueType) : base(value, valueType) { }
|
||||||
|
|
||||||
|
public override bool HasSubContent => true;
|
||||||
|
public override bool SubContentWanted => true;
|
||||||
|
public override bool WantInspectBtn => true;
|
||||||
|
|
||||||
|
public override void RefreshUIForValue()
|
||||||
|
{
|
||||||
|
base.RefreshUIForValue();
|
||||||
|
|
||||||
|
if (m_subContentConstructed)
|
||||||
|
RefreshUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshUI()
|
||||||
|
{
|
||||||
|
var color = (Color)this.Value;
|
||||||
|
|
||||||
|
m_inputs[0].text = color.r.ToString();
|
||||||
|
m_inputs[1].text = color.g.ToString();
|
||||||
|
m_inputs[2].text = color.b.ToString();
|
||||||
|
m_inputs[3].text = color.a.ToString();
|
||||||
|
|
||||||
|
if (m_colorImage)
|
||||||
|
m_colorImage.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void OnToggleSubcontent(bool toggle)
|
||||||
|
{
|
||||||
|
base.OnToggleSubcontent(toggle);
|
||||||
|
|
||||||
|
RefreshUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
|
private Image m_colorImage;
|
||||||
|
|
||||||
|
private readonly InputField[] m_inputs = new InputField[4];
|
||||||
|
private readonly Slider[] m_sliders = new Slider[4];
|
||||||
|
|
||||||
|
public override void ConstructUI(GameObject parent, GameObject subGroup)
|
||||||
|
{
|
||||||
|
base.ConstructUI(parent, subGroup);
|
||||||
|
|
||||||
|
//// Limit the label width for colors, they're always about the same so make use of that space.
|
||||||
|
//UIFactory.SetLayoutElement(this.m_baseLabel.gameObject, flexibleWidth: 0, minWidth: 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ConstructSubcontent()
|
||||||
|
{
|
||||||
|
base.ConstructSubcontent();
|
||||||
|
|
||||||
|
var horiGroup = UIFactory.CreateHorizontalGroup(m_subContentParent, "ColorEditor", false, false, true, true, 5,
|
||||||
|
default, default, TextAnchor.MiddleLeft);
|
||||||
|
|
||||||
|
var editorContainer = UIFactory.CreateVerticalGroup(horiGroup, "EditorContent", false, true, true, true, 2, new Vector4(4, 4, 4, 4),
|
||||||
|
new Color(0.08f, 0.08f, 0.08f));
|
||||||
|
UIFactory.SetLayoutElement(editorContainer, minWidth: 300, flexibleWidth: 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
AddEditorRow(i, editorContainer);
|
||||||
|
|
||||||
|
if (Owner.CanWrite)
|
||||||
|
{
|
||||||
|
var applyBtn = UIFactory.CreateButton(editorContainer, "ApplyButton", "Apply", OnSetValue, new Color(0.2f, 0.2f, 0.2f));
|
||||||
|
UIFactory.SetLayoutElement(applyBtn.gameObject, minWidth: 175, minHeight: 25, flexibleWidth: 0);
|
||||||
|
|
||||||
|
void OnSetValue()
|
||||||
|
{
|
||||||
|
Owner.SetValue();
|
||||||
|
RefreshUIForValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var imgHolder = UIFactory.CreateVerticalGroup(horiGroup, "ImgHolder", true, true, true, true, 0, new Vector4(1, 1, 1, 1),
|
||||||
|
new Color(0.08f, 0.08f, 0.08f));
|
||||||
|
UIFactory.SetLayoutElement(imgHolder, minWidth: 128, minHeight: 128, flexibleWidth: 0, flexibleHeight: 0);
|
||||||
|
|
||||||
|
var imgObj = UIFactory.CreateUIObject("ColorImageHelper", imgHolder, new Vector2(100, 25));
|
||||||
|
m_colorImage = imgObj.AddComponent<Image>();
|
||||||
|
m_colorImage.color = (Color)this.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly string[] s_fieldNames = new[] { "R", "G", "B", "A" };
|
||||||
|
|
||||||
|
internal void AddEditorRow(int index, GameObject groupObj)
|
||||||
|
{
|
||||||
|
var row = UIFactory.CreateHorizontalGroup(groupObj, "EditorRow_" + s_fieldNames[index],
|
||||||
|
false, true, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
|
|
||||||
|
var label = UIFactory.CreateLabel(row, "RowLabel", $"{s_fieldNames[index]}:", TextAnchor.MiddleRight, Color.cyan);
|
||||||
|
UIFactory.SetLayoutElement(label.gameObject, minWidth: 50, flexibleWidth: 0, minHeight: 25);
|
||||||
|
|
||||||
|
var inputFieldObj = UIFactory.CreateInputField(row, "InputField", "...", 14, 3, 1);
|
||||||
|
UIFactory.SetLayoutElement(inputFieldObj, minWidth: 120, minHeight: 25, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var inputField = inputFieldObj.GetComponent<InputField>();
|
||||||
|
m_inputs[index] = inputField;
|
||||||
|
inputField.characterValidation = InputField.CharacterValidation.Decimal;
|
||||||
|
|
||||||
|
inputField.onValueChanged.AddListener((string value) =>
|
||||||
|
{
|
||||||
|
float val = float.Parse(value);
|
||||||
|
SetValueToColor(val);
|
||||||
|
m_sliders[index].value = val;
|
||||||
|
});
|
||||||
|
|
||||||
|
var sliderObj = UIFactory.CreateSlider(row, "Slider", out Slider slider);
|
||||||
|
m_sliders[index] = slider;
|
||||||
|
UIFactory.SetLayoutElement(sliderObj, minWidth: 200, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||||
|
slider.minValue = 0;
|
||||||
|
slider.maxValue = 1;
|
||||||
|
slider.value = GetValueFromColor();
|
||||||
|
|
||||||
|
slider.onValueChanged.AddListener((float value) =>
|
||||||
|
{
|
||||||
|
inputField.text = value.ToString();
|
||||||
|
SetValueToColor(value);
|
||||||
|
m_inputs[index].text = value.ToString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// methods for writing to the color for this field
|
||||||
|
|
||||||
|
void SetValueToColor(float floatValue)
|
||||||
|
{
|
||||||
|
Color _color = (Color)Value;
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: _color.r = floatValue; break;
|
||||||
|
case 1: _color.g = floatValue; break;
|
||||||
|
case 2: _color.b = floatValue; break;
|
||||||
|
case 3: _color.a = floatValue; break;
|
||||||
|
}
|
||||||
|
Value = _color;
|
||||||
|
m_colorImage.color = _color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetValueFromColor()
|
||||||
|
{
|
||||||
|
Color _color = (Color)Value;
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return _color.r;
|
||||||
|
case 1: return _color.g;
|
||||||
|
case 2: return _color.b;
|
||||||
|
case 3: return _color.a;
|
||||||
|
default: throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -8,13 +8,15 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.Core.Config;
|
using UnityExplorer.Core.Config;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Reusable;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using UnityExplorer.UI.CacheObject;
|
||||||
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.UI.Utility;
|
||||||
#if CPP
|
#if CPP
|
||||||
using CppDictionary = Il2CppSystem.Collections.IDictionary;
|
using CppDictionary = Il2CppSystem.Collections.IDictionary;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
public class InteractiveDictionary : InteractiveValue
|
public class InteractiveDictionary : InteractiveValue
|
||||||
{
|
{
|
||||||
@ -35,7 +37,6 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
public override bool WantInspectBtn => false;
|
public override bool WantInspectBtn => false;
|
||||||
public override bool HasSubContent => true;
|
public override bool HasSubContent => true;
|
||||||
// todo fix for il2cpp
|
|
||||||
public override bool SubContentWanted
|
public override bool SubContentWanted
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -59,7 +60,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
= new List<KeyValuePair<CachePaired, CachePaired>>();
|
= new List<KeyValuePair<CachePaired, CachePaired>>();
|
||||||
|
|
||||||
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
|
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
|
||||||
= new KeyValuePair<CachePaired, CachePaired>[ExplorerConfig.Instance.Default_Page_Limit];
|
= new KeyValuePair<CachePaired, CachePaired>[ConfigManager.Default_Page_Limit.Value];
|
||||||
|
|
||||||
internal bool m_recacheWanted = true;
|
internal bool m_recacheWanted = true;
|
||||||
|
|
||||||
@ -217,7 +218,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
private IDictionary EnumerateWithReflection()
|
private IDictionary EnumerateWithReflection()
|
||||||
{
|
{
|
||||||
var valueType = Value?.GetType() ?? FallbackType;
|
var valueType = ReflectionUtility.GetType(Value);
|
||||||
|
|
||||||
// get keys and values
|
// get keys and values
|
||||||
var keys = valueType.GetProperty("Keys").GetValue(Value, null);
|
var keys = valueType.GetProperty("Keys").GetValue(Value, null);
|
||||||
@ -283,38 +284,23 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
m_pageHandler.ConstructUI(m_subContentParent);
|
m_pageHandler.ConstructUI(m_subContentParent);
|
||||||
m_pageHandler.OnPageChanged += OnPageTurned;
|
m_pageHandler.OnPageChanged += OnPageTurned;
|
||||||
|
|
||||||
var scrollObj = UIFactory.CreateVerticalGroup(this.m_subContentParent, new Color(0.08f, 0.08f, 0.08f));
|
m_listContent = UIFactory.CreateVerticalGroup(m_subContentParent, "DictionaryContent", true, true, true, true, 2, new Vector4(5,5,5,5),
|
||||||
m_listContent = scrollObj;
|
new Color(0.08f, 0.08f, 0.08f));
|
||||||
|
|
||||||
var scrollRect = scrollObj.GetComponent<RectTransform>();
|
var scrollRect = m_listContent.GetComponent<RectTransform>();
|
||||||
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
|
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
|
||||||
|
|
||||||
m_listLayout = Owner.m_mainContent.GetComponent<LayoutElement>();
|
m_listLayout = Owner.m_mainContent.GetComponent<LayoutElement>();
|
||||||
m_listLayout.minHeight = 25;
|
m_listLayout.minHeight = 25;
|
||||||
m_listLayout.flexibleHeight = 0;
|
m_listLayout.flexibleHeight = 0;
|
||||||
|
|
||||||
Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||||
|
|
||||||
var scrollGroup = m_listContent.GetComponent<VerticalLayoutGroup>();
|
var contentFitter = m_listContent.AddComponent<ContentSizeFitter>();
|
||||||
scrollGroup.childForceExpandHeight = true;
|
|
||||||
scrollGroup.childControlHeight = true;
|
|
||||||
scrollGroup.spacing = 2;
|
|
||||||
scrollGroup.padding.top = 5;
|
|
||||||
scrollGroup.padding.left = 5;
|
|
||||||
scrollGroup.padding.right = 5;
|
|
||||||
scrollGroup.padding.bottom = 5;
|
|
||||||
|
|
||||||
var contentFitter = scrollObj.AddComponent<ContentSizeFitter>();
|
|
||||||
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||||
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
//internal void AddRowHolder()
|
|
||||||
//{
|
|
||||||
// var obj = UIFactory.CreateHorizontalGroup(m_listContent, new Color(0.15f, 0.15f, 0.15f));
|
|
||||||
|
|
||||||
// m_rowHolders.Add(obj);
|
|
||||||
//}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
public class InteractiveEnum : InteractiveValue
|
public class InteractiveEnum : InteractiveValue
|
||||||
{
|
{
|
||||||
@ -136,32 +136,18 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
if (Owner.CanWrite)
|
if (Owner.CanWrite)
|
||||||
{
|
{
|
||||||
var groupObj = UIFactory.CreateHorizontalGroup(m_subContentParent, new Color(1, 1, 1, 0));
|
var groupObj = UIFactory.CreateHorizontalGroup(m_subContentParent, "InteractiveEnumGroup", false, true, true, true, 5,
|
||||||
var group = groupObj.GetComponent<HorizontalLayoutGroup>();
|
new Vector4(3,3,3,3),new Color(1, 1, 1, 0));
|
||||||
group.padding.top = 3;
|
|
||||||
group.padding.left = 3;
|
|
||||||
group.padding.right = 3;
|
|
||||||
group.padding.bottom = 3;
|
|
||||||
group.spacing = 5;
|
|
||||||
|
|
||||||
// apply button
|
// apply button
|
||||||
|
|
||||||
var applyObj = UIFactory.CreateButton(groupObj, new Color(0.3f, 0.3f, 0.3f));
|
var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", SetValueFromDropdown, new Color(0.3f, 0.3f, 0.3f));
|
||||||
var applyLayout = applyObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(apply.gameObject, minHeight: 25, minWidth: 50);
|
||||||
applyLayout.minHeight = 25;
|
|
||||||
applyLayout.minWidth = 50;
|
|
||||||
var applyText = applyObj.GetComponentInChildren<Text>();
|
|
||||||
applyText.text = "Apply";
|
|
||||||
var applyBtn = applyObj.GetComponent<Button>();
|
|
||||||
applyBtn.onClick.AddListener(SetValueFromDropdown);
|
|
||||||
|
|
||||||
// dropdown
|
// dropdown
|
||||||
|
|
||||||
var dropdownObj = UIFactory.CreateDropdown(groupObj, out m_dropdown);
|
var dropdownObj = UIFactory.CreateDropdown(groupObj, out m_dropdown, "", 14, null);
|
||||||
var dropLayout = dropdownObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(dropdownObj, minWidth: 150, minHeight: 25, flexibleWidth: 120);
|
||||||
dropLayout.minWidth = 150;
|
|
||||||
dropLayout.minHeight = 25;
|
|
||||||
dropLayout.flexibleWidth = 120;
|
|
||||||
|
|
||||||
foreach (var kvp in m_values)
|
foreach (var kvp in m_values)
|
||||||
{
|
{
|
@ -9,9 +9,10 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.Core.Config;
|
using UnityExplorer.Core.Config;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Reusable;
|
using UnityExplorer.UI.CacheObject;
|
||||||
|
using UnityExplorer.UI.Utility;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
public class InteractiveEnumerable : InteractiveValue
|
public class InteractiveEnumerable : InteractiveValue
|
||||||
{
|
{
|
||||||
@ -46,7 +47,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
internal readonly Type m_baseEntryType;
|
internal readonly Type m_baseEntryType;
|
||||||
|
|
||||||
internal readonly List<CacheEnumerated> m_entries = new List<CacheEnumerated>();
|
internal readonly List<CacheEnumerated> m_entries = new List<CacheEnumerated>();
|
||||||
internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ExplorerConfig.Instance.Default_Page_Limit];
|
internal readonly CacheEnumerated[] m_displayedEntries = new CacheEnumerated[ConfigManager.Default_Page_Limit.Value];
|
||||||
internal bool m_recacheWanted = true;
|
internal bool m_recacheWanted = true;
|
||||||
|
|
||||||
public override void OnValueUpdated()
|
public override void OnValueUpdated()
|
||||||
@ -257,10 +258,10 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
m_pageHandler.ConstructUI(m_subContentParent);
|
m_pageHandler.ConstructUI(m_subContentParent);
|
||||||
m_pageHandler.OnPageChanged += OnPageTurned;
|
m_pageHandler.OnPageChanged += OnPageTurned;
|
||||||
|
|
||||||
var scrollObj = UIFactory.CreateVerticalGroup(this.m_subContentParent, new Color(0.08f, 0.08f, 0.08f));
|
m_listContent = UIFactory.CreateVerticalGroup(this.m_subContentParent, "EnumerableContent", true, true, true, true, 2, new Vector4(5,5,5,5),
|
||||||
m_listContent = scrollObj;
|
new Color(0.08f, 0.08f, 0.08f));
|
||||||
|
|
||||||
var scrollRect = scrollObj.GetComponent<RectTransform>();
|
var scrollRect = m_listContent.GetComponent<RectTransform>();
|
||||||
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
|
scrollRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
|
||||||
|
|
||||||
m_listLayout = Owner.m_mainContent.GetComponent<LayoutElement>();
|
m_listLayout = Owner.m_mainContent.GetComponent<LayoutElement>();
|
||||||
@ -268,16 +269,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
m_listLayout.flexibleHeight = 0;
|
m_listLayout.flexibleHeight = 0;
|
||||||
Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
Owner.m_mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||||
|
|
||||||
var scrollGroup = m_listContent.GetComponent<VerticalLayoutGroup>();
|
var contentFitter = m_listContent.AddComponent<ContentSizeFitter>();
|
||||||
scrollGroup.childForceExpandHeight = true;
|
|
||||||
scrollGroup.childControlHeight = true;
|
|
||||||
scrollGroup.spacing = 2;
|
|
||||||
scrollGroup.padding.top = 5;
|
|
||||||
scrollGroup.padding.left = 5;
|
|
||||||
scrollGroup.padding.right = 5;
|
|
||||||
scrollGroup.padding.bottom = 5;
|
|
||||||
|
|
||||||
var contentFitter = scrollObj.AddComponent<ContentSizeFitter>();
|
|
||||||
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
contentFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||||
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
public class InteractiveFlags : InteractiveEnum
|
public class InteractiveFlags : InteractiveEnum
|
||||||
{
|
{
|
||||||
@ -94,47 +94,27 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
if (Owner.CanWrite)
|
if (Owner.CanWrite)
|
||||||
{
|
{
|
||||||
var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, new Color(1, 1, 1, 0));
|
var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, "InteractiveFlagsContent", false, true, true, true, 5,
|
||||||
var group = groupObj.GetComponent<VerticalLayoutGroup>();
|
new Vector4(3,3,3,3), new Color(1, 1, 1, 0));
|
||||||
group.childForceExpandHeight = true;
|
|
||||||
group.childForceExpandWidth = false;
|
|
||||||
group.childControlHeight = true;
|
|
||||||
group.childControlWidth = true;
|
|
||||||
group.padding.top = 3;
|
|
||||||
group.padding.left = 3;
|
|
||||||
group.padding.right = 3;
|
|
||||||
group.padding.bottom = 3;
|
|
||||||
group.spacing = 5;
|
|
||||||
|
|
||||||
// apply button
|
// apply button
|
||||||
|
|
||||||
var applyObj = UIFactory.CreateButton(groupObj, new Color(0.3f, 0.3f, 0.3f));
|
var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", SetValueFromToggles, new Color(0.3f, 0.3f, 0.3f));
|
||||||
var applyLayout = applyObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(apply.gameObject, minWidth: 50, minHeight: 25);
|
||||||
applyLayout.minHeight = 25;
|
|
||||||
applyLayout.minWidth = 50;
|
|
||||||
var applyText = applyObj.GetComponentInChildren<Text>();
|
|
||||||
applyText.text = "Apply";
|
|
||||||
var applyBtn = applyObj.GetComponent<Button>();
|
|
||||||
applyBtn.onClick.AddListener(SetValueFromToggles);
|
|
||||||
|
|
||||||
// toggles
|
// toggles
|
||||||
|
|
||||||
for (int i = 0; i < m_values.Length; i++)
|
for (int i = 0; i < m_values.Length; i++)
|
||||||
{
|
|
||||||
AddToggle(i, groupObj);
|
AddToggle(i, groupObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
internal void AddToggle(int index, GameObject groupObj)
|
internal void AddToggle(int index, GameObject groupObj)
|
||||||
{
|
{
|
||||||
var value = m_values[index];
|
var value = m_values[index];
|
||||||
|
|
||||||
var toggleObj = UIFactory.CreateToggle(groupObj, out Toggle toggle, out Text text, new Color(0.1f, 0.1f, 0.1f));
|
var toggleObj = UIFactory.CreateToggle(groupObj, "FlagToggle", out Toggle toggle, out Text text, new Color(0.1f, 0.1f, 0.1f));
|
||||||
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(toggleObj, minWidth: 100, flexibleWidth: 2000, minHeight: 25);
|
||||||
toggleLayout.minWidth = 100;
|
|
||||||
toggleLayout.flexibleWidth = 2000;
|
|
||||||
toggleLayout.minHeight = 25;
|
|
||||||
|
|
||||||
m_toggles[index] = toggle;
|
m_toggles[index] = toggle;
|
||||||
|
|
@ -9,8 +9,9 @@ using UnityExplorer.Core.Unity;
|
|||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
|
using UnityExplorer.UI.CacheObject;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
public class InteractiveNumber : InteractiveValue
|
public class InteractiveNumber : InteractiveValue
|
||||||
{
|
{
|
||||||
@ -101,27 +102,16 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
labelLayout.minWidth = 50;
|
labelLayout.minWidth = 50;
|
||||||
labelLayout.flexibleWidth = 0;
|
labelLayout.flexibleWidth = 0;
|
||||||
|
|
||||||
var inputObj = UIFactory.CreateInputField(m_valueContent);
|
var inputObj = UIFactory.CreateInputField(m_mainContent, "InteractiveNumberInput", "...");
|
||||||
var inputLayout = inputObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(inputObj, minWidth: 120, minHeight: 25, flexibleWidth: 0);
|
||||||
inputLayout.minWidth = 120;
|
|
||||||
inputLayout.minHeight = 25;
|
|
||||||
inputLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
m_valueInput = inputObj.GetComponent<InputField>();
|
m_valueInput = inputObj.GetComponent<InputField>();
|
||||||
m_valueInput.gameObject.SetActive(false);
|
m_valueInput.gameObject.SetActive(false);
|
||||||
|
|
||||||
if (Owner.CanWrite)
|
if (Owner.CanWrite)
|
||||||
{
|
{
|
||||||
var applyBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.2f, 0.2f, 0.2f));
|
m_applyBtn = UIFactory.CreateButton(m_mainContent, "ApplyButton", "Apply", OnApplyClicked, new Color(0.2f, 0.2f, 0.2f));
|
||||||
var applyLayout = applyBtnObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(m_applyBtn.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0);
|
||||||
applyLayout.minWidth = 50;
|
|
||||||
applyLayout.minHeight = 25;
|
|
||||||
applyLayout.flexibleWidth = 0;
|
|
||||||
m_applyBtn = applyBtnObj.GetComponent<Button>();
|
|
||||||
m_applyBtn.onClick.AddListener(OnApplyClicked);
|
|
||||||
|
|
||||||
var applyText = applyBtnObj.GetComponentInChildren<Text>();
|
|
||||||
applyText.text = "Apply";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,8 +8,9 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
|
using UnityExplorer.UI.CacheObject;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
public class InteractiveString : InteractiveValue
|
public class InteractiveString : InteractiveValue
|
||||||
{
|
{
|
||||||
@ -114,32 +115,23 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
m_labelLayout = m_baseLabel.gameObject.GetComponent<LayoutElement>();
|
m_labelLayout = m_baseLabel.gameObject.GetComponent<LayoutElement>();
|
||||||
|
|
||||||
var readonlyInputObj = UIFactory.CreateLabel(m_valueContent, TextAnchor.MiddleLeft);
|
m_readonlyInput = UIFactory.CreateLabel(m_mainContent, "ReadonlyLabel", "", TextAnchor.MiddleLeft);
|
||||||
m_readonlyInput = readonlyInputObj.GetComponent<Text>();
|
|
||||||
m_readonlyInput.horizontalOverflow = HorizontalWrapMode.Overflow;
|
m_readonlyInput.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
|
||||||
var testFitter = readonlyInputObj.AddComponent<ContentSizeFitter>();
|
var testFitter = m_readonlyInput.gameObject.AddComponent<ContentSizeFitter>();
|
||||||
testFitter.verticalFit = ContentSizeFitter.FitMode.MinSize;
|
testFitter.verticalFit = ContentSizeFitter.FitMode.MinSize;
|
||||||
|
|
||||||
var labelLayout = readonlyInputObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(m_readonlyInput.gameObject, minHeight: 25, preferredHeight: 25, flexibleHeight: 0);
|
||||||
labelLayout.minHeight = 25;
|
|
||||||
labelLayout.preferredHeight = 25;
|
|
||||||
labelLayout.flexibleHeight = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ConstructSubcontent()
|
public override void ConstructSubcontent()
|
||||||
{
|
{
|
||||||
base.ConstructSubcontent();
|
base.ConstructSubcontent();
|
||||||
|
|
||||||
var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, new Color(1, 1, 1, 0));
|
var groupObj = UIFactory.CreateVerticalGroup(m_subContentParent, "SubContent", false, false, true, true, 4, new Vector4(3,3,3,3),
|
||||||
var group = groupObj.GetComponent<VerticalLayoutGroup>();
|
new Color(1, 1, 1, 0));
|
||||||
group.spacing = 4;
|
|
||||||
group.padding.top = 3;
|
|
||||||
group.padding.left = 3;
|
|
||||||
group.padding.right = 3;
|
|
||||||
group.padding.bottom = 3;
|
|
||||||
|
|
||||||
m_hiddenObj = UIFactory.CreateLabel(groupObj, TextAnchor.MiddleLeft);
|
m_hiddenObj = UIFactory.CreateLabel(groupObj, "HiddenLabel", "", TextAnchor.MiddleLeft).gameObject;
|
||||||
m_hiddenObj.SetActive(false);
|
m_hiddenObj.SetActive(false);
|
||||||
var hiddenText = m_hiddenObj.GetComponent<Text>();
|
var hiddenText = m_hiddenObj.GetComponent<Text>();
|
||||||
hiddenText.color = Color.clear;
|
hiddenText.color = Color.clear;
|
||||||
@ -148,23 +140,11 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
hiddenText.supportRichText = false;
|
hiddenText.supportRichText = false;
|
||||||
var hiddenFitter = m_hiddenObj.AddComponent<ContentSizeFitter>();
|
var hiddenFitter = m_hiddenObj.AddComponent<ContentSizeFitter>();
|
||||||
hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
var hiddenLayout = m_hiddenObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(m_hiddenObj, minHeight: 25, flexibleHeight: 500, minWidth: 250, flexibleWidth: 9000);
|
||||||
hiddenLayout.minHeight = 25;
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(m_hiddenObj, true, true, true, true);
|
||||||
hiddenLayout.flexibleHeight = 500;
|
|
||||||
hiddenLayout.minWidth = 250;
|
|
||||||
hiddenLayout.flexibleWidth = 9000;
|
|
||||||
var hiddenGroup = m_hiddenObj.AddComponent<HorizontalLayoutGroup>();
|
|
||||||
hiddenGroup.childForceExpandWidth = true;
|
|
||||||
hiddenGroup.childControlWidth = true;
|
|
||||||
hiddenGroup.childForceExpandHeight = true;
|
|
||||||
hiddenGroup.childControlHeight = true;
|
|
||||||
|
|
||||||
var inputObj = UIFactory.CreateInputField(m_hiddenObj, 14, 3);
|
var inputObj = UIFactory.CreateInputField(m_hiddenObj, "StringInputField", "...", 14, 3);
|
||||||
var inputLayout = inputObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(inputObj, minWidth: 120, minHeight: 25, flexibleWidth: 5000, flexibleHeight: 5000);
|
||||||
inputLayout.minWidth = 120;
|
|
||||||
inputLayout.minHeight = 25;
|
|
||||||
inputLayout.flexibleWidth = 5000;
|
|
||||||
inputLayout.flexibleHeight = 5000;
|
|
||||||
|
|
||||||
m_valueInput = inputObj.GetComponent<InputField>();
|
m_valueInput = inputObj.GetComponent<InputField>();
|
||||||
m_valueInput.lineType = InputField.LineType.MultiLineNewline;
|
m_valueInput.lineType = InputField.LineType.MultiLineNewline;
|
||||||
@ -182,17 +162,8 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
if (Owner.CanWrite)
|
if (Owner.CanWrite)
|
||||||
{
|
{
|
||||||
var applyBtnObj = UIFactory.CreateButton(groupObj, new Color(0.2f, 0.2f, 0.2f));
|
var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", OnApplyClicked, new Color(0.2f, 0.2f, 0.2f));
|
||||||
var applyLayout = applyBtnObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(apply.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0);
|
||||||
applyLayout.minWidth = 50;
|
|
||||||
applyLayout.minHeight = 25;
|
|
||||||
applyLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
var applyBtn = applyBtnObj.GetComponent<Button>();
|
|
||||||
applyBtn.onClick.AddListener(OnApplyClicked);
|
|
||||||
|
|
||||||
var applyText = applyBtnObj.GetComponentInChildren<Text>();
|
|
||||||
applyText.text = "Apply";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
@ -7,7 +7,7 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
#region IStructInfo helper
|
#region IStructInfo helper
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
typeof(Vector3),
|
typeof(Vector3),
|
||||||
typeof(Vector4),
|
typeof(Vector4),
|
||||||
typeof(Rect),
|
typeof(Rect),
|
||||||
typeof(Color) // todo might make a special editor for colors
|
//typeof(Color) // todo might make a special editor for colors
|
||||||
};
|
};
|
||||||
|
|
||||||
//~~~~~~~~~ Instance ~~~~~~~~~~
|
//~~~~~~~~~ Instance ~~~~~~~~~~
|
||||||
@ -225,17 +225,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (StructInfo != null)
|
if (StructInfo != null)
|
||||||
{
|
|
||||||
DestroySubContent();
|
DestroySubContent();
|
||||||
//// changing types, destroy subcontent
|
|
||||||
//for (int i = 0; i < m_subContentParent.transform.childCount; i++)
|
|
||||||
//{
|
|
||||||
// var child = m_subContentParent.transform.GetChild(i);
|
|
||||||
// GameObject.Destroy(child.gameObject);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//m_UIConstructed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lastStructType = type;
|
m_lastStructType = type;
|
||||||
|
|
||||||
@ -266,68 +256,38 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var editorContainer = UIFactory.CreateVerticalGroup(m_subContentParent, new Color(0.08f, 0.08f, 0.08f));
|
var editorContainer = UIFactory.CreateVerticalGroup(m_subContentParent, "EditorContent", false, true, true, true, 2, new Vector4(4,4,4,4),
|
||||||
var editorGroup = editorContainer.GetComponent<VerticalLayoutGroup>();
|
new Color(0.08f, 0.08f, 0.08f));
|
||||||
editorGroup.childForceExpandWidth = false;
|
|
||||||
editorGroup.padding.top = 4;
|
|
||||||
editorGroup.padding.right = 4;
|
|
||||||
editorGroup.padding.left = 4;
|
|
||||||
editorGroup.padding.bottom = 4;
|
|
||||||
editorGroup.spacing = 2;
|
|
||||||
|
|
||||||
m_inputs = new InputField[StructInfo.FieldNames.Length];
|
m_inputs = new InputField[StructInfo.FieldNames.Length];
|
||||||
|
|
||||||
for (int i = 0; i < StructInfo.FieldNames.Length; i++)
|
for (int i = 0; i < StructInfo.FieldNames.Length; i++)
|
||||||
{
|
|
||||||
AddEditorRow(i, editorContainer);
|
AddEditorRow(i, editorContainer);
|
||||||
}
|
|
||||||
|
|
||||||
if (Owner.CanWrite)
|
if (Owner.CanWrite)
|
||||||
{
|
{
|
||||||
var applyBtnObj = UIFactory.CreateButton(editorContainer, new Color(0.2f, 0.2f, 0.2f));
|
var applyBtn = UIFactory.CreateButton(editorContainer, "ApplyButton", "Apply", OnSetValue, new Color(0.2f, 0.2f, 0.2f));
|
||||||
var applyLayout = applyBtnObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(applyBtn.gameObject, minWidth: 175, minHeight: 25, flexibleWidth: 0);
|
||||||
applyLayout.minWidth = 175;
|
|
||||||
applyLayout.minHeight = 25;
|
|
||||||
applyLayout.flexibleWidth = 0;
|
|
||||||
var m_applyBtn = applyBtnObj.GetComponent<Button>();
|
|
||||||
m_applyBtn.onClick.AddListener(OnSetValue);
|
|
||||||
|
|
||||||
void OnSetValue()
|
void OnSetValue()
|
||||||
{
|
{
|
||||||
Owner.SetValue();
|
Owner.SetValue();
|
||||||
RefreshUIForValue();
|
RefreshUIForValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
var applyText = applyBtnObj.GetComponentInChildren<Text>();
|
|
||||||
applyText.text = "Apply";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddEditorRow(int index, GameObject groupObj)
|
internal void AddEditorRow(int index, GameObject groupObj)
|
||||||
{
|
{
|
||||||
var rowObj = UIFactory.CreateHorizontalGroup(groupObj, new Color(1, 1, 1, 0));
|
var rowObj = UIFactory.CreateHorizontalGroup(groupObj, "EditorRow", false, true, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
rowGroup.childForceExpandHeight = true;
|
|
||||||
rowGroup.childForceExpandWidth = false;
|
|
||||||
rowGroup.spacing = 5;
|
|
||||||
|
|
||||||
var label = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleRight);
|
var label = UIFactory.CreateLabel(rowObj, "RowLabel", $"{StructInfo.FieldNames[index]}:", TextAnchor.MiddleRight, Color.cyan);
|
||||||
var labelLayout = label.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(label.gameObject, minWidth: 50, flexibleWidth: 0, minHeight: 25);
|
||||||
labelLayout.minWidth = 50;
|
|
||||||
labelLayout.flexibleWidth = 0;
|
var inputFieldObj = UIFactory.CreateInputField(rowObj, "InputField", "...", 14, 3, 1);
|
||||||
labelLayout.minHeight = 25;
|
UIFactory.SetLayoutElement(inputFieldObj, minWidth: 120, minHeight: 25, flexibleWidth: 0);
|
||||||
var labelText = label.GetComponent<Text>();
|
|
||||||
labelText.text = $"{StructInfo.FieldNames[index]}:";
|
|
||||||
labelText.color = Color.cyan;
|
|
||||||
|
|
||||||
var inputFieldObj = UIFactory.CreateInputField(rowObj, 14, 3, 1);
|
|
||||||
var inputField = inputFieldObj.GetComponent<InputField>();
|
var inputField = inputFieldObj.GetComponent<InputField>();
|
||||||
inputField.characterValidation = InputField.CharacterValidation.Decimal;
|
|
||||||
var inputLayout = inputFieldObj.AddComponent<LayoutElement>();
|
|
||||||
inputLayout.flexibleWidth = 0;
|
|
||||||
inputLayout.minWidth = 120;
|
|
||||||
inputLayout.minHeight = 25;
|
|
||||||
|
|
||||||
m_inputs[index] = inputField;
|
m_inputs[index] = inputField;
|
||||||
|
|
||||||
inputField.onValueChanged.AddListener((string val) => { Value = StructInfo.SetValue(ref this.Value, index, float.Parse(val)); });
|
inputField.onValueChanged.AddListener((string val) => { Value = StructInfo.SetValue(ref this.Value, index, float.Parse(val)); });
|
@ -10,8 +10,10 @@ using UnityExplorer.Core.Unity;
|
|||||||
using UnityExplorer.Core.Runtime;
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
|
using UnityExplorer.UI.CacheObject;
|
||||||
|
using UnityExplorer.UI.Main.Home;
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors.Reflection
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
public class InteractiveValue
|
public class InteractiveValue
|
||||||
{
|
{
|
||||||
@ -44,6 +46,8 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
return typeof(InteractiveEnum);
|
return typeof(InteractiveEnum);
|
||||||
}
|
}
|
||||||
// check for unity struct types
|
// check for unity struct types
|
||||||
|
else if (typeof(Color).IsAssignableFrom(type))
|
||||||
|
return typeof(InteractiveColor);
|
||||||
else if (InteractiveUnityStruct.SupportsType(type))
|
else if (InteractiveUnityStruct.SupportsType(type))
|
||||||
return typeof(InteractiveUnityStruct);
|
return typeof(InteractiveUnityStruct);
|
||||||
// check Transform, force InteractiveValue so they dont become InteractiveEnumerables.
|
// check Transform, force InteractiveValue so they dont become InteractiveEnumerables.
|
||||||
@ -93,11 +97,11 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
|
|
||||||
public virtual void OnDestroy()
|
public virtual void OnDestroy()
|
||||||
{
|
{
|
||||||
if (this.m_valueContent)
|
if (this.m_mainContent)
|
||||||
{
|
{
|
||||||
m_valueContent.transform.SetParent(null, false);
|
m_mainContent.transform.SetParent(null, false);
|
||||||
m_valueContent.SetActive(false);
|
m_mainContent.SetActive(false);
|
||||||
GameObject.Destroy(this.m_valueContent.gameObject);
|
GameObject.Destroy(this.m_mainContent.gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
DestroySubContent();
|
DestroySubContent();
|
||||||
@ -255,6 +259,8 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
else
|
else
|
||||||
toString = (string)m_toStringMethod.Invoke(Value, new object[0]);
|
toString = (string)m_toStringMethod.Invoke(Value, new object[0]);
|
||||||
|
|
||||||
|
toString = toString ?? "";
|
||||||
|
|
||||||
string typeName = valueType.FullName;
|
string typeName = valueType.FullName;
|
||||||
if (typeName.StartsWith("Il2CppSystem."))
|
if (typeName.StartsWith("Il2CppSystem."))
|
||||||
typeName = typeName.Substring(6, typeName.Length - 6);
|
typeName = typeName.Substring(6, typeName.Length - 6);
|
||||||
@ -289,7 +295,7 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
internal GameObject m_mainContentParent;
|
internal GameObject m_mainContentParent;
|
||||||
internal GameObject m_subContentParent;
|
internal GameObject m_subContentParent;
|
||||||
|
|
||||||
internal GameObject m_valueContent;
|
internal GameObject m_mainContent;
|
||||||
internal GameObject m_inspectButton;
|
internal GameObject m_inspectButton;
|
||||||
internal Text m_baseLabel;
|
internal Text m_baseLabel;
|
||||||
|
|
||||||
@ -300,69 +306,42 @@ namespace UnityExplorer.Core.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
m_UIConstructed = true;
|
m_UIConstructed = true;
|
||||||
|
|
||||||
m_valueContent = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
m_mainContent = UIFactory.CreateHorizontalGroup(parent, $"InteractiveValue_{this.GetType().Name}", false, false, true, true, 4, default,
|
||||||
m_valueContent.name = "InteractiveValue.ValueContent";
|
new Color(1, 1, 1, 0), TextAnchor.UpperLeft);
|
||||||
var mainRect = m_valueContent.GetComponent<RectTransform>();
|
|
||||||
mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
|
||||||
var mainGroup = m_valueContent.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
mainGroup.childForceExpandWidth = false;
|
|
||||||
mainGroup.childControlWidth = true;
|
|
||||||
mainGroup.childForceExpandHeight = false;
|
|
||||||
mainGroup.childControlHeight = true;
|
|
||||||
mainGroup.spacing = 4;
|
|
||||||
mainGroup.childAlignment = TextAnchor.UpperLeft;
|
|
||||||
var mainLayout = m_valueContent.AddComponent<LayoutElement>();
|
|
||||||
mainLayout.flexibleWidth = 9000;
|
|
||||||
mainLayout.minWidth = 175;
|
|
||||||
mainLayout.minHeight = 25;
|
|
||||||
mainLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
// subcontent expand button TODO
|
var mainRect = m_mainContent.GetComponent<RectTransform>();
|
||||||
|
mainRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 25);
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(m_mainContent, flexibleWidth: 9000, minWidth: 175, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
// subcontent expand button
|
||||||
if (HasSubContent)
|
if (HasSubContent)
|
||||||
{
|
{
|
||||||
var subBtnObj = UIFactory.CreateButton(m_valueContent, new Color(0.3f, 0.3f, 0.3f));
|
m_subExpandBtn = UIFactory.CreateButton(m_mainContent, "ExpandSubcontentButton", "▲", ToggleSubcontent, new Color(0.3f, 0.3f, 0.3f));
|
||||||
var btnLayout = subBtnObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(m_subExpandBtn.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||||
btnLayout.minHeight = 25;
|
|
||||||
btnLayout.minWidth = 25;
|
|
||||||
btnLayout.flexibleWidth = 0;
|
|
||||||
btnLayout.flexibleHeight = 0;
|
|
||||||
var btnText = subBtnObj.GetComponentInChildren<Text>();
|
|
||||||
btnText.text = "▲";
|
|
||||||
m_subExpandBtn = subBtnObj.GetComponent<Button>();
|
|
||||||
m_subExpandBtn.onClick.AddListener(() =>
|
|
||||||
{
|
|
||||||
ToggleSubcontent();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// inspect button
|
// inspect button
|
||||||
|
|
||||||
m_inspectButton = UIFactory.CreateButton(m_valueContent, new Color(0.3f, 0.3f, 0.3f, 0.2f));
|
var inspectBtn = UIFactory.CreateButton(m_mainContent,
|
||||||
var inspectLayout = m_inspectButton.AddComponent<LayoutElement>();
|
"InspectButton",
|
||||||
inspectLayout.minWidth = 60;
|
"Inspect",
|
||||||
inspectLayout.minHeight = 25;
|
() =>
|
||||||
inspectLayout.flexibleHeight = 0;
|
|
||||||
inspectLayout.flexibleWidth = 0;
|
|
||||||
var inspectText = m_inspectButton.GetComponentInChildren<Text>();
|
|
||||||
inspectText.text = "Inspect";
|
|
||||||
var inspectBtn = m_inspectButton.GetComponent<Button>();
|
|
||||||
|
|
||||||
inspectBtn.onClick.AddListener(OnInspectClicked);
|
|
||||||
void OnInspectClicked()
|
|
||||||
{
|
{
|
||||||
if (!Value.IsNullOrDestroyed(false))
|
if (!Value.IsNullOrDestroyed(false))
|
||||||
InspectorManager.Instance.Inspect(this.Value, this.Owner);
|
InspectorManager.Instance.Inspect(this.Value, this.Owner);
|
||||||
}
|
},
|
||||||
|
new Color(0.3f, 0.3f, 0.3f, 0.2f));
|
||||||
|
|
||||||
|
m_inspectButton = inspectBtn.gameObject;
|
||||||
|
UIFactory.SetLayoutElement(m_inspectButton, minWidth: 60, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||||
|
|
||||||
m_inspectButton.SetActive(false);
|
m_inspectButton.SetActive(false);
|
||||||
|
|
||||||
// value label
|
// value label
|
||||||
|
|
||||||
var labelObj = UIFactory.CreateLabel(m_valueContent, TextAnchor.MiddleLeft);
|
m_baseLabel = UIFactory.CreateLabel(m_mainContent, "ValueLabel", "", TextAnchor.MiddleLeft);
|
||||||
m_baseLabel = labelObj.GetComponent<Text>();
|
UIFactory.SetLayoutElement(m_baseLabel.gameObject, flexibleWidth: 9000, minHeight: 25);
|
||||||
var labelLayout = labelObj.AddComponent<LayoutElement>();
|
|
||||||
labelLayout.flexibleWidth = 9000;
|
|
||||||
labelLayout.minHeight = 25;
|
|
||||||
|
|
||||||
m_subContentParent = subGroup;
|
m_subContentParent = subGroup;
|
||||||
}
|
}
|
@ -5,9 +5,10 @@ using UnityEngine;
|
|||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.CSharp;
|
using UnityExplorer.Core.CSharp;
|
||||||
|
using UnityExplorer.Core.Input;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.CSConsole;
|
|
||||||
using UnityExplorer.UI.Main;
|
using UnityExplorer.UI.Main;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main.CSConsole
|
namespace UnityExplorer.UI.Main.CSConsole
|
||||||
@ -20,7 +21,6 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
private const int UPDATES_PER_BATCH = 100;
|
private const int UPDATES_PER_BATCH = 100;
|
||||||
|
|
||||||
public static GameObject m_mainObj;
|
public static GameObject m_mainObj;
|
||||||
//private static RectTransform m_thisRect;
|
|
||||||
|
|
||||||
private static readonly List<GameObject> m_suggestionButtons = new List<GameObject>();
|
private static readonly List<GameObject> m_suggestionButtons = new List<GameObject>();
|
||||||
private static readonly List<Text> m_suggestionTexts = new List<Text>();
|
private static readonly List<Text> m_suggestionTexts = new List<Text>();
|
||||||
@ -43,16 +43,12 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
if (!m_mainObj)
|
if (!m_mainObj)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!CSharpConsole.EnableAutocompletes)
|
if (!CSharpConsole.EnableAutocompletes)
|
||||||
{
|
{
|
||||||
if (m_mainObj.activeSelf)
|
if (m_mainObj.activeSelf)
|
||||||
{
|
|
||||||
m_mainObj.SetActive(false);
|
m_mainObj.SetActive(false);
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -206,7 +202,7 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
{
|
{
|
||||||
// Credit ManylMarco
|
// Credit ManylMarco
|
||||||
CSharpConsole.AutoCompletes.Clear();
|
CSharpConsole.AutoCompletes.Clear();
|
||||||
string[] completions = CSharpConsole.Instance.m_evaluator.GetCompletions(input, out string prefix);
|
string[] completions = CSharpConsole.Instance.Evaluator.GetCompletions(input, out string prefix);
|
||||||
if (completions != null)
|
if (completions != null)
|
||||||
{
|
{
|
||||||
if (prefix == null)
|
if (prefix == null)
|
||||||
@ -257,7 +253,7 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
{
|
{
|
||||||
var parent = UIManager.CanvasRoot;
|
var parent = UIManager.CanvasRoot;
|
||||||
|
|
||||||
var obj = UIFactory.CreateScrollView(parent, out GameObject content, out _, new Color(0.1f, 0.1f, 0.1f, 0.95f));
|
var obj = UIFactory.CreateScrollView(parent, "AutoCompleterScrollView", out GameObject content, out _, new Color(0.1f, 0.1f, 0.1f, 0.95f));
|
||||||
|
|
||||||
m_mainObj = obj;
|
m_mainObj = obj;
|
||||||
|
|
||||||
@ -270,43 +266,35 @@ namespace UnityExplorer.UI.Main.CSConsole
|
|||||||
mainRect.offsetMax = Vector2.zero;
|
mainRect.offsetMax = Vector2.zero;
|
||||||
|
|
||||||
var mainGroup = content.GetComponent<VerticalLayoutGroup>();
|
var mainGroup = content.GetComponent<VerticalLayoutGroup>();
|
||||||
mainGroup.childControlHeight = false;
|
mainGroup.SetChildControlHeight(false);
|
||||||
mainGroup.childControlWidth = true;
|
mainGroup.SetChildControlWidth(true);
|
||||||
mainGroup.childForceExpandHeight = false;
|
mainGroup.childForceExpandHeight = false;
|
||||||
mainGroup.childForceExpandWidth = true;
|
mainGroup.childForceExpandWidth = true;
|
||||||
|
|
||||||
|
ColorBlock btnColors = new ColorBlock();
|
||||||
|
RuntimeProvider.Instance.SetColorBlock(btnColors, new Color(0, 0, 0, 0), highlighted: new Color(0.2f, 0.2f, 0.2f, 1.0f));
|
||||||
|
|
||||||
for (int i = 0; i < MAX_LABELS; i++)
|
for (int i = 0; i < MAX_LABELS; i++)
|
||||||
{
|
{
|
||||||
var buttonObj = UIFactory.CreateButton(content);
|
var btn = UIFactory.CreateButton(content, "AutoCompleteButton", "", null, btnColors);
|
||||||
Button btn = buttonObj.GetComponent<Button>();
|
|
||||||
ColorBlock btnColors = btn.colors;
|
|
||||||
btnColors.normalColor = new Color(0f, 0f, 0f, 0f);
|
|
||||||
btnColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1.0f);
|
|
||||||
btn.colors = btnColors;
|
|
||||||
|
|
||||||
var nav = btn.navigation;
|
var nav = btn.navigation;
|
||||||
nav.mode = Navigation.Mode.Vertical;
|
nav.mode = Navigation.Mode.Vertical;
|
||||||
btn.navigation = nav;
|
btn.navigation = nav;
|
||||||
|
|
||||||
var btnLayout = buttonObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(btn.gameObject, minHeight: 20);
|
||||||
btnLayout.minHeight = 20;
|
|
||||||
|
|
||||||
var text = btn.GetComponentInChildren<Text>();
|
var text = btn.GetComponentInChildren<Text>();
|
||||||
text.alignment = TextAnchor.MiddleLeft;
|
text.alignment = TextAnchor.MiddleLeft;
|
||||||
text.color = Color.white;
|
text.color = Color.white;
|
||||||
|
|
||||||
var hiddenChild = UIFactory.CreateUIObject("HiddenText", buttonObj);
|
var hiddenChild = UIFactory.CreateUIObject("HiddenText", btn.gameObject);
|
||||||
hiddenChild.SetActive(false);
|
hiddenChild.SetActive(false);
|
||||||
var hiddenText = hiddenChild.AddComponent<Text>();
|
var hiddenText = hiddenChild.AddComponent<Text>();
|
||||||
m_hiddenSuggestionTexts.Add(hiddenText);
|
m_hiddenSuggestionTexts.Add(hiddenText);
|
||||||
btn.onClick.AddListener(UseAutocompleteButton);
|
btn.onClick.AddListener(() => { CSharpConsole.Instance.UseAutocomplete(hiddenText.text); });
|
||||||
|
|
||||||
void UseAutocompleteButton()
|
m_suggestionButtons.Add(btn.gameObject);
|
||||||
{
|
|
||||||
CSharpConsole.Instance.UseAutocomplete(hiddenText.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_suggestionButtons.Add(buttonObj);
|
|
||||||
m_suggestionTexts.Add(text);
|
m_suggestionTexts.Add(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityExplorer.UI.CSConsole.Lexer;
|
using UnityExplorer.UI.Main.CSConsole.Lexer;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.CSConsole
|
namespace UnityExplorer.UI.Main.CSConsole
|
||||||
{
|
{
|
||||||
public struct LexerMatchInfo
|
public struct LexerMatchInfo
|
||||||
{
|
{
|
||||||
@ -40,29 +40,12 @@ namespace UnityExplorer.UI.CSConsole
|
|||||||
{
|
{
|
||||||
'[', ']', '(', ')', '{', '}', ';', ':', ',', '.'
|
'[', ']', '(', ')', '{', '}', ';', ':', ',', '.'
|
||||||
};
|
};
|
||||||
|
|
||||||
public static CommentMatch commentMatcher = new CommentMatch();
|
public static CommentMatch commentMatcher = new CommentMatch();
|
||||||
public static SymbolMatch symbolMatcher = new SymbolMatch();
|
public static SymbolMatch symbolMatcher = new SymbolMatch();
|
||||||
public static NumberMatch numberMatcher = new NumberMatch();
|
public static NumberMatch numberMatcher = new NumberMatch();
|
||||||
public static StringMatch stringMatcher = new StringMatch();
|
public static StringMatch stringMatcher = new StringMatch();
|
||||||
|
public static KeywordMatch validKeywordMatcher = new KeywordMatch();
|
||||||
public static KeywordMatch validKeywordMatcher = new KeywordMatch
|
|
||||||
{
|
|
||||||
highlightColor = new Color(0.33f, 0.61f, 0.83f, 1.0f),
|
|
||||||
Keywords = new[] { "add", "as", "ascending", "await", "bool", "break", "by", "byte",
|
|
||||||
"case", "catch", "char", "checked", "const", "continue", "decimal", "default", "descending", "do", "dynamic",
|
|
||||||
"else", "equals", "false", "finally", "float", "for", "foreach", "from", "global", "goto", "group",
|
|
||||||
"if", "in", "int", "into", "is", "join", "let", "lock", "long", "new", "null", "object", "on", "orderby", "out",
|
|
||||||
"ref", "remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string",
|
|
||||||
"switch", "throw", "true", "try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield" }
|
|
||||||
};
|
|
||||||
|
|
||||||
public static KeywordMatch invalidKeywordMatcher = new KeywordMatch()
|
|
||||||
{
|
|
||||||
highlightColor = new Color(0.95f, 0.10f, 0.10f, 1.0f),
|
|
||||||
Keywords = new[] { "abstract", "async", "base", "class", "delegate", "enum", "explicit", "extern", "fixed", "get",
|
|
||||||
"implicit", "interface", "internal", "namespace", "operator", "override", "params", "private", "protected", "public",
|
|
||||||
"using", "partial", "readonly", "sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void" }
|
|
||||||
};
|
|
||||||
|
|
||||||
// ~~~~~~~ ctor ~~~~~~~
|
// ~~~~~~~ ctor ~~~~~~~
|
||||||
|
|
||||||
@ -78,7 +61,6 @@ namespace UnityExplorer.UI.CSConsole
|
|||||||
numberMatcher,
|
numberMatcher,
|
||||||
stringMatcher,
|
stringMatcher,
|
||||||
validKeywordMatcher,
|
validKeywordMatcher,
|
||||||
invalidKeywordMatcher,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (Matcher lexer in matchers)
|
foreach (Matcher lexer in matchers)
|
||||||
|
@ -4,17 +4,20 @@ using System.IO;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityExplorer.Core.CSharp;
|
using UnityExplorer.Core.CSharp;
|
||||||
using UnityExplorer.UI.CSConsole;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityExplorer.Core.Input;
|
using UnityExplorer.Core.Input;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.UI.Reusable;
|
|
||||||
using UnityExplorer.UI.Main.CSConsole;
|
using UnityExplorer.UI.Main.CSConsole;
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.Core.Unity;
|
||||||
|
using UnityExplorer.UI.Utility;
|
||||||
|
#if CPP
|
||||||
|
using UnityExplorer.Core.Runtime.Il2Cpp;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main
|
namespace UnityExplorer.UI.Main.CSConsole
|
||||||
{
|
{
|
||||||
public class CSharpConsole : BaseMenuPage
|
public class CSharpConsole : BaseMenuPage
|
||||||
{
|
{
|
||||||
@ -22,8 +25,8 @@ namespace UnityExplorer.UI.Main
|
|||||||
|
|
||||||
public static CSharpConsole Instance { get; private set; }
|
public static CSharpConsole Instance { get; private set; }
|
||||||
|
|
||||||
//public UI.CSConsole.CSharpConsole m_codeEditor;
|
public ScriptEvaluator Evaluator;
|
||||||
public ScriptEvaluator m_evaluator;
|
internal StringBuilder m_evalLogBuilder;
|
||||||
|
|
||||||
public static List<string> UsingDirectives;
|
public static List<string> UsingDirectives;
|
||||||
|
|
||||||
@ -50,14 +53,13 @@ namespace UnityExplorer.UI.Main
|
|||||||
InitConsole();
|
InitConsole();
|
||||||
|
|
||||||
AutoCompleter.Init();
|
AutoCompleter.Init();
|
||||||
|
#if MONO
|
||||||
|
DummyBehaviour.Setup();
|
||||||
|
#endif
|
||||||
|
|
||||||
ResetConsole();
|
ResetConsole(false);
|
||||||
|
|
||||||
// Make sure compiler is supported on this platform
|
// Make sure compiler is supported on this platform
|
||||||
m_evaluator.Compile("");
|
Evaluator.Compile("");
|
||||||
|
|
||||||
foreach (string use in DefaultUsing)
|
|
||||||
AddUsing(use);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -75,10 +77,32 @@ namespace UnityExplorer.UI.Main
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetConsole(bool log = true)
|
||||||
|
{
|
||||||
|
if (Evaluator != null)
|
||||||
|
Evaluator.Dispose();
|
||||||
|
|
||||||
|
m_evalLogBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
Evaluator = new ScriptEvaluator(new StringWriter(m_evalLogBuilder)) { InteractiveBaseClass = typeof(ScriptInteraction) };
|
||||||
|
|
||||||
|
UsingDirectives = new List<string>();
|
||||||
|
|
||||||
|
foreach (string use in DefaultUsing)
|
||||||
|
AddUsing(use);
|
||||||
|
|
||||||
|
if (log)
|
||||||
|
ExplorerCore.Log($"C# Console reset. Using directives:\r\n{Evaluator.GetUsing()}");
|
||||||
|
}
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
UpdateConsole();
|
UpdateConsole();
|
||||||
|
|
||||||
AutoCompleter.Update();
|
AutoCompleter.Update();
|
||||||
|
#if CPP
|
||||||
|
Il2CppCoroutine.Process();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddUsing(string asm)
|
public void AddUsing(string asm)
|
||||||
@ -90,40 +114,34 @@ namespace UnityExplorer.UI.Main
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Evaluate(string code, bool suppressWarning = false)
|
public void Evaluate(string code, bool supressLog = false)
|
||||||
{
|
|
||||||
m_evaluator.Compile(code, out Mono.CSharp.CompiledMethod compiled);
|
|
||||||
|
|
||||||
if (compiled == null)
|
|
||||||
{
|
|
||||||
if (!suppressWarning)
|
|
||||||
ExplorerCore.LogWarning("Unable to compile the code!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
object ret = VoidType.Value;
|
Evaluator.Run(code);
|
||||||
compiled.Invoke(ref ret);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
if (!suppressWarning)
|
|
||||||
ExplorerCore.LogWarning($"Exception executing code: {e.GetType()}, {e.Message}\r\n{e.StackTrace}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetConsole()
|
string output = ScriptEvaluator._textWriter.ToString();
|
||||||
{
|
var outputSplit = output.Split('\n');
|
||||||
if (m_evaluator != null)
|
if (outputSplit.Length >= 2)
|
||||||
{
|
output = outputSplit[outputSplit.Length - 2];
|
||||||
m_evaluator.Dispose();
|
m_evalLogBuilder.Clear();
|
||||||
|
|
||||||
|
if (ScriptEvaluator._reportPrinter.ErrorsCount > 0)
|
||||||
|
throw new FormatException($"Unable to compile the code. Evaluator's last output was:\r\n{output}");
|
||||||
|
|
||||||
|
if (!supressLog)
|
||||||
|
ExplorerCore.Log("Code executed successfully.");
|
||||||
|
}
|
||||||
|
catch (FormatException fex)
|
||||||
|
{
|
||||||
|
if (!supressLog)
|
||||||
|
ExplorerCore.LogWarning(fex.Message);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (!supressLog)
|
||||||
|
ExplorerCore.LogWarning(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_evaluator = new ScriptEvaluator(new StringWriter(new StringBuilder())) { InteractiveBaseClass = typeof(ScriptInteraction) };
|
|
||||||
|
|
||||||
UsingDirectives = new List<string>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
@ -161,6 +179,8 @@ The following helper methods are available:
|
|||||||
|
|
||||||
* <color=#add490>Log(""message"")</color> logs a message to the debug console
|
* <color=#add490>Log(""message"")</color> logs a message to the debug console
|
||||||
|
|
||||||
|
* <color=#add490>StartCoroutine(IEnumerator routine)</color> start the IEnumerator as a UnityEngine.Coroutine
|
||||||
|
|
||||||
* <color=#add490>CurrentTarget()</color> returns the currently inspected target on the Home page
|
* <color=#add490>CurrentTarget()</color> returns the currently inspected target on the Home page
|
||||||
|
|
||||||
* <color=#add490>AllTargets()</color> returns an object[] array containing all inspected instances
|
* <color=#add490>AllTargets()</color> returns an object[] array containing all inspected instances
|
||||||
@ -285,6 +305,7 @@ The following helper methods are available:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EnableAutoIndent)
|
||||||
UpdateIndent(newText);
|
UpdateIndent(newText);
|
||||||
|
|
||||||
if (!forceUpdate && string.IsNullOrEmpty(newText))
|
if (!forceUpdate && string.IsNullOrEmpty(newText))
|
||||||
@ -292,6 +313,7 @@ The following helper methods are available:
|
|||||||
else
|
else
|
||||||
inputHighlightText.text = SyntaxHighlightContent(newText);
|
inputHighlightText.text = SyntaxHighlightContent(newText);
|
||||||
|
|
||||||
|
if (EnableAutocompletes)
|
||||||
UpdateAutocompletes();
|
UpdateAutocompletes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +361,7 @@ The following helper methods are available:
|
|||||||
|
|
||||||
string ret = "";
|
string ret = "";
|
||||||
|
|
||||||
foreach (LexerMatchInfo match in highlightLexer.GetMatches(inputText))
|
foreach (var match in highlightLexer.GetMatches(inputText))
|
||||||
{
|
{
|
||||||
for (int i = offset; i < match.startIndex; i++)
|
for (int i = offset; i < match.startIndex; i++)
|
||||||
ret += inputText[i];
|
ret += inputText[i];
|
||||||
@ -434,93 +456,54 @@ The following helper methods are available:
|
|||||||
|
|
||||||
public void ConstructUI()
|
public void ConstructUI()
|
||||||
{
|
{
|
||||||
Content = UIFactory.CreateUIObject("C# Console", MainMenu.Instance.PageViewport);
|
Content = UIFactory.CreateVerticalGroup(MainMenu.Instance.PageViewport, "CSharpConsole", true, true, true, true);
|
||||||
|
UIFactory.SetLayoutElement(Content, preferredHeight: 500, flexibleHeight: 9000);
|
||||||
var mainLayout = Content.AddComponent<LayoutElement>();
|
|
||||||
mainLayout.preferredHeight = 500;
|
|
||||||
mainLayout.flexibleHeight = 9000;
|
|
||||||
|
|
||||||
var mainGroup = Content.AddComponent<VerticalLayoutGroup>();
|
|
||||||
mainGroup.childControlHeight = true;
|
|
||||||
mainGroup.childControlWidth = true;
|
|
||||||
mainGroup.childForceExpandHeight = true;
|
|
||||||
mainGroup.childForceExpandWidth = true;
|
|
||||||
|
|
||||||
#region TOP BAR
|
#region TOP BAR
|
||||||
|
|
||||||
// Main group object
|
// Main group object
|
||||||
|
|
||||||
var topBarObj = UIFactory.CreateHorizontalGroup(Content);
|
var topBarObj = UIFactory.CreateHorizontalGroup(Content, "TopBar", true, true, true, true, 10, new Vector4(8, 8, 30, 30),
|
||||||
LayoutElement topBarLayout = topBarObj.AddComponent<LayoutElement>();
|
default, TextAnchor.LowerCenter);
|
||||||
topBarLayout.minHeight = 50;
|
UIFactory.SetLayoutElement(topBarObj, minHeight: 50, flexibleHeight: 0);
|
||||||
topBarLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
var topBarGroup = topBarObj.GetComponent<HorizontalLayoutGroup>();
|
// Top label
|
||||||
topBarGroup.padding.left = 30;
|
|
||||||
topBarGroup.padding.right = 30;
|
|
||||||
topBarGroup.padding.top = 8;
|
|
||||||
topBarGroup.padding.bottom = 8;
|
|
||||||
topBarGroup.spacing = 10;
|
|
||||||
topBarGroup.childForceExpandHeight = true;
|
|
||||||
topBarGroup.childForceExpandWidth = true;
|
|
||||||
topBarGroup.childControlWidth = true;
|
|
||||||
topBarGroup.childControlHeight = true;
|
|
||||||
topBarGroup.childAlignment = TextAnchor.LowerCenter;
|
|
||||||
|
|
||||||
var topBarLabel = UIFactory.CreateLabel(topBarObj, TextAnchor.MiddleLeft);
|
var topBarLabel = UIFactory.CreateLabel(topBarObj, "TopLabel", "C# Console", TextAnchor.MiddleLeft, default, true, 25);
|
||||||
var topBarLabelLayout = topBarLabel.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(topBarLabel.gameObject, preferredWidth: 150, flexibleWidth: 5000);
|
||||||
topBarLabelLayout.preferredWidth = 150;
|
|
||||||
topBarLabelLayout.flexibleWidth = 5000;
|
|
||||||
var topBarText = topBarLabel.GetComponent<Text>();
|
|
||||||
topBarText.text = "C# Console";
|
|
||||||
topBarText.fontSize = 20;
|
|
||||||
|
|
||||||
// Enable Ctrl+R toggle
|
// Enable Ctrl+R toggle
|
||||||
|
|
||||||
var ctrlRToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle ctrlRToggle, out Text ctrlRToggleText);
|
var ctrlRToggleObj = UIFactory.CreateToggle(topBarObj, "CtrlRToggle", out Toggle ctrlRToggle, out Text ctrlRToggleText);
|
||||||
ctrlRToggle.onValueChanged.AddListener(CtrlRToggleCallback);
|
ctrlRToggle.onValueChanged.AddListener((bool val) => { EnableCtrlRShortcut = val; });
|
||||||
void CtrlRToggleCallback(bool val)
|
|
||||||
{
|
|
||||||
EnableCtrlRShortcut = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrlRToggleText.text = "Run on Ctrl+R";
|
ctrlRToggleText.text = "Run on Ctrl+R";
|
||||||
ctrlRToggleText.alignment = TextAnchor.UpperLeft;
|
ctrlRToggleText.alignment = TextAnchor.UpperLeft;
|
||||||
var ctrlRLayout = ctrlRToggleObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(ctrlRToggleObj, minWidth: 140, flexibleWidth: 0, minHeight: 25);
|
||||||
ctrlRLayout.minWidth = 140;
|
|
||||||
ctrlRLayout.flexibleWidth = 0;
|
|
||||||
ctrlRLayout.minHeight = 25;
|
|
||||||
|
|
||||||
// Enable Suggestions toggle
|
// Enable Suggestions toggle
|
||||||
|
|
||||||
var suggestToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle suggestToggle, out Text suggestToggleText);
|
var suggestToggleObj = UIFactory.CreateToggle(topBarObj, "SuggestionToggle", out Toggle suggestToggle, out Text suggestToggleText);
|
||||||
suggestToggle.onValueChanged.AddListener(SuggestToggleCallback);
|
suggestToggle.onValueChanged.AddListener((bool val) =>
|
||||||
void SuggestToggleCallback(bool val)
|
|
||||||
{
|
{
|
||||||
EnableAutocompletes = val;
|
EnableAutocompletes = val;
|
||||||
AutoCompleter.Update();
|
AutoCompleter.Update();
|
||||||
}
|
});
|
||||||
|
|
||||||
suggestToggleText.text = "Suggestions";
|
suggestToggleText.text = "Suggestions";
|
||||||
suggestToggleText.alignment = TextAnchor.UpperLeft;
|
suggestToggleText.alignment = TextAnchor.UpperLeft;
|
||||||
var suggestLayout = suggestToggleObj.AddComponent<LayoutElement>();
|
|
||||||
suggestLayout.minWidth = 120;
|
UIFactory.SetLayoutElement(suggestToggleObj, minWidth: 120, flexibleWidth: 0, minHeight: 25);
|
||||||
suggestLayout.flexibleWidth = 0;
|
|
||||||
suggestLayout.minHeight = 25;
|
|
||||||
|
|
||||||
// Enable Auto-indent toggle
|
// Enable Auto-indent toggle
|
||||||
|
|
||||||
var autoIndentToggleObj = UIFactory.CreateToggle(topBarObj, out Toggle autoIndentToggle, out Text autoIndentToggleText);
|
var autoIndentToggleObj = UIFactory.CreateToggle(topBarObj, "IndentToggle", out Toggle autoIndentToggle, out Text autoIndentToggleText);
|
||||||
autoIndentToggle.onValueChanged.AddListener(OnIndentChanged);
|
autoIndentToggle.onValueChanged.AddListener((bool val) => EnableAutoIndent = val);
|
||||||
void OnIndentChanged(bool val) => EnableAutoIndent = val;
|
|
||||||
|
|
||||||
autoIndentToggleText.text = "Auto-indent on Enter";
|
autoIndentToggleText.text = "Auto-indent on Enter";
|
||||||
autoIndentToggleText.alignment = TextAnchor.UpperLeft;
|
autoIndentToggleText.alignment = TextAnchor.UpperLeft;
|
||||||
|
|
||||||
var autoIndentLayout = autoIndentToggleObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(autoIndentToggleObj, minWidth: 180, flexibleWidth: 0, minHeight: 25);
|
||||||
autoIndentLayout.minWidth = 180;
|
|
||||||
autoIndentLayout.flexibleWidth = 0;
|
|
||||||
autoIndentLayout.minHeight = 25;
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -528,7 +511,7 @@ The following helper methods are available:
|
|||||||
|
|
||||||
int fontSize = 16;
|
int fontSize = 16;
|
||||||
|
|
||||||
var inputObj = UIFactory.CreateSrollInputField(Content, out InputFieldScroller consoleScroll, fontSize);
|
var inputObj = UIFactory.CreateSrollInputField(Content, "ConsoleInput", STARTUP_TEXT, out InputFieldScroller consoleScroll, fontSize);
|
||||||
|
|
||||||
var inputField = consoleScroll.inputField;
|
var inputField = consoleScroll.inputField;
|
||||||
|
|
||||||
@ -538,7 +521,6 @@ The following helper methods are available:
|
|||||||
mainTextInput.color = new Color(1, 1, 1, 0.5f);
|
mainTextInput.color = new Color(1, 1, 1, 0.5f);
|
||||||
|
|
||||||
var placeHolderText = inputField.placeholder.GetComponent<Text>();
|
var placeHolderText = inputField.placeholder.GetComponent<Text>();
|
||||||
placeHolderText.text = STARTUP_TEXT;
|
|
||||||
placeHolderText.fontSize = fontSize;
|
placeHolderText.fontSize = fontSize;
|
||||||
|
|
||||||
var highlightTextObj = UIFactory.CreateUIObject("HighlightText", mainTextObj.gameObject);
|
var highlightTextObj = UIFactory.CreateUIObject("HighlightText", mainTextObj.gameObject);
|
||||||
@ -555,31 +537,28 @@ The following helper methods are available:
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region COMPILE BUTTON
|
#region COMPILE BUTTON BAR
|
||||||
|
|
||||||
var compileBtnObj = UIFactory.CreateButton(Content);
|
var horozGroupObj = UIFactory.CreateHorizontalGroup(Content, "BigButtons", true, true, true, true, 0, new Vector4(2,2,2,2),
|
||||||
var compileBtnLayout = compileBtnObj.AddComponent<LayoutElement>();
|
new Color(1, 1, 1, 0));
|
||||||
compileBtnLayout.preferredWidth = 80;
|
|
||||||
compileBtnLayout.flexibleWidth = 0;
|
var resetButton = UIFactory.CreateButton(horozGroupObj, "ResetButton", "Reset", () => ResetConsole(), "666666".ToColor());
|
||||||
compileBtnLayout.minHeight = 45;
|
var resetBtnText = resetButton.GetComponentInChildren<Text>();
|
||||||
compileBtnLayout.flexibleHeight = 0;
|
resetBtnText.fontSize = 18;
|
||||||
var compileButton = compileBtnObj.GetComponent<Button>();
|
UIFactory.SetLayoutElement(resetButton.gameObject, preferredWidth: 80, flexibleWidth: 0, minHeight: 45, flexibleHeight: 0);
|
||||||
var compileBtnColors = compileButton.colors;
|
|
||||||
compileBtnColors.normalColor = new Color(14f / 255f, 80f / 255f, 14f / 255f);
|
var compileButton = UIFactory.CreateButton(horozGroupObj, "CompileButton", "Compile", CompileCallback,
|
||||||
compileButton.colors = compileBtnColors;
|
new Color(14f / 255f, 80f / 255f, 14f / 255f));
|
||||||
var btnText = compileBtnObj.GetComponentInChildren<Text>();
|
var btnText = compileButton.GetComponentInChildren<Text>();
|
||||||
btnText.text = "Run";
|
|
||||||
btnText.fontSize = 18;
|
btnText.fontSize = 18;
|
||||||
btnText.color = Color.white;
|
UIFactory.SetLayoutElement(compileButton.gameObject, preferredWidth: 80, flexibleWidth: 0, minHeight: 45, flexibleHeight: 0);
|
||||||
|
|
||||||
// Set compile button callback now that we have the Input Field reference
|
|
||||||
compileButton.onClick.AddListener(CompileCallback);
|
|
||||||
void CompileCallback()
|
void CompileCallback()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(inputField.text))
|
if (!string.IsNullOrEmpty(inputField.text))
|
||||||
{
|
|
||||||
Evaluate(inputField.text.Trim());
|
Evaluate(inputField.text.Trim());
|
||||||
}
|
else
|
||||||
|
ExplorerCore.Log("Cannot evaluate empty input!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.CSConsole.Lexer
|
namespace UnityExplorer.UI.Main.CSConsole.Lexer
|
||||||
{
|
{
|
||||||
public class CommentMatch : Matcher
|
public class CommentMatch : Matcher
|
||||||
{
|
{
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.CSConsole.Lexer
|
namespace UnityExplorer.UI.Main.CSConsole.Lexer
|
||||||
{
|
{
|
||||||
// I use two different KeywordMatch instances (valid and invalid).
|
// I use two different KeywordMatch instances (valid and invalid).
|
||||||
// This class just contains common implementations.
|
// This class just contains common implementations.
|
||||||
public class KeywordMatch : Matcher
|
public class KeywordMatch : Matcher
|
||||||
{
|
{
|
||||||
public string[] Keywords;
|
public string[] Keywords = new[] {"add", "as", "ascending", "await", "bool", "break", "by", "byte",
|
||||||
|
"case", "catch", "char", "checked", "const", "continue", "decimal", "default", "descending", "do", "dynamic",
|
||||||
|
"else", "equals", "false", "finally", "float", "for", "foreach", "from", "global", "goto", "group",
|
||||||
|
"if", "in", "int", "into", "is", "join", "let", "lock", "long", "new", "null", "object", "on", "orderby", "out",
|
||||||
|
"ref", "remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string",
|
||||||
|
"switch", "throw", "true", "try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield",
|
||||||
|
"abstract", "async", "base", "class", "delegate", "enum", "explicit", "extern", "fixed", "get",
|
||||||
|
"implicit", "interface", "internal", "namespace", "operator", "override", "params", "private", "protected", "public",
|
||||||
|
"using", "partial", "readonly", "sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void" };
|
||||||
|
|
||||||
public override Color HighlightColor => highlightColor;
|
public override Color HighlightColor => highlightColor;
|
||||||
public Color highlightColor;
|
public Color highlightColor = new Color(0.33f, 0.61f, 0.83f, 1.0f);
|
||||||
|
|
||||||
private readonly HashSet<string> shortlist = new HashSet<string>();
|
private readonly HashSet<string> shortlist = new HashSet<string>();
|
||||||
private readonly Stack<string> removeList = new Stack<string>();
|
private readonly Stack<string> removeList = new Stack<string>();
|
||||||
|
@ -3,7 +3,7 @@ using UnityEngine;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.CSConsole.Lexer
|
namespace UnityExplorer.UI.Main.CSConsole.Lexer
|
||||||
{
|
{
|
||||||
public abstract class Matcher
|
public abstract class Matcher
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.CSConsole.Lexer
|
namespace UnityExplorer.UI.Main.CSConsole.Lexer
|
||||||
{
|
{
|
||||||
public class NumberMatch : Matcher
|
public class NumberMatch : Matcher
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.CSConsole.Lexer
|
namespace UnityExplorer.UI.Main.CSConsole.Lexer
|
||||||
{
|
{
|
||||||
public class StringMatch : Matcher
|
public class StringMatch : Matcher
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.CSConsole.Lexer
|
namespace UnityExplorer.UI.Main.CSConsole.Lexer
|
||||||
{
|
{
|
||||||
public class SymbolMatch : Matcher
|
public class SymbolMatch : Matcher
|
||||||
{
|
{
|
||||||
|
@ -3,10 +3,10 @@ using System.Collections.Generic;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.Config;
|
using UnityExplorer.Core.Config;
|
||||||
using UnityExplorer.UI.Reusable;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
|
using UnityExplorer.UI.Utility;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main
|
namespace UnityExplorer.UI.Main
|
||||||
{
|
{
|
||||||
@ -14,7 +14,7 @@ namespace UnityExplorer.UI.Main
|
|||||||
{
|
{
|
||||||
public static DebugConsole Instance { get; private set; }
|
public static DebugConsole Instance { get; private set; }
|
||||||
|
|
||||||
public static bool LogUnity { get; set; } = ExplorerConfig.Instance.Log_Unity_Debug;
|
public static bool LogUnity { get; set; }
|
||||||
//public static bool SaveToDisk { get; set; } = ModConfig.Instance.Save_Logs_To_Disk;
|
//public static bool SaveToDisk { get; set; } = ModConfig.Instance.Save_Logs_To_Disk;
|
||||||
|
|
||||||
internal static StreamWriter s_streamWriter;
|
internal static StreamWriter s_streamWriter;
|
||||||
@ -32,9 +32,13 @@ namespace UnityExplorer.UI.Main
|
|||||||
public DebugConsole(GameObject parent)
|
public DebugConsole(GameObject parent)
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
LogUnity = ConfigManager.Log_Unity_Debug.Value;
|
||||||
|
|
||||||
ConstructUI(parent);
|
ConstructUI(parent);
|
||||||
|
|
||||||
|
if (!ConfigManager.Last_DebugConsole_State.Value)
|
||||||
|
ToggleShow();
|
||||||
|
|
||||||
// append messages that logged before we were set up
|
// append messages that logged before we were set up
|
||||||
string preAppend = "";
|
string preAppend = "";
|
||||||
for (int i = s_preInitMessages.Count - 1; i >= 0; i--)
|
for (int i = s_preInitMessages.Count - 1; i >= 0; i--)
|
||||||
@ -48,10 +52,7 @@ namespace UnityExplorer.UI.Main
|
|||||||
|
|
||||||
// set up IO
|
// set up IO
|
||||||
|
|
||||||
//if (!SaveToDisk)
|
var path = Path.Combine(ExplorerCore.Loader.ExplorerFolder, "Logs");
|
||||||
// return;
|
|
||||||
|
|
||||||
var path = ExplorerCore.EXPLORER_FOLDER + @"\Logs";
|
|
||||||
|
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
@ -80,6 +81,34 @@ namespace UnityExplorer.UI.Main
|
|||||||
s_streamWriter.WriteLine(msg);
|
s_streamWriter.WriteLine(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool Hiding;
|
||||||
|
|
||||||
|
private GameObject m_logAreaObj;
|
||||||
|
private Text m_hideBtnText;
|
||||||
|
private LayoutElement m_mainLayout;
|
||||||
|
|
||||||
|
public static Action<bool> OnToggleShow;
|
||||||
|
|
||||||
|
public void ToggleShow()
|
||||||
|
{
|
||||||
|
if (m_logAreaObj.activeSelf)
|
||||||
|
{
|
||||||
|
Hiding = true;
|
||||||
|
m_logAreaObj.SetActive(false);
|
||||||
|
m_hideBtnText.text = "Show";
|
||||||
|
m_mainLayout.minHeight = 30;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Hiding = false;
|
||||||
|
m_logAreaObj.SetActive(true);
|
||||||
|
m_hideBtnText.text = "Hide";
|
||||||
|
m_mainLayout.minHeight = 190;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnToggleShow?.Invoke(!Hiding);
|
||||||
|
}
|
||||||
|
|
||||||
public static string RemoveInvalidFilenameChars(string s)
|
public static string RemoveInvalidFilenameChars(string s)
|
||||||
{
|
{
|
||||||
var invalid = Path.GetInvalidFileNameChars();
|
var invalid = Path.GetInvalidFileNameChars();
|
||||||
@ -126,184 +155,84 @@ namespace UnityExplorer.UI.Main
|
|||||||
|
|
||||||
public void ConstructUI(GameObject parent)
|
public void ConstructUI(GameObject parent)
|
||||||
{
|
{
|
||||||
var mainObj = UIFactory.CreateVerticalGroup(parent, new Color(0.1f, 0.1f, 0.1f, 1.0f));
|
var mainObj = UIFactory.CreateVerticalGroup(parent, "DebugConsole", true, true, true, true, 0, default, new Color(0.1f, 0.1f, 0.1f, 1.0f));
|
||||||
|
|
||||||
var mainGroup = mainObj.GetComponent<VerticalLayoutGroup>();
|
|
||||||
mainGroup.childControlHeight = true;
|
|
||||||
mainGroup.childControlWidth = true;
|
|
||||||
mainGroup.childForceExpandHeight = true;
|
|
||||||
mainGroup.childForceExpandWidth = true;
|
|
||||||
|
|
||||||
var mainImage = mainObj.GetComponent<Image>();
|
var mainImage = mainObj.GetComponent<Image>();
|
||||||
mainImage.maskable = true;
|
mainImage.maskable = true;
|
||||||
|
|
||||||
var mask = mainObj.AddComponent<Mask>();
|
var mask = mainObj.AddComponent<Mask>();
|
||||||
mask.showMaskGraphic = true;
|
mask.showMaskGraphic = true;
|
||||||
|
|
||||||
var mainLayout = mainObj.AddComponent<LayoutElement>();
|
m_mainLayout = mainObj.AddComponent<LayoutElement>();
|
||||||
mainLayout.minHeight = 190;
|
m_mainLayout.minHeight = 190;
|
||||||
mainLayout.flexibleHeight = 0;
|
m_mainLayout.flexibleHeight = 0;
|
||||||
|
|
||||||
#region LOG AREA
|
#region LOG AREA
|
||||||
var logAreaObj = UIFactory.CreateHorizontalGroup(mainObj);
|
m_logAreaObj = UIFactory.CreateHorizontalGroup(mainObj, "LogArea", true, true, true, true);
|
||||||
var logAreaGroup = logAreaObj.GetComponent<HorizontalLayoutGroup>();
|
UIFactory.SetLayoutElement(m_logAreaObj, preferredHeight: 190, flexibleHeight: 0);
|
||||||
logAreaGroup.childControlHeight = true;
|
|
||||||
logAreaGroup.childControlWidth = true;
|
|
||||||
logAreaGroup.childForceExpandHeight = true;
|
|
||||||
logAreaGroup.childForceExpandWidth = true;
|
|
||||||
|
|
||||||
var logAreaLayout = logAreaObj.AddComponent<LayoutElement>();
|
var inputScrollerObj = UIFactory.CreateSrollInputField(m_logAreaObj,
|
||||||
logAreaLayout.preferredHeight = 190;
|
"DebugConsoleOutput",
|
||||||
logAreaLayout.flexibleHeight = 0;
|
"<no output>",
|
||||||
|
out InputFieldScroller inputScroll,
|
||||||
var inputScrollerObj = UIFactory.CreateSrollInputField(logAreaObj, out InputFieldScroller inputScroll, 14, new Color(0.05f, 0.05f, 0.05f));
|
14,
|
||||||
|
new Color(0.05f, 0.05f, 0.05f));
|
||||||
|
|
||||||
inputScroll.inputField.textComponent.font = UIManager.ConsoleFont;
|
inputScroll.inputField.textComponent.font = UIManager.ConsoleFont;
|
||||||
inputScroll.inputField.readOnly = true;
|
inputScroll.inputField.readOnly = true;
|
||||||
|
|
||||||
m_textInput = inputScroll.inputField;
|
m_textInput = inputScroll.inputField;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region BOTTOM BAR
|
#region BOTTOM BAR
|
||||||
|
|
||||||
var bottomBarObj = UIFactory.CreateHorizontalGroup(mainObj);
|
var bottomBarObj = UIFactory.CreateHorizontalGroup(mainObj, "BottomBar", false, true, true, true, 10, new Vector4(2,2,10,10),
|
||||||
LayoutElement topBarLayout = bottomBarObj.AddComponent<LayoutElement>();
|
default, TextAnchor.MiddleLeft);
|
||||||
topBarLayout.minHeight = 30;
|
UIFactory.SetLayoutElement(bottomBarObj, minHeight: 30, flexibleHeight: 0);
|
||||||
topBarLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
var bottomGroup = bottomBarObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
bottomGroup.padding.left = 10;
|
|
||||||
bottomGroup.padding.right = 10;
|
|
||||||
bottomGroup.padding.top = 2;
|
|
||||||
bottomGroup.padding.bottom = 2;
|
|
||||||
bottomGroup.spacing = 10;
|
|
||||||
bottomGroup.childForceExpandHeight = true;
|
|
||||||
bottomGroup.childForceExpandWidth = false;
|
|
||||||
bottomGroup.childControlWidth = true;
|
|
||||||
bottomGroup.childControlHeight = true;
|
|
||||||
bottomGroup.childAlignment = TextAnchor.MiddleLeft;
|
|
||||||
|
|
||||||
// Debug Console label
|
// Debug Console label
|
||||||
|
|
||||||
var bottomLabel = UIFactory.CreateLabel(bottomBarObj, TextAnchor.MiddleLeft);
|
var bottomLabel = UIFactory.CreateLabel(bottomBarObj, "DebugConsoleLabel", "Debug Console", TextAnchor.MiddleLeft);
|
||||||
var topBarLabelLayout = bottomLabel.AddComponent<LayoutElement>();
|
bottomLabel.fontStyle = FontStyle.Bold;
|
||||||
topBarLabelLayout.minWidth = 100;
|
UIFactory.SetLayoutElement(bottomLabel.gameObject, minWidth: 100, flexibleWidth: 0);
|
||||||
topBarLabelLayout.flexibleWidth = 0;
|
|
||||||
var topBarText = bottomLabel.GetComponent<Text>();
|
|
||||||
topBarText.fontStyle = FontStyle.Bold;
|
|
||||||
topBarText.text = "Debug Console";
|
|
||||||
topBarText.fontSize = 14;
|
|
||||||
|
|
||||||
// Hide button
|
// Hide button
|
||||||
|
|
||||||
var hideButtonObj = UIFactory.CreateButton(bottomBarObj);
|
var hideButton = UIFactory.CreateButton(bottomBarObj, "HideButton", "Hide", ToggleShow);
|
||||||
|
UIFactory.SetLayoutElement(hideButton.gameObject, minWidth: 80, flexibleWidth: 0);
|
||||||
var hideBtnText = hideButtonObj.GetComponentInChildren<Text>();
|
m_hideBtnText = hideButton.GetComponentInChildren<Text>();
|
||||||
hideBtnText.text = "Hide";
|
|
||||||
|
|
||||||
var hideButton = hideButtonObj.GetComponent<Button>();
|
|
||||||
|
|
||||||
hideButton.onClick.AddListener(HideCallback);
|
|
||||||
void HideCallback()
|
|
||||||
{
|
|
||||||
if (logAreaObj.activeSelf)
|
|
||||||
{
|
|
||||||
logAreaObj.SetActive(false);
|
|
||||||
hideBtnText.text = "Show";
|
|
||||||
mainLayout.minHeight = 30;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logAreaObj.SetActive(true);
|
|
||||||
hideBtnText.text = "Hide";
|
|
||||||
mainLayout.minHeight = 190;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var hideBtnColors = hideButton.colors;
|
|
||||||
//hideBtnColors.normalColor = new Color(160f / 255f, 140f / 255f, 40f / 255f);
|
|
||||||
hideButton.colors = hideBtnColors;
|
|
||||||
|
|
||||||
var hideBtnLayout = hideButtonObj.AddComponent<LayoutElement>();
|
|
||||||
hideBtnLayout.minWidth = 80;
|
|
||||||
hideBtnLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
// Clear button
|
// Clear button
|
||||||
|
|
||||||
var clearButtonObj = UIFactory.CreateButton(bottomBarObj);
|
var clearButton = UIFactory.CreateButton(bottomBarObj, "ClearButton", "Clear", () =>
|
||||||
|
|
||||||
var clearBtnText = clearButtonObj.GetComponentInChildren<Text>();
|
|
||||||
clearBtnText.text = "Clear";
|
|
||||||
|
|
||||||
var clearButton = clearButtonObj.GetComponent<Button>();
|
|
||||||
|
|
||||||
clearButton.onClick.AddListener(ClearCallback);
|
|
||||||
void ClearCallback()
|
|
||||||
{
|
{
|
||||||
m_textInput.text = "";
|
m_textInput.text = "";
|
||||||
AllMessages.Clear();
|
AllMessages.Clear();
|
||||||
}
|
});
|
||||||
|
UIFactory.SetLayoutElement(clearButton.gameObject, minWidth: 80, flexibleWidth: 0);
|
||||||
var clearBtnColors = clearButton.colors;
|
|
||||||
//clearBtnColors.normalColor = new Color(160f/255f, 140f/255f, 40f/255f);
|
|
||||||
clearButton.colors = clearBtnColors;
|
|
||||||
|
|
||||||
var clearBtnLayout = clearButtonObj.AddComponent<LayoutElement>();
|
|
||||||
clearBtnLayout.minWidth = 80;
|
|
||||||
clearBtnLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
// Unity log toggle
|
// Unity log toggle
|
||||||
|
|
||||||
var unityToggleObj = UIFactory.CreateToggle(bottomBarObj, out Toggle unityToggle, out Text unityToggleText);
|
var unityToggleObj = UIFactory.CreateToggle(bottomBarObj, "UnityLogToggle", out Toggle unityToggle, out Text unityToggleText);
|
||||||
|
|
||||||
unityToggle.onValueChanged.AddListener(ToggleLogUnity);
|
unityToggle.onValueChanged.AddListener((bool val) =>
|
||||||
|
|
||||||
unityToggle.isOn = LogUnity;
|
|
||||||
unityToggleText.text = "Print Unity Debug?";
|
|
||||||
unityToggleText.alignment = TextAnchor.MiddleLeft;
|
|
||||||
|
|
||||||
void ToggleLogUnity(bool val)
|
|
||||||
{
|
{
|
||||||
LogUnity = val;
|
LogUnity = val;
|
||||||
ExplorerConfig.Instance.Log_Unity_Debug = val;
|
ConfigManager.Log_Unity_Debug.Value = val;
|
||||||
ExplorerConfig.SaveSettings();
|
ConfigManager.Handler.SaveConfig();
|
||||||
}
|
});
|
||||||
|
|
||||||
var unityToggleLayout = unityToggleObj.AddComponent<LayoutElement>();
|
ConfigManager.Log_Unity_Debug.OnValueChanged += (bool val) => { unityToggle.isOn = val; };
|
||||||
unityToggleLayout.minWidth = 170;
|
|
||||||
unityToggleLayout.flexibleWidth = 0;
|
unityToggle.isOn = LogUnity;
|
||||||
|
unityToggleText.text = "Log Unity Debug?";
|
||||||
|
unityToggleText.alignment = TextAnchor.MiddleLeft;
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(unityToggleObj, minWidth: 170, flexibleWidth: 0);
|
||||||
|
|
||||||
var unityToggleRect = unityToggleObj.transform.Find("Background").GetComponent<RectTransform>();
|
var unityToggleRect = unityToggleObj.transform.Find("Background").GetComponent<RectTransform>();
|
||||||
var pos = unityToggleRect.localPosition;
|
var pos = unityToggleRect.localPosition;
|
||||||
pos.y = -4;
|
pos.y = -4;
|
||||||
unityToggleRect.localPosition = pos;
|
unityToggleRect.localPosition = pos;
|
||||||
|
|
||||||
// // Save to disk button
|
|
||||||
|
|
||||||
// var saveToDiskObj = UIFactory.CreateToggle(bottomBarObj, out Toggle diskToggle, out Text diskToggleText);
|
|
||||||
|
|
||||||
// diskToggle.onValueChanged.AddListener(ToggleDisk);
|
|
||||||
|
|
||||||
// diskToggle.isOn = SaveToDisk;
|
|
||||||
// diskToggleText.text = "Save logs to 'Mods\\UnityExplorer\\Logs'?";
|
|
||||||
// diskToggleText.alignment = TextAnchor.MiddleLeft;
|
|
||||||
|
|
||||||
// void ToggleDisk(bool val)
|
|
||||||
// {
|
|
||||||
// SaveToDisk = val;
|
|
||||||
// ModConfig.Instance.Save_Logs_To_Disk = val;
|
|
||||||
// ModConfig.SaveSettings();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var diskToggleLayout = saveToDiskObj.AddComponent<LayoutElement>();
|
|
||||||
// diskToggleLayout.minWidth = 340;
|
|
||||||
// diskToggleLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
// var saveToDiskRect = saveToDiskObj.transform.Find("Background").GetComponent<RectTransform>();
|
|
||||||
// pos = unityToggleRect.localPosition;
|
|
||||||
// pos.y = -8;
|
|
||||||
// saveToDiskRect.localPosition = pos;
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.Inspectors;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main
|
namespace UnityExplorer.UI.Main.Home
|
||||||
{
|
{
|
||||||
public class HomePage : BaseMenuPage
|
public class HomePage : BaseMenuPage
|
||||||
{
|
{
|
||||||
@ -38,17 +37,7 @@ namespace UnityExplorer.UI.Main
|
|||||||
{
|
{
|
||||||
GameObject parent = MainMenu.Instance.PageViewport;
|
GameObject parent = MainMenu.Instance.PageViewport;
|
||||||
|
|
||||||
Content = UIFactory.CreateHorizontalGroup(parent);
|
Content = UIFactory.CreateHorizontalGroup(parent, "HomePage", true, true, true, true, 3, new Vector4(1,1,1,1)).gameObject;
|
||||||
var mainGroup = Content.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
mainGroup.padding.left = 1;
|
|
||||||
mainGroup.padding.right = 1;
|
|
||||||
mainGroup.padding.top = 1;
|
|
||||||
mainGroup.padding.bottom = 1;
|
|
||||||
mainGroup.spacing = 3;
|
|
||||||
mainGroup.childForceExpandHeight = true;
|
|
||||||
mainGroup.childForceExpandWidth = true;
|
|
||||||
mainGroup.childControlHeight = true;
|
|
||||||
mainGroup.childControlWidth = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
333
src/UI/Main/Home/InspectUnderMouse.cs
Normal file
333
src/UI/Main/Home/InspectUnderMouse.cs
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.Core.Unity;
|
||||||
|
using UnityExplorer.Core.Input;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
|
using UnityExplorer.UI;
|
||||||
|
using UnityExplorer.UI.Main;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Main.Home
|
||||||
|
{
|
||||||
|
public class InspectUnderMouse
|
||||||
|
{
|
||||||
|
public enum MouseInspectMode
|
||||||
|
{
|
||||||
|
World,
|
||||||
|
UI
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Inspecting { get; set; }
|
||||||
|
|
||||||
|
public static MouseInspectMode Mode { get; set; }
|
||||||
|
|
||||||
|
private static GameObject s_lastHit;
|
||||||
|
private static Vector3 s_lastMousePos;
|
||||||
|
|
||||||
|
private static readonly List<Graphic> _wasDisabledGraphics = new List<Graphic>();
|
||||||
|
private static readonly List<CanvasGroup> _wasDisabledCanvasGroups = new List<CanvasGroup>();
|
||||||
|
private static readonly List<GameObject> _objectsAddedCastersTo = new List<GameObject>();
|
||||||
|
|
||||||
|
internal static Camera MainCamera;
|
||||||
|
internal static GraphicRaycaster[] graphicRaycasters;
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
ConstructUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StartInspect(MouseInspectMode mode)
|
||||||
|
{
|
||||||
|
MainCamera = Camera.main;
|
||||||
|
if (!MainCamera)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Mode = mode;
|
||||||
|
Inspecting = true;
|
||||||
|
MainMenu.Instance.MainPanel.SetActive(false);
|
||||||
|
|
||||||
|
s_UIContent.SetActive(true);
|
||||||
|
|
||||||
|
if (mode == MouseInspectMode.UI)
|
||||||
|
SetupUIRaycast();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void ClearHitData()
|
||||||
|
{
|
||||||
|
s_lastHit = null;
|
||||||
|
s_objNameLabel.text = "No hits...";
|
||||||
|
s_objPathLabel.text = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StopInspect()
|
||||||
|
{
|
||||||
|
Inspecting = false;
|
||||||
|
MainMenu.Instance.MainPanel.SetActive(true);
|
||||||
|
s_UIContent.SetActive(false);
|
||||||
|
|
||||||
|
if (Mode == MouseInspectMode.UI)
|
||||||
|
StopUIInspect();
|
||||||
|
|
||||||
|
ClearHitData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateInspect()
|
||||||
|
{
|
||||||
|
if (InputManager.GetKeyDown(KeyCode.Escape))
|
||||||
|
{
|
||||||
|
StopInspect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mousePos = InputManager.MousePosition;
|
||||||
|
|
||||||
|
if (mousePos != s_lastMousePos)
|
||||||
|
UpdatePosition(mousePos);
|
||||||
|
|
||||||
|
// actual inspect raycast
|
||||||
|
|
||||||
|
switch (Mode)
|
||||||
|
{
|
||||||
|
case MouseInspectMode.UI:
|
||||||
|
RaycastUI(mousePos); break;
|
||||||
|
case MouseInspectMode.World:
|
||||||
|
RaycastWorld(mousePos); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void UpdatePosition(Vector2 mousePos)
|
||||||
|
{
|
||||||
|
s_lastMousePos = mousePos;
|
||||||
|
|
||||||
|
var inversePos = UIManager.CanvasRoot.transform.InverseTransformPoint(mousePos);
|
||||||
|
|
||||||
|
s_mousePosLabel.text = $"<color=grey>Mouse Position:</color> {mousePos.ToString()}";
|
||||||
|
|
||||||
|
float yFix = mousePos.y < 120 ? 80 : -80;
|
||||||
|
s_UIContent.transform.localPosition = new Vector3(inversePos.x, inversePos.y + yFix, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void OnHitGameObject(GameObject obj)
|
||||||
|
{
|
||||||
|
if (obj != s_lastHit)
|
||||||
|
{
|
||||||
|
s_lastHit = obj;
|
||||||
|
s_objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
|
||||||
|
s_objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InputManager.GetMouseButtonDown(0))
|
||||||
|
{
|
||||||
|
StopInspect();
|
||||||
|
InspectorManager.Instance.Inspect(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collider raycasting
|
||||||
|
|
||||||
|
internal static void RaycastWorld(Vector2 mousePos)
|
||||||
|
{
|
||||||
|
var ray = MainCamera.ScreenPointToRay(mousePos);
|
||||||
|
Physics.Raycast(ray, out RaycastHit hit, 1000f);
|
||||||
|
|
||||||
|
if (hit.transform)
|
||||||
|
{
|
||||||
|
var obj = hit.transform.gameObject;
|
||||||
|
OnHitGameObject(obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (s_lastHit)
|
||||||
|
ClearHitData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UI Graphic raycasting
|
||||||
|
|
||||||
|
private static void SetupUIRaycast()
|
||||||
|
{
|
||||||
|
foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(Canvas)))
|
||||||
|
{
|
||||||
|
var canvas = obj.Cast(typeof(Canvas)) as Canvas;
|
||||||
|
if (!canvas || !canvas.enabled || !canvas.gameObject.activeInHierarchy)
|
||||||
|
continue;
|
||||||
|
if (!canvas.GetComponent<GraphicRaycaster>())
|
||||||
|
{
|
||||||
|
canvas.gameObject.AddComponent<GraphicRaycaster>();
|
||||||
|
//ExplorerCore.Log("Added raycaster to " + canvas.name);
|
||||||
|
_objectsAddedCastersTo.Add(canvas.gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recache Graphic Raycasters each time we start
|
||||||
|
var casters = RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(GraphicRaycaster));
|
||||||
|
graphicRaycasters = new GraphicRaycaster[casters.Length];
|
||||||
|
for (int i = 0; i < casters.Length; i++)
|
||||||
|
{
|
||||||
|
graphicRaycasters[i] = casters[i].Cast(typeof(GraphicRaycaster)) as GraphicRaycaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable raycastTarget on Graphics
|
||||||
|
foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(Graphic)))
|
||||||
|
{
|
||||||
|
var graphic = obj.Cast(typeof(Graphic)) as Graphic;
|
||||||
|
if (!graphic || !graphic.enabled || graphic.raycastTarget || !graphic.gameObject.activeInHierarchy)
|
||||||
|
continue;
|
||||||
|
graphic.raycastTarget = true;
|
||||||
|
//ExplorerCore.Log("Enabled raycastTarget on " + graphic.name);
|
||||||
|
_wasDisabledGraphics.Add(graphic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable blocksRaycasts on CanvasGroups
|
||||||
|
foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(CanvasGroup)))
|
||||||
|
{
|
||||||
|
var canvas = obj.Cast(typeof(CanvasGroup)) as CanvasGroup;
|
||||||
|
if (!canvas || !canvas.gameObject.activeInHierarchy || canvas.blocksRaycasts)
|
||||||
|
continue;
|
||||||
|
canvas.blocksRaycasts = true;
|
||||||
|
//ExplorerCore.Log("Enabled raycasts on " + canvas.name);
|
||||||
|
_wasDisabledCanvasGroups.Add(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void RaycastUI(Vector2 mousePos)
|
||||||
|
{
|
||||||
|
var ped = new PointerEventData(null)
|
||||||
|
{
|
||||||
|
position = mousePos
|
||||||
|
};
|
||||||
|
|
||||||
|
#if MONO
|
||||||
|
var list = new List<RaycastResult>();
|
||||||
|
#else
|
||||||
|
var list = new Il2CppSystem.Collections.Generic.List<RaycastResult>();
|
||||||
|
#endif
|
||||||
|
//ExplorerCore.Log("~~~~~~~~~ begin raycast ~~~~~~~~");
|
||||||
|
GameObject hitObject = null;
|
||||||
|
int highestLayer = int.MinValue;
|
||||||
|
int highestOrder = int.MinValue;
|
||||||
|
int highestDepth = int.MinValue;
|
||||||
|
foreach (var gr in graphicRaycasters)
|
||||||
|
{
|
||||||
|
gr.Raycast(ped, list);
|
||||||
|
|
||||||
|
if (list.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var hit in list)
|
||||||
|
{
|
||||||
|
// Manual trying to determine which object is "on top".
|
||||||
|
// Not perfect, but not terrible.
|
||||||
|
|
||||||
|
if (!hit.gameObject)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (hit.gameObject.GetComponent<CanvasGroup>() is CanvasGroup group && group.alpha == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (hit.gameObject.GetComponent<Graphic>() is Graphic graphic && graphic.color.a == 0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (hit.sortingLayer < highestLayer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (hit.sortingLayer > highestLayer)
|
||||||
|
{
|
||||||
|
highestLayer = hit.sortingLayer;
|
||||||
|
highestDepth = int.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit.depth < highestDepth)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (hit.depth > highestDepth)
|
||||||
|
{
|
||||||
|
highestDepth = hit.depth;
|
||||||
|
highestOrder = int.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit.sortingOrder <= highestOrder)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
highestOrder = hit.sortingOrder;
|
||||||
|
hitObject = hit.gameObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (s_lastHit)
|
||||||
|
ClearHitData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hitObject)
|
||||||
|
OnHitGameObject(hitObject);
|
||||||
|
|
||||||
|
//ExplorerCore.Log("~~~~~~~~~ end raycast ~~~~~~~~");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void StopUIInspect()
|
||||||
|
{
|
||||||
|
foreach (var obj in _objectsAddedCastersTo)
|
||||||
|
{
|
||||||
|
if (obj.GetComponent<GraphicRaycaster>() is GraphicRaycaster raycaster)
|
||||||
|
GameObject.Destroy(raycaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var graphic in _wasDisabledGraphics)
|
||||||
|
graphic.raycastTarget = false;
|
||||||
|
|
||||||
|
foreach (var canvas in _wasDisabledCanvasGroups)
|
||||||
|
canvas.blocksRaycasts = false;
|
||||||
|
|
||||||
|
_objectsAddedCastersTo.Clear();
|
||||||
|
_wasDisabledCanvasGroups.Clear();
|
||||||
|
_wasDisabledGraphics.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI
|
||||||
|
|
||||||
|
internal static Text s_objNameLabel;
|
||||||
|
internal static Text s_objPathLabel;
|
||||||
|
internal static Text s_mousePosLabel;
|
||||||
|
internal static GameObject s_UIContent;
|
||||||
|
|
||||||
|
internal static void ConstructUI()
|
||||||
|
{
|
||||||
|
s_UIContent = UIFactory.CreatePanel("InspectUnderMouse_UI", out GameObject content);
|
||||||
|
|
||||||
|
var baseRect = s_UIContent.GetComponent<RectTransform>();
|
||||||
|
var half = new Vector2(0.5f, 0.5f);
|
||||||
|
baseRect.anchorMin = half;
|
||||||
|
baseRect.anchorMax = half;
|
||||||
|
baseRect.pivot = half;
|
||||||
|
baseRect.sizeDelta = new Vector2(700, 150);
|
||||||
|
|
||||||
|
var group = content.GetComponent<VerticalLayoutGroup>();
|
||||||
|
group.childForceExpandHeight = true;
|
||||||
|
|
||||||
|
// Title text
|
||||||
|
|
||||||
|
UIFactory.CreateLabel(content, "InspectLabel", "<b>Mouse Inspector</b> (press <b>ESC</b> to cancel)", TextAnchor.MiddleCenter);
|
||||||
|
|
||||||
|
s_mousePosLabel = UIFactory.CreateLabel(content, "MousePosLabel", "Mouse Position:", TextAnchor.MiddleCenter);
|
||||||
|
|
||||||
|
s_objNameLabel = UIFactory.CreateLabel(content, "HitLabelObj", "No hits...", TextAnchor.MiddleLeft);
|
||||||
|
s_objNameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
|
||||||
|
s_objPathLabel = UIFactory.CreateLabel(content, "PathLabel", "", TextAnchor.MiddleLeft);
|
||||||
|
s_objPathLabel.fontStyle = FontStyle.Italic;
|
||||||
|
s_objPathLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(s_objPathLabel.gameObject, minHeight: 75);
|
||||||
|
|
||||||
|
s_UIContent.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
215
src/UI/Main/Home/InspectorManager.cs
Normal file
215
src/UI/Main/Home/InspectorManager.cs
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityExplorer.Core.Unity;
|
||||||
|
using UnityExplorer.UI;
|
||||||
|
using UnityExplorer.UI.Main;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
|
using UnityExplorer.UI.Main.Home;
|
||||||
|
using UnityExplorer.UI.Main.Home.Inspectors;
|
||||||
|
using UnityExplorer.UI.CacheObject;
|
||||||
|
using UnityExplorer.UI.Main.Home.Inspectors.GameObjects;
|
||||||
|
using UnityExplorer.UI.Main.Home.Inspectors.Reflection;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Main.Home
|
||||||
|
{
|
||||||
|
public class InspectorManager
|
||||||
|
{
|
||||||
|
public static InspectorManager Instance { get; private set; }
|
||||||
|
|
||||||
|
public InspectorManager()
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
|
||||||
|
ConstructInspectorPane();
|
||||||
|
}
|
||||||
|
|
||||||
|
public InspectorBase m_activeInspector;
|
||||||
|
public readonly List<InspectorBase> m_currentInspectors = new List<InspectorBase>();
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_currentInspectors.Count; i++)
|
||||||
|
{
|
||||||
|
if (i >= m_currentInspectors.Count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
m_currentInspectors[i].Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Inspect(object obj, CacheObjectBase parentMember = null)
|
||||||
|
{
|
||||||
|
obj = ReflectionProvider.Instance.Cast(obj, ReflectionProvider.Instance.GetActualType(obj));
|
||||||
|
|
||||||
|
UnityEngine.Object unityObj = obj as UnityEngine.Object;
|
||||||
|
|
||||||
|
if (obj.IsNullOrDestroyed(false))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if currently inspecting this object
|
||||||
|
foreach (InspectorBase tab in m_currentInspectors)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(obj, tab.Target))
|
||||||
|
{
|
||||||
|
SetInspectorTab(tab);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if CPP
|
||||||
|
else if (unityObj && tab.Target is UnityEngine.Object uTabObj)
|
||||||
|
{
|
||||||
|
if (unityObj.m_CachedPtr == uTabObj.m_CachedPtr)
|
||||||
|
{
|
||||||
|
SetInspectorTab(tab);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
InspectorBase inspector;
|
||||||
|
if (obj is GameObject go)
|
||||||
|
inspector = new GameObjectInspector(go);
|
||||||
|
else
|
||||||
|
inspector = new InstanceInspector(obj);
|
||||||
|
|
||||||
|
if (inspector is ReflectionInspector ri)
|
||||||
|
ri.ParentMember = parentMember;
|
||||||
|
|
||||||
|
m_currentInspectors.Add(inspector);
|
||||||
|
SetInspectorTab(inspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Inspect(Type type)
|
||||||
|
{
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
ExplorerCore.LogWarning("The provided type was null!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var tab in m_currentInspectors.Where(x => x is StaticInspector))
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(tab.Target as Type, type))
|
||||||
|
{
|
||||||
|
SetInspectorTab(tab);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var inspector = new StaticInspector(type);
|
||||||
|
|
||||||
|
m_currentInspectors.Add(inspector);
|
||||||
|
SetInspectorTab(inspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetInspectorTab(InspectorBase inspector)
|
||||||
|
{
|
||||||
|
MainMenu.Instance.SetPage(HomePage.Instance);
|
||||||
|
|
||||||
|
if (m_activeInspector == inspector)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UnsetInspectorTab();
|
||||||
|
|
||||||
|
m_activeInspector = inspector;
|
||||||
|
inspector.SetActive();
|
||||||
|
|
||||||
|
OnSetInspectorTab(inspector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnsetInspectorTab()
|
||||||
|
{
|
||||||
|
if (m_activeInspector == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_activeInspector.SetInactive();
|
||||||
|
|
||||||
|
OnUnsetInspectorTab();
|
||||||
|
|
||||||
|
m_activeInspector = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject m_tabBarContent;
|
||||||
|
public static GameObject m_inspectorContent;
|
||||||
|
|
||||||
|
public void OnSetInspectorTab(InspectorBase inspector)
|
||||||
|
{
|
||||||
|
Color activeColor = new Color(0, 0.25f, 0, 1);
|
||||||
|
inspector.m_tabButton.colors = RuntimeProvider.Instance.SetColorBlock(inspector.m_tabButton.colors, activeColor, activeColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnUnsetInspectorTab()
|
||||||
|
{
|
||||||
|
m_activeInspector.m_tabButton.colors = RuntimeProvider.Instance.SetColorBlock(m_activeInspector.m_tabButton.colors,
|
||||||
|
new Color(0.2f, 0.2f, 0.2f, 1), new Color(0.1f, 0.3f, 0.1f, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConstructInspectorPane()
|
||||||
|
{
|
||||||
|
var mainObj = UIFactory.CreateVerticalGroup(HomePage.Instance.Content,
|
||||||
|
"InspectorManager_Root",
|
||||||
|
true, true, true, true,
|
||||||
|
4,
|
||||||
|
new Vector4(4,4,4,4));
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(mainObj, preferredHeight: 400, flexibleHeight: 9000, preferredWidth: 620, flexibleWidth: 9000);
|
||||||
|
|
||||||
|
var topRowObj = UIFactory.CreateHorizontalGroup(mainObj, "TopRow", false, true, true, true, 15);
|
||||||
|
|
||||||
|
var inspectorTitle = UIFactory.CreateLabel(topRowObj, "Title", "Inspector", TextAnchor.MiddleLeft, default, true, 25);
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(inspectorTitle.gameObject, minHeight: 30, flexibleHeight: 0, minWidth: 90, flexibleWidth: 20000);
|
||||||
|
|
||||||
|
ConstructToolbar(topRowObj);
|
||||||
|
|
||||||
|
// inspector tab bar
|
||||||
|
|
||||||
|
m_tabBarContent = UIFactory.CreateGridGroup(mainObj, "TabHolder", new Vector2(185, 20), new Vector2(5, 2), new Color(0.1f, 0.1f, 0.1f, 1));
|
||||||
|
|
||||||
|
var gridGroup = m_tabBarContent.GetComponent<GridLayoutGroup>();
|
||||||
|
gridGroup.padding.top = 3;
|
||||||
|
gridGroup.padding.left = 3;
|
||||||
|
gridGroup.padding.right = 3;
|
||||||
|
gridGroup.padding.bottom = 3;
|
||||||
|
|
||||||
|
// inspector content area
|
||||||
|
|
||||||
|
m_inspectorContent = UIFactory.CreateVerticalGroup(mainObj, "InspectorContent",
|
||||||
|
true, true, true, true,
|
||||||
|
0,
|
||||||
|
new Vector4(2,2,2,2),
|
||||||
|
new Color(0.1f, 0.1f, 0.1f));
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(m_inspectorContent, preferredHeight: 900, flexibleHeight: 10000, preferredWidth: 600, flexibleWidth: 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConstructToolbar(GameObject topRowObj)
|
||||||
|
{
|
||||||
|
// invisible group
|
||||||
|
UIFactory.CreateHorizontalGroup(topRowObj, "Toolbar", false, false, true, true, 10, new Vector4(2, 2, 2, 2), new Color(1,1,1,0));
|
||||||
|
|
||||||
|
// inspect under mouse button
|
||||||
|
AddMouseInspectButton(topRowObj, "UI", InspectUnderMouse.MouseInspectMode.UI);
|
||||||
|
AddMouseInspectButton(topRowObj, "3D", InspectUnderMouse.MouseInspectMode.World);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddMouseInspectButton(GameObject topRowObj, string suffix, InspectUnderMouse.MouseInspectMode mode)
|
||||||
|
{
|
||||||
|
string lbl = $"Mouse Inspect ({suffix})";
|
||||||
|
|
||||||
|
var inspectObj = UIFactory.CreateButton(topRowObj,
|
||||||
|
lbl,
|
||||||
|
lbl,
|
||||||
|
() => { InspectUnderMouse.StartInspect(mode); },
|
||||||
|
new Color(0.2f, 0.2f, 0.2f));
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(inspectObj.gameObject, minWidth: 150, flexibleWidth: 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,159 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityExplorer.Core.Inspectors;
|
|
||||||
using UnityExplorer.UI.Main;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main.Home
|
|
||||||
{
|
|
||||||
public class InspectorManagerUI
|
|
||||||
{
|
|
||||||
public GameObject m_tabBarContent;
|
|
||||||
public GameObject m_inspectorContent;
|
|
||||||
|
|
||||||
public void OnSetInspectorTab(InspectorBase inspector)
|
|
||||||
{
|
|
||||||
Color activeColor = new Color(0, 0.25f, 0, 1);
|
|
||||||
ColorBlock colors = inspector.BaseUI.tabButton.colors;
|
|
||||||
colors.normalColor = activeColor;
|
|
||||||
colors.highlightedColor = activeColor;
|
|
||||||
inspector.BaseUI.tabButton.colors = colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnUnsetInspectorTab()
|
|
||||||
{
|
|
||||||
ColorBlock colors = InspectorManager.Instance.m_activeInspector.BaseUI.tabButton.colors;
|
|
||||||
colors.normalColor = new Color(0.2f, 0.2f, 0.2f, 1);
|
|
||||||
colors.highlightedColor = new Color(0.1f, 0.3f, 0.1f, 1);
|
|
||||||
InspectorManager.Instance.m_activeInspector.BaseUI.tabButton.colors = colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ConstructInspectorPane()
|
|
||||||
{
|
|
||||||
var mainObj = UIFactory.CreateVerticalGroup(HomePage.Instance.Content, new Color(72f / 255f, 72f / 255f, 72f / 255f));
|
|
||||||
LayoutElement mainLayout = mainObj.AddComponent<LayoutElement>();
|
|
||||||
mainLayout.preferredHeight = 400;
|
|
||||||
mainLayout.flexibleHeight = 9000;
|
|
||||||
mainLayout.preferredWidth = 620;
|
|
||||||
mainLayout.flexibleWidth = 9000;
|
|
||||||
|
|
||||||
var mainGroup = mainObj.GetComponent<VerticalLayoutGroup>();
|
|
||||||
mainGroup.childForceExpandHeight = true;
|
|
||||||
mainGroup.childForceExpandWidth = true;
|
|
||||||
mainGroup.childControlHeight = true;
|
|
||||||
mainGroup.childControlWidth = true;
|
|
||||||
mainGroup.spacing = 4;
|
|
||||||
mainGroup.padding.left = 4;
|
|
||||||
mainGroup.padding.right = 4;
|
|
||||||
mainGroup.padding.top = 4;
|
|
||||||
mainGroup.padding.bottom = 4;
|
|
||||||
|
|
||||||
var topRowObj = UIFactory.CreateHorizontalGroup(mainObj, new Color(1, 1, 1, 0));
|
|
||||||
var topRowGroup = topRowObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
topRowGroup.childForceExpandWidth = false;
|
|
||||||
topRowGroup.childControlWidth = true;
|
|
||||||
topRowGroup.childForceExpandHeight = true;
|
|
||||||
topRowGroup.childControlHeight = true;
|
|
||||||
topRowGroup.spacing = 15;
|
|
||||||
|
|
||||||
var inspectorTitle = UIFactory.CreateLabel(topRowObj, TextAnchor.MiddleLeft);
|
|
||||||
Text title = inspectorTitle.GetComponent<Text>();
|
|
||||||
title.text = "Inspector";
|
|
||||||
title.fontSize = 20;
|
|
||||||
var titleLayout = inspectorTitle.AddComponent<LayoutElement>();
|
|
||||||
titleLayout.minHeight = 30;
|
|
||||||
titleLayout.flexibleHeight = 0;
|
|
||||||
titleLayout.minWidth = 90;
|
|
||||||
titleLayout.flexibleWidth = 20000;
|
|
||||||
|
|
||||||
ConstructToolbar(topRowObj);
|
|
||||||
|
|
||||||
// inspector tab bar
|
|
||||||
|
|
||||||
m_tabBarContent = UIFactory.CreateGridGroup(mainObj, new Vector2(185, 20), new Vector2(5, 2), new Color(0.1f, 0.1f, 0.1f, 1));
|
|
||||||
|
|
||||||
var gridGroup = m_tabBarContent.GetComponent<GridLayoutGroup>();
|
|
||||||
gridGroup.padding.top = 3;
|
|
||||||
gridGroup.padding.left = 3;
|
|
||||||
gridGroup.padding.right = 3;
|
|
||||||
gridGroup.padding.bottom = 3;
|
|
||||||
|
|
||||||
// inspector content area
|
|
||||||
|
|
||||||
m_inspectorContent = UIFactory.CreateVerticalGroup(mainObj, new Color(0.1f, 0.1f, 0.1f));
|
|
||||||
var inspectorGroup = m_inspectorContent.GetComponent<VerticalLayoutGroup>();
|
|
||||||
inspectorGroup.childForceExpandHeight = true;
|
|
||||||
inspectorGroup.childForceExpandWidth = true;
|
|
||||||
inspectorGroup.childControlHeight = true;
|
|
||||||
inspectorGroup.childControlWidth = true;
|
|
||||||
|
|
||||||
m_inspectorContent = UIFactory.CreateVerticalGroup(mainObj, new Color(0.1f, 0.1f, 0.1f));
|
|
||||||
var contentGroup = m_inspectorContent.GetComponent<VerticalLayoutGroup>();
|
|
||||||
contentGroup.childForceExpandHeight = true;
|
|
||||||
contentGroup.childForceExpandWidth = true;
|
|
||||||
contentGroup.childControlHeight = true;
|
|
||||||
contentGroup.childControlWidth = true;
|
|
||||||
contentGroup.padding.top = 2;
|
|
||||||
contentGroup.padding.left = 2;
|
|
||||||
contentGroup.padding.right = 2;
|
|
||||||
contentGroup.padding.bottom = 2;
|
|
||||||
|
|
||||||
var contentLayout = m_inspectorContent.AddComponent<LayoutElement>();
|
|
||||||
contentLayout.preferredHeight = 900;
|
|
||||||
contentLayout.flexibleHeight = 10000;
|
|
||||||
contentLayout.preferredWidth = 600;
|
|
||||||
contentLayout.flexibleWidth = 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ConstructToolbar(GameObject topRowObj)
|
|
||||||
{
|
|
||||||
var invisObj = UIFactory.CreateHorizontalGroup(topRowObj, new Color(1, 1, 1, 0));
|
|
||||||
var invisGroup = invisObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
invisGroup.childForceExpandWidth = false;
|
|
||||||
invisGroup.childForceExpandHeight = false;
|
|
||||||
invisGroup.childControlWidth = true;
|
|
||||||
invisGroup.childControlHeight = true;
|
|
||||||
invisGroup.padding.top = 2;
|
|
||||||
invisGroup.padding.bottom = 2;
|
|
||||||
invisGroup.padding.left = 2;
|
|
||||||
invisGroup.padding.right = 2;
|
|
||||||
invisGroup.spacing = 10;
|
|
||||||
|
|
||||||
// inspect under mouse button
|
|
||||||
AddMouseInspectButton(topRowObj, InspectUnderMouse.MouseInspectMode.UI);
|
|
||||||
AddMouseInspectButton(topRowObj, InspectUnderMouse.MouseInspectMode.World);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddMouseInspectButton(GameObject topRowObj, InspectUnderMouse.MouseInspectMode mode)
|
|
||||||
{
|
|
||||||
var inspectObj = UIFactory.CreateButton(topRowObj);
|
|
||||||
var inspectLayout = inspectObj.AddComponent<LayoutElement>();
|
|
||||||
inspectLayout.minWidth = 120;
|
|
||||||
inspectLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
var inspectText = inspectObj.GetComponentInChildren<Text>();
|
|
||||||
inspectText.text = "Mouse Inspect";
|
|
||||||
inspectText.fontSize = 13;
|
|
||||||
|
|
||||||
if (mode == InspectUnderMouse.MouseInspectMode.UI)
|
|
||||||
inspectText.text += " (UI)";
|
|
||||||
|
|
||||||
var inspectBtn = inspectObj.GetComponent<Button>();
|
|
||||||
var inspectColors = inspectBtn.colors;
|
|
||||||
inspectColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
|
|
||||||
inspectBtn.colors = inspectColors;
|
|
||||||
|
|
||||||
inspectBtn.onClick.AddListener(OnInspectMouseClicked);
|
|
||||||
|
|
||||||
void OnInspectMouseClicked()
|
|
||||||
{
|
|
||||||
InspectUnderMouse.Mode = mode;
|
|
||||||
InspectUnderMouse.StartInspect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityExplorer.Core.Unity;
|
using System.Text;
|
||||||
using UnityExplorer.UI;
|
|
||||||
using UnityExplorer.UI.Reusable;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.Input;
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.Core.Inspectors;
|
using UnityExplorer.UI.Utility;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main.Home.Inspectors
|
namespace UnityExplorer.UI.Main.Home.Inspectors.GameObjects
|
||||||
{
|
{
|
||||||
public class ChildList
|
public class ChildList
|
||||||
{
|
{
|
||||||
@ -139,29 +137,15 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
|
|
||||||
internal void ConstructChildList(GameObject parent)
|
internal void ConstructChildList(GameObject parent)
|
||||||
{
|
{
|
||||||
var vertGroupObj = UIFactory.CreateVerticalGroup(parent, new Color(1, 1, 1, 0));
|
var vertGroupObj = UIFactory.CreateVerticalGroup(parent, "ChildListGroup", false, true, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
var vertGroup = vertGroupObj.GetComponent<VerticalLayoutGroup>();
|
UIFactory.SetLayoutElement(vertGroupObj, minWidth: 120, flexibleWidth: 25000, minHeight: 200, flexibleHeight: 5000);
|
||||||
vertGroup.childForceExpandHeight = true;
|
|
||||||
vertGroup.childForceExpandWidth = false;
|
|
||||||
vertGroup.childControlWidth = true;
|
|
||||||
vertGroup.spacing = 5;
|
|
||||||
var vertLayout = vertGroupObj.AddComponent<LayoutElement>();
|
|
||||||
vertLayout.minWidth = 120;
|
|
||||||
vertLayout.flexibleWidth = 25000;
|
|
||||||
vertLayout.minHeight = 200;
|
|
||||||
vertLayout.flexibleHeight = 5000;
|
|
||||||
|
|
||||||
var childTitleObj = UIFactory.CreateLabel(vertGroupObj, TextAnchor.MiddleLeft);
|
var childTitle = UIFactory.CreateLabel(vertGroupObj, "ChildListTitle", "Children:", TextAnchor.MiddleLeft, Color.grey, true, 14);
|
||||||
var childTitleText = childTitleObj.GetComponent<Text>();
|
UIFactory.SetLayoutElement(childTitle.gameObject, minHeight: 30);
|
||||||
childTitleText.text = "Children";
|
|
||||||
childTitleText.color = Color.grey;
|
|
||||||
childTitleText.fontSize = 14;
|
|
||||||
var childTitleLayout = childTitleObj.AddComponent<LayoutElement>();
|
|
||||||
childTitleLayout.minHeight = 30;
|
|
||||||
|
|
||||||
var childrenScrollObj = UIFactory.CreateScrollView(vertGroupObj, out s_childListContent, out SliderScrollbar scroller, new Color(0.07f, 0.07f, 0.07f));
|
var childrenScrollObj = UIFactory.CreateScrollView(vertGroupObj, "ChildListScrollView", out s_childListContent,
|
||||||
var contentLayout = childrenScrollObj.GetComponent<LayoutElement>();
|
out SliderScrollbar scroller, new Color(0.07f, 0.07f, 0.07f));
|
||||||
contentLayout.minHeight = 50;
|
UIFactory.SetLayoutElement(childrenScrollObj, minHeight: 50);
|
||||||
|
|
||||||
s_childListPageHandler = new PageHandler(scroller);
|
s_childListPageHandler = new PageHandler(scroller);
|
||||||
s_childListPageHandler.ConstructUI(vertGroupObj);
|
s_childListPageHandler.ConstructUI(vertGroupObj);
|
||||||
@ -172,46 +156,37 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
{
|
{
|
||||||
int thisIndex = s_childListTexts.Count;
|
int thisIndex = s_childListTexts.Count;
|
||||||
|
|
||||||
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(s_childListContent, new Color(0.07f, 0.07f, 0.07f));
|
var btnGroupObj = UIFactory.CreateHorizontalGroup(s_childListContent, "ChildButtonGroup", true, false, true, true,
|
||||||
HorizontalLayoutGroup btnGroup = btnGroupObj.GetComponent<HorizontalLayoutGroup>();
|
0, default, new Color(0.07f, 0.07f, 0.07f));
|
||||||
btnGroup.childForceExpandWidth = true;
|
UIFactory.SetLayoutElement(btnGroupObj, flexibleWidth: 320, minHeight: 25, flexibleHeight: 0);
|
||||||
btnGroup.childControlWidth = true;
|
|
||||||
btnGroup.childForceExpandHeight = false;
|
|
||||||
btnGroup.childControlHeight = true;
|
|
||||||
LayoutElement btnLayout = btnGroupObj.AddComponent<LayoutElement>();
|
|
||||||
btnLayout.flexibleWidth = 320;
|
|
||||||
btnLayout.minHeight = 25;
|
|
||||||
btnLayout.flexibleHeight = 0;
|
|
||||||
btnGroupObj.AddComponent<Mask>();
|
btnGroupObj.AddComponent<Mask>();
|
||||||
|
|
||||||
var toggleObj = UIFactory.CreateToggle(btnGroupObj, out Toggle toggle, out Text toggleText, new Color(0.3f, 0.3f, 0.3f));
|
var toggleObj = UIFactory.CreateToggle(btnGroupObj, "Toggle", out Toggle toggle, out Text toggleText, new Color(0.3f, 0.3f, 0.3f));
|
||||||
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: 25);
|
||||||
toggleLayout.minHeight = 25;
|
|
||||||
toggleLayout.minWidth = 25;
|
|
||||||
toggleText.text = "";
|
toggleText.text = "";
|
||||||
toggle.isOn = false;
|
toggle.isOn = false;
|
||||||
s_childListToggles.Add(toggle);
|
s_childListToggles.Add(toggle);
|
||||||
toggle.onValueChanged.AddListener((bool val) => { OnToggleClicked(thisIndex, val); });
|
toggle.onValueChanged.AddListener((bool val) => { OnToggleClicked(thisIndex, val); });
|
||||||
|
|
||||||
GameObject mainButtonObj = UIFactory.CreateButton(btnGroupObj);
|
ColorBlock mainColors = new ColorBlock();
|
||||||
LayoutElement mainBtnLayout = mainButtonObj.AddComponent<LayoutElement>();
|
mainColors = RuntimeProvider.Instance.SetColorBlock(mainColors, new Color(0.07f, 0.07f, 0.07f),
|
||||||
mainBtnLayout.minHeight = 25;
|
new Color(0.2f, 0.2f, 0.2f, 1), new Color(0.05f, 0.05f, 0.05f));
|
||||||
mainBtnLayout.flexibleHeight = 0;
|
|
||||||
mainBtnLayout.minWidth = 25;
|
|
||||||
mainBtnLayout.flexibleWidth = 999;
|
|
||||||
Button mainBtn = mainButtonObj.GetComponent<Button>();
|
|
||||||
ColorBlock mainColors = mainBtn.colors;
|
|
||||||
mainColors.normalColor = new Color(0.07f, 0.07f, 0.07f);
|
|
||||||
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1);
|
|
||||||
mainBtn.colors = mainColors;
|
|
||||||
mainBtn.onClick.AddListener(() => { OnChildListObjectClicked(thisIndex); });
|
|
||||||
|
|
||||||
Text mainText = mainButtonObj.GetComponentInChildren<Text>();
|
var mainBtn = UIFactory.CreateButton(btnGroupObj,
|
||||||
|
"MainButton",
|
||||||
|
"",
|
||||||
|
() => { OnChildListObjectClicked(thisIndex); },
|
||||||
|
mainColors);
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(mainBtn.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 25, flexibleWidth: 9999);
|
||||||
|
|
||||||
|
Text mainText = mainBtn.GetComponentInChildren<Text>();
|
||||||
mainText.alignment = TextAnchor.MiddleLeft;
|
mainText.alignment = TextAnchor.MiddleLeft;
|
||||||
mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
mainText.resizeTextForBestFit = true;
|
mainText.resizeTextForBestFit = true;
|
||||||
mainText.resizeTextMaxSize = 14;
|
mainText.resizeTextMaxSize = 14;
|
||||||
mainText.resizeTextMinSize = 10;
|
mainText.resizeTextMinSize = 10;
|
||||||
|
|
||||||
s_childListTexts.Add(mainText);
|
s_childListTexts.Add(mainText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityExplorer.UI;
|
using System.Text;
|
||||||
using UnityExplorer.UI.Reusable;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.Input;
|
|
||||||
using UnityExplorer.Core;
|
using UnityExplorer.Core;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
using UnityExplorer.Core.Inspectors;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main.Home.Inspectors
|
namespace UnityExplorer.UI.Main.Home.Inspectors.GameObjects
|
||||||
{
|
{
|
||||||
public class ComponentList
|
public class ComponentList
|
||||||
{
|
{
|
||||||
@ -137,34 +135,20 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region UI CONSTRUCTION
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
internal void ConstructCompList(GameObject parent)
|
internal void ConstructCompList(GameObject parent)
|
||||||
{
|
{
|
||||||
var vertGroupObj = UIFactory.CreateVerticalGroup(parent, new Color(1, 1, 1, 0));
|
var vertGroupObj = UIFactory.CreateVerticalGroup(parent, "ComponentList", false, true, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
var vertGroup = vertGroupObj.GetComponent<VerticalLayoutGroup>();
|
UIFactory.SetLayoutElement(vertGroupObj, minWidth: 120, flexibleWidth: 25000, minHeight: 200, flexibleHeight: 5000);
|
||||||
vertGroup.childForceExpandHeight = true;
|
|
||||||
vertGroup.childForceExpandWidth = false;
|
|
||||||
vertGroup.childControlWidth = true;
|
|
||||||
vertGroup.spacing = 5;
|
|
||||||
var vertLayout = vertGroupObj.AddComponent<LayoutElement>();
|
|
||||||
vertLayout.minWidth = 120;
|
|
||||||
vertLayout.flexibleWidth = 25000;
|
|
||||||
vertLayout.minHeight = 200;
|
|
||||||
vertLayout.flexibleHeight = 5000;
|
|
||||||
|
|
||||||
var compTitleObj = UIFactory.CreateLabel(vertGroupObj, TextAnchor.MiddleLeft);
|
var compTitle = UIFactory.CreateLabel(vertGroupObj, "ComponentsTitle", "Components:", TextAnchor.MiddleLeft, Color.grey);
|
||||||
var compTitleText = compTitleObj.GetComponent<Text>();
|
UIFactory.SetLayoutElement(compTitle.gameObject, minHeight: 30);
|
||||||
compTitleText.text = "Components";
|
|
||||||
compTitleText.color = Color.grey;
|
|
||||||
compTitleText.fontSize = 14;
|
|
||||||
var childTitleLayout = compTitleObj.AddComponent<LayoutElement>();
|
|
||||||
childTitleLayout.minHeight = 30;
|
|
||||||
|
|
||||||
var compScrollObj = UIFactory.CreateScrollView(vertGroupObj, out s_compListContent, out SliderScrollbar scroller, new Color(0.07f, 0.07f, 0.07f));
|
var compScrollObj = UIFactory.CreateScrollView(vertGroupObj, "ComponentListScrollView", out s_compListContent,
|
||||||
var contentLayout = compScrollObj.AddComponent<LayoutElement>();
|
out SliderScrollbar scroller, new Color(0.07f, 0.07f, 0.07f));
|
||||||
contentLayout.minHeight = 50;
|
|
||||||
contentLayout.flexibleHeight = 5000;
|
UIFactory.SetLayoutElement(compScrollObj, minHeight: 50, flexibleHeight: 5000);
|
||||||
|
|
||||||
s_compListPageHandler = new PageHandler(scroller);
|
s_compListPageHandler = new PageHandler(scroller);
|
||||||
s_compListPageHandler.ConstructUI(vertGroupObj);
|
s_compListPageHandler.ConstructUI(vertGroupObj);
|
||||||
@ -175,26 +159,15 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
{
|
{
|
||||||
int thisIndex = s_compListTexts.Count;
|
int thisIndex = s_compListTexts.Count;
|
||||||
|
|
||||||
GameObject groupObj = UIFactory.CreateHorizontalGroup(s_compListContent, new Color(0.07f, 0.07f, 0.07f));
|
GameObject groupObj = UIFactory.CreateHorizontalGroup(s_compListContent, "CompListButton", true, false, true, true, 0, default,
|
||||||
HorizontalLayoutGroup group = groupObj.GetComponent<HorizontalLayoutGroup>();
|
new Color(0.07f, 0.07f, 0.07f), TextAnchor.MiddleLeft);
|
||||||
group.childForceExpandWidth = true;
|
UIFactory.SetLayoutElement(groupObj, minWidth: 25, flexibleWidth: 999, minHeight: 25, flexibleHeight: 0);
|
||||||
group.childControlWidth = true;
|
|
||||||
group.childForceExpandHeight = false;
|
|
||||||
group.childControlHeight = true;
|
|
||||||
group.childAlignment = TextAnchor.MiddleLeft;
|
|
||||||
LayoutElement groupLayout = groupObj.AddComponent<LayoutElement>();
|
|
||||||
groupLayout.minWidth = 25;
|
|
||||||
groupLayout.flexibleWidth = 999;
|
|
||||||
groupLayout.minHeight = 25;
|
|
||||||
groupLayout.flexibleHeight = 0;
|
|
||||||
groupObj.AddComponent<Mask>();
|
groupObj.AddComponent<Mask>();
|
||||||
|
|
||||||
// Behaviour enabled toggle
|
// Behaviour enabled toggle
|
||||||
|
|
||||||
var toggleObj = UIFactory.CreateToggle(groupObj, out Toggle toggle, out Text toggleText, new Color(0.3f, 0.3f, 0.3f));
|
var toggleObj = UIFactory.CreateToggle(groupObj, "EnabledToggle", out Toggle toggle, out Text toggleText, new Color(0.3f, 0.3f, 0.3f));
|
||||||
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(toggleObj, minWidth: 25, minHeight: 25);
|
||||||
toggleLayout.minHeight = 25;
|
|
||||||
toggleLayout.minWidth = 25;
|
|
||||||
toggleText.text = "";
|
toggleText.text = "";
|
||||||
toggle.isOn = true;
|
toggle.isOn = true;
|
||||||
s_compToggles.Add(toggle);
|
s_compToggles.Add(toggle);
|
||||||
@ -202,35 +175,30 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
|
|
||||||
// Main component button
|
// Main component button
|
||||||
|
|
||||||
GameObject mainButtonObj = UIFactory.CreateButton(groupObj);
|
ColorBlock mainColors = new ColorBlock();
|
||||||
LayoutElement mainBtnLayout = mainButtonObj.AddComponent<LayoutElement>();
|
mainColors = RuntimeProvider.Instance.SetColorBlock(mainColors, new Color(0.07f, 0.07f, 0.07f),
|
||||||
mainBtnLayout.minHeight = 25;
|
new Color(0.2f, 0.2f, 0.2f, 1), new Color(0.05f, 0.05f, 0.05f));
|
||||||
mainBtnLayout.flexibleHeight = 0;
|
|
||||||
mainBtnLayout.minWidth = 25;
|
var mainBtn = UIFactory.CreateButton(groupObj,
|
||||||
mainBtnLayout.flexibleWidth = 999;
|
"MainButton",
|
||||||
Button mainBtn = mainButtonObj.GetComponent<Button>();
|
"",
|
||||||
ColorBlock mainColors = mainBtn.colors;
|
() => { OnCompListObjectClicked(thisIndex); },
|
||||||
mainColors.normalColor = new Color(0.07f, 0.07f, 0.07f);
|
mainColors);
|
||||||
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1);
|
|
||||||
mainBtn.colors = mainColors;
|
UIFactory.SetLayoutElement(mainBtn.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 25, flexibleWidth: 999);
|
||||||
mainBtn.onClick.AddListener(() => { OnCompListObjectClicked(thisIndex); });
|
|
||||||
|
|
||||||
// Component button text
|
// Component button text
|
||||||
|
|
||||||
Text mainText = mainButtonObj.GetComponentInChildren<Text>();
|
Text mainText = mainBtn.GetComponentInChildren<Text>();
|
||||||
mainText.alignment = TextAnchor.MiddleLeft;
|
mainText.alignment = TextAnchor.MiddleLeft;
|
||||||
mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
mainText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
//mainText.color = SyntaxColors.Class_Instance.ToColor();
|
|
||||||
mainText.resizeTextForBestFit = true;
|
mainText.resizeTextForBestFit = true;
|
||||||
mainText.resizeTextMaxSize = 14;
|
mainText.resizeTextMaxSize = 14;
|
||||||
mainText.resizeTextMinSize = 8;
|
mainText.resizeTextMinSize = 8;
|
||||||
|
|
||||||
s_compListTexts.Add(mainText);
|
s_compListTexts.Add(mainText);
|
||||||
|
|
||||||
// TODO remove component button
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityExplorer.UI;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.Input;
|
using UnityExplorer.Core.Input;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.Core.Inspectors;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main.Home.Inspectors
|
namespace UnityExplorer.UI.Main.Home.Inspectors.GameObjects
|
||||||
{
|
{
|
||||||
public class GameObjectControls
|
public class GameObjectControls
|
||||||
{
|
{
|
||||||
@ -19,6 +19,24 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
Instance = this;
|
Instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool Showing;
|
||||||
|
|
||||||
|
internal static void ToggleVisibility() => SetVisibility(!Showing);
|
||||||
|
|
||||||
|
internal static void SetVisibility(bool show)
|
||||||
|
{
|
||||||
|
if (show == Showing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Showing = show;
|
||||||
|
|
||||||
|
m_hideShowLabel.text = show ? "Hide" : "Show";
|
||||||
|
m_contentObj.SetActive(show);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static GameObject m_contentObj;
|
||||||
|
internal static Text m_hideShowLabel;
|
||||||
|
|
||||||
private static InputField s_setParentInput;
|
private static InputField s_setParentInput;
|
||||||
|
|
||||||
private static ControlEditor s_positionControl;
|
private static ControlEditor s_positionControl;
|
||||||
@ -59,22 +77,22 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
{
|
{
|
||||||
var go = GameObjectInspector.ActiveInstance.TargetGO;
|
var go = GameObjectInspector.ActiveInstance.TargetGO;
|
||||||
|
|
||||||
s_positionControl.fullValue.text = go.transform.position.ToStringLong();
|
s_positionControl.fullValue.text = go.transform.position.ToStringPretty();
|
||||||
s_positionControl.values[0].text = go.transform.position.x.ToString("F3");
|
s_positionControl.values[0].text = go.transform.position.x.ToString("F3");
|
||||||
s_positionControl.values[1].text = go.transform.position.y.ToString("F3");
|
s_positionControl.values[1].text = go.transform.position.y.ToString("F3");
|
||||||
s_positionControl.values[2].text = go.transform.position.z.ToString("F3");
|
s_positionControl.values[2].text = go.transform.position.z.ToString("F3");
|
||||||
|
|
||||||
s_localPosControl.fullValue.text = go.transform.localPosition.ToStringLong();
|
s_localPosControl.fullValue.text = go.transform.localPosition.ToStringPretty();
|
||||||
s_localPosControl.values[0].text = go.transform.localPosition.x.ToString("F3");
|
s_localPosControl.values[0].text = go.transform.localPosition.x.ToString("F3");
|
||||||
s_localPosControl.values[1].text = go.transform.localPosition.y.ToString("F3");
|
s_localPosControl.values[1].text = go.transform.localPosition.y.ToString("F3");
|
||||||
s_localPosControl.values[2].text = go.transform.localPosition.z.ToString("F3");
|
s_localPosControl.values[2].text = go.transform.localPosition.z.ToString("F3");
|
||||||
|
|
||||||
s_rotationControl.fullValue.text = go.transform.eulerAngles.ToStringLong();
|
s_rotationControl.fullValue.text = go.transform.eulerAngles.ToStringPretty();
|
||||||
s_rotationControl.values[0].text = go.transform.eulerAngles.x.ToString("F3");
|
s_rotationControl.values[0].text = go.transform.eulerAngles.x.ToString("F3");
|
||||||
s_rotationControl.values[1].text = go.transform.eulerAngles.y.ToString("F3");
|
s_rotationControl.values[1].text = go.transform.eulerAngles.y.ToString("F3");
|
||||||
s_rotationControl.values[2].text = go.transform.eulerAngles.z.ToString("F3");
|
s_rotationControl.values[2].text = go.transform.eulerAngles.z.ToString("F3");
|
||||||
|
|
||||||
s_scaleControl.fullValue.text = go.transform.localScale.ToStringLong();
|
s_scaleControl.fullValue.text = go.transform.localScale.ToStringPretty();
|
||||||
s_scaleControl.values[0].text = go.transform.localScale.x.ToString("F3");
|
s_scaleControl.values[0].text = go.transform.localScale.x.ToString("F3");
|
||||||
s_scaleControl.values[1].text = go.transform.localScale.y.ToString("F3");
|
s_scaleControl.values[1].text = go.transform.localScale.y.ToString("F3");
|
||||||
s_scaleControl.values[2].text = go.transform.localScale.z.ToString("F3");
|
s_scaleControl.values[2].text = go.transform.localScale.z.ToString("F3");
|
||||||
@ -244,184 +262,79 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
|
|
||||||
internal void ConstructControls(GameObject parent)
|
internal void ConstructControls(GameObject parent)
|
||||||
{
|
{
|
||||||
var controlsObj = UIFactory.CreateVerticalGroup(parent, new Color(0.07f, 0.07f, 0.07f));
|
var mainGroup = UIFactory.CreateVerticalGroup(parent, "ControlsGroup", false, false, true, true, 5, new Vector4(4,4,4,4),
|
||||||
var controlsGroup = controlsObj.GetComponent<VerticalLayoutGroup>();
|
new Color(0.07f, 0.07f, 0.07f));
|
||||||
controlsGroup.childForceExpandWidth = false;
|
|
||||||
controlsGroup.childControlWidth = true;
|
|
||||||
controlsGroup.childForceExpandHeight = false;
|
|
||||||
controlsGroup.spacing = 5;
|
|
||||||
controlsGroup.padding.top = 4;
|
|
||||||
controlsGroup.padding.left = 4;
|
|
||||||
controlsGroup.padding.right = 4;
|
|
||||||
controlsGroup.padding.bottom = 4;
|
|
||||||
|
|
||||||
// ~~~~~~ Top row ~~~~~~
|
// ~~~~~~ Top row ~~~~~~
|
||||||
|
|
||||||
var topRow = UIFactory.CreateHorizontalGroup(controlsObj, new Color(1, 1, 1, 0));
|
var topRow = UIFactory.CreateHorizontalGroup(mainGroup, "TopRow", false, false, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
var topRowGroup = topRow.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
topRowGroup.childForceExpandWidth = false;
|
|
||||||
topRowGroup.childControlWidth = true;
|
|
||||||
topRowGroup.childForceExpandHeight = false;
|
|
||||||
topRowGroup.childControlHeight = true;
|
|
||||||
topRowGroup.spacing = 5;
|
|
||||||
|
|
||||||
var hideButtonObj = UIFactory.CreateButton(topRow);
|
var hideButton = UIFactory.CreateButton(topRow, "ToggleShowButton", "Show", ToggleVisibility, new Color(0.16f, 0.16f, 0.16f));
|
||||||
var hideButton = hideButtonObj.GetComponent<Button>();
|
UIFactory.SetLayoutElement(hideButton.gameObject, minWidth: 40, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
|
||||||
var hideColors = hideButton.colors;
|
m_hideShowLabel = hideButton.GetComponentInChildren<Text>();
|
||||||
hideColors.normalColor = new Color(0.16f, 0.16f, 0.16f);
|
|
||||||
hideButton.colors = hideColors;
|
|
||||||
var hideText = hideButtonObj.GetComponentInChildren<Text>();
|
|
||||||
hideText.text = "Show";
|
|
||||||
hideText.fontSize = 14;
|
|
||||||
var hideButtonLayout = hideButtonObj.AddComponent<LayoutElement>();
|
|
||||||
hideButtonLayout.minWidth = 40;
|
|
||||||
hideButtonLayout.flexibleWidth = 0;
|
|
||||||
hideButtonLayout.minHeight = 25;
|
|
||||||
hideButtonLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
var topTitle = UIFactory.CreateLabel(topRow, TextAnchor.MiddleLeft);
|
var topTitle = UIFactory.CreateLabel(topRow, "ControlsLabel", "Controls", TextAnchor.MiddleLeft);
|
||||||
var topText = topTitle.GetComponent<Text>();
|
UIFactory.SetLayoutElement(topTitle.gameObject, minWidth: 100, flexibleWidth: 9500, minHeight: 25);
|
||||||
topText.text = "Controls";
|
|
||||||
var titleLayout = topTitle.AddComponent<LayoutElement>();
|
|
||||||
titleLayout.minWidth = 100;
|
|
||||||
titleLayout.flexibleWidth = 9500;
|
|
||||||
titleLayout.minHeight = 25;
|
|
||||||
|
|
||||||
//// ~~~~~~~~ Content ~~~~~~~~ //
|
//// ~~~~~~~~ Content ~~~~~~~~ //
|
||||||
|
|
||||||
var contentObj = UIFactory.CreateVerticalGroup(controlsObj, new Color(1, 1, 1, 0));
|
m_contentObj = UIFactory.CreateVerticalGroup(mainGroup, "ContentGroup", true, false, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
var contentGroup = contentObj.GetComponent<VerticalLayoutGroup>();
|
|
||||||
contentGroup.childForceExpandHeight = false;
|
|
||||||
contentGroup.childControlHeight = true;
|
|
||||||
contentGroup.spacing = 5;
|
|
||||||
contentGroup.childForceExpandWidth = true;
|
|
||||||
contentGroup.childControlWidth = true;
|
|
||||||
|
|
||||||
// ~~ add hide button callback now that we have scroll reference ~~
|
|
||||||
hideButton.onClick.AddListener(OnHideClicked);
|
|
||||||
void OnHideClicked()
|
|
||||||
{
|
|
||||||
if (hideText.text == "Show")
|
|
||||||
{
|
|
||||||
hideText.text = "Hide";
|
|
||||||
contentObj.SetActive(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hideText.text = "Show";
|
|
||||||
contentObj.SetActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// transform controls
|
// transform controls
|
||||||
ConstructVector3Editor(contentObj, "Position", ControlType.position, out s_positionControl);
|
ConstructVector3Editor(m_contentObj, "Position", ControlType.position, out s_positionControl);
|
||||||
ConstructVector3Editor(contentObj, "Local Position", ControlType.localPosition, out s_localPosControl);
|
ConstructVector3Editor(m_contentObj, "Local Position", ControlType.localPosition, out s_localPosControl);
|
||||||
ConstructVector3Editor(contentObj, "Rotation", ControlType.eulerAngles, out s_rotationControl);
|
ConstructVector3Editor(m_contentObj, "Rotation", ControlType.eulerAngles, out s_rotationControl);
|
||||||
ConstructVector3Editor(contentObj, "Scale", ControlType.localScale, out s_scaleControl);
|
ConstructVector3Editor(m_contentObj, "Scale", ControlType.localScale, out s_scaleControl);
|
||||||
|
|
||||||
// set parent
|
// set parent
|
||||||
ConstructSetParent(contentObj);
|
ConstructSetParent(m_contentObj);
|
||||||
|
|
||||||
// bottom row buttons
|
// bottom row buttons
|
||||||
ConstructBottomButtons(contentObj);
|
ConstructBottomButtons(m_contentObj);
|
||||||
|
|
||||||
// set controls content inactive now that content is made (otherwise TMP font size goes way too big?)
|
// set controls content inactive now that content is made (otherwise TMP font size goes way too big?)
|
||||||
contentObj.SetActive(false);
|
m_contentObj.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ConstructSetParent(GameObject contentObj)
|
internal void ConstructSetParent(GameObject contentObj)
|
||||||
{
|
{
|
||||||
var setParentGroupObj = UIFactory.CreateHorizontalGroup(contentObj, new Color(1, 1, 1, 0));
|
var setParentGroupObj = UIFactory.CreateHorizontalGroup(contentObj, "SetParentRow", false, false, true, true, 5, default,
|
||||||
var setParentGroup = setParentGroupObj.GetComponent<HorizontalLayoutGroup>();
|
new Color(1, 1, 1, 0));
|
||||||
setParentGroup.childForceExpandHeight = false;
|
UIFactory.SetLayoutElement(setParentGroupObj, minHeight: 25, flexibleHeight: 0);
|
||||||
setParentGroup.childControlHeight = true;
|
|
||||||
setParentGroup.childForceExpandWidth = false;
|
|
||||||
setParentGroup.childControlWidth = true;
|
|
||||||
setParentGroup.spacing = 5;
|
|
||||||
var setParentLayout = setParentGroupObj.AddComponent<LayoutElement>();
|
|
||||||
setParentLayout.minHeight = 25;
|
|
||||||
setParentLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
var setParentLabelObj = UIFactory.CreateLabel(setParentGroupObj, TextAnchor.MiddleLeft);
|
var title = UIFactory.CreateLabel(setParentGroupObj, "SetParentLabel", "Set Parent:", TextAnchor.MiddleLeft, Color.grey);
|
||||||
var setParentLabel = setParentLabelObj.GetComponent<Text>();
|
UIFactory.SetLayoutElement(title.gameObject, minWidth: 110, minHeight: 25, flexibleHeight: 0);
|
||||||
setParentLabel.text = "Set Parent:";
|
|
||||||
setParentLabel.color = Color.grey;
|
|
||||||
setParentLabel.fontSize = 14;
|
|
||||||
var setParentLabelLayout = setParentLabelObj.AddComponent<LayoutElement>();
|
|
||||||
setParentLabelLayout.minWidth = 110;
|
|
||||||
setParentLabelLayout.minHeight = 25;
|
|
||||||
setParentLabelLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
var setParentInputObj = UIFactory.CreateInputField(setParentGroupObj);
|
var inputFieldObj = UIFactory.CreateInputField(setParentGroupObj, "SetParentInputField", "Enter a GameObject name or path...");
|
||||||
s_setParentInput = setParentInputObj.GetComponent<InputField>();
|
s_setParentInput = inputFieldObj.GetComponent<InputField>();
|
||||||
var placeholderInput = s_setParentInput.placeholder.GetComponent<Text>();
|
UIFactory.SetLayoutElement(inputFieldObj, minHeight: 25, preferredWidth: 400, flexibleWidth: 9999);
|
||||||
placeholderInput.text = "Enter a GameObject name or path...";
|
|
||||||
var setParentInputLayout = setParentInputObj.AddComponent<LayoutElement>();
|
|
||||||
setParentInputLayout.minHeight = 25;
|
|
||||||
setParentInputLayout.preferredWidth = 400;
|
|
||||||
setParentInputLayout.flexibleWidth = 9999;
|
|
||||||
|
|
||||||
var applyButtonObj = UIFactory.CreateButton(setParentGroupObj);
|
var applyButton = UIFactory.CreateButton(setParentGroupObj, "SetParentButton", "Apply", OnSetParentClicked);
|
||||||
var applyButton = applyButtonObj.GetComponent<Button>();
|
UIFactory.SetLayoutElement(applyButton.gameObject, minWidth: 55, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
|
||||||
applyButton.onClick.AddListener(OnSetParentClicked);
|
|
||||||
var applyText = applyButtonObj.GetComponentInChildren<Text>();
|
|
||||||
applyText.text = "Apply";
|
|
||||||
var applyLayout = applyButtonObj.AddComponent<LayoutElement>();
|
|
||||||
applyLayout.minWidth = 55;
|
|
||||||
applyLayout.flexibleWidth = 0;
|
|
||||||
applyLayout.minHeight = 25;
|
|
||||||
applyLayout.flexibleHeight = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ConstructVector3Editor(GameObject parent, string title, ControlType type, out ControlEditor editor)
|
internal void ConstructVector3Editor(GameObject parent, string titleText, ControlType type, out ControlEditor editor)
|
||||||
{
|
{
|
||||||
editor = new ControlEditor();
|
editor = new ControlEditor();
|
||||||
|
|
||||||
var topBarObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
var topBarObj = UIFactory.CreateHorizontalGroup(parent, "Vector3Editor", false, false, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
var topGroup = topBarObj.GetComponent<HorizontalLayoutGroup>();
|
UIFactory.SetLayoutElement(topBarObj, minHeight: 25, flexibleHeight: 0);
|
||||||
topGroup.childForceExpandWidth = false;
|
|
||||||
topGroup.childControlWidth = true;
|
|
||||||
topGroup.childForceExpandHeight = false;
|
|
||||||
topGroup.childControlHeight = true;
|
|
||||||
topGroup.spacing = 5;
|
|
||||||
var topLayout = topBarObj.AddComponent<LayoutElement>();
|
|
||||||
topLayout.minHeight = 25;
|
|
||||||
topLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
var titleObj = UIFactory.CreateLabel(topBarObj, TextAnchor.MiddleLeft);
|
var title = UIFactory.CreateLabel(topBarObj, "Title", titleText, TextAnchor.MiddleLeft, Color.grey);
|
||||||
var titleText = titleObj.GetComponent<Text>();
|
UIFactory.SetLayoutElement(title.gameObject, minWidth: 110, flexibleWidth: 0, minHeight: 25);
|
||||||
titleText.text = title;
|
|
||||||
titleText.color = Color.grey;
|
|
||||||
titleText.fontSize = 14;
|
|
||||||
var titleLayout = titleObj.AddComponent<LayoutElement>();
|
|
||||||
titleLayout.minWidth = 110;
|
|
||||||
titleLayout.flexibleWidth = 0;
|
|
||||||
titleLayout.minHeight = 25;
|
|
||||||
|
|
||||||
// expand button
|
// expand button
|
||||||
var expandButtonObj = UIFactory.CreateButton(topBarObj);
|
var expandButton = UIFactory.CreateButton(topBarObj, "ExpandArrow", "▼");
|
||||||
var expandButton = expandButtonObj.GetComponent<Button>();
|
var expandText = expandButton.GetComponentInChildren<Text>();
|
||||||
var expandText = expandButtonObj.GetComponentInChildren<Text>();
|
|
||||||
expandText.text = "▼";
|
|
||||||
expandText.fontSize = 12;
|
expandText.fontSize = 12;
|
||||||
var btnLayout = expandButtonObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(expandButton.gameObject, minWidth: 35, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
|
||||||
btnLayout.minWidth = 35;
|
|
||||||
btnLayout.flexibleWidth = 0;
|
|
||||||
btnLayout.minHeight = 25;
|
|
||||||
btnLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
// readonly value input
|
// readonly value input
|
||||||
|
|
||||||
var valueInputObj = UIFactory.CreateInputField(topBarObj);
|
var valueInputObj = UIFactory.CreateInputField(topBarObj, "ValueInput", "...");
|
||||||
var valueInput = valueInputObj.GetComponent<InputField>();
|
var valueInput = valueInputObj.GetComponent<InputField>();
|
||||||
valueInput.readOnly = true;
|
valueInput.readOnly = true;
|
||||||
//valueInput.richText = true;
|
UIFactory.SetLayoutElement(valueInputObj, minHeight: 25, flexibleHeight: 0, preferredWidth: 400, flexibleWidth: 9999);
|
||||||
//valueInput.isRichTextEditingAllowed = true;
|
|
||||||
var valueInputLayout = valueInputObj.AddComponent<LayoutElement>();
|
|
||||||
valueInputLayout.minHeight = 25;
|
|
||||||
valueInputLayout.flexibleHeight = 0;
|
|
||||||
valueInputLayout.preferredWidth = 400;
|
|
||||||
valueInputLayout.flexibleWidth = 9999;
|
|
||||||
|
|
||||||
editor.fullValue = valueInput;
|
editor.fullValue = valueInput;
|
||||||
|
|
||||||
@ -459,89 +372,43 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
|
|
||||||
internal GameObject ConstructEditorRow(GameObject parent, ControlEditor editor, ControlType type, VectorValue vectorValue)
|
internal GameObject ConstructEditorRow(GameObject parent, ControlEditor editor, ControlType type, VectorValue vectorValue)
|
||||||
{
|
{
|
||||||
var rowObject = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
var rowObject = UIFactory.CreateHorizontalGroup(parent, "EditorRow", false, false, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
var rowGroup = rowObject.GetComponent<HorizontalLayoutGroup>();
|
UIFactory.SetLayoutElement(rowObject, minHeight: 25, flexibleHeight: 0, minWidth: 100);
|
||||||
rowGroup.childForceExpandWidth = false;
|
|
||||||
rowGroup.childControlWidth = true;
|
|
||||||
rowGroup.childForceExpandHeight = false;
|
|
||||||
rowGroup.childControlHeight = true;
|
|
||||||
rowGroup.spacing = 5;
|
|
||||||
var rowLayout = rowObject.AddComponent<LayoutElement>();
|
|
||||||
rowLayout.minHeight = 25;
|
|
||||||
rowLayout.flexibleHeight = 0;
|
|
||||||
rowLayout.minWidth = 100;
|
|
||||||
|
|
||||||
// Value labels
|
// Value labels
|
||||||
|
|
||||||
var labelObj = UIFactory.CreateLabel(rowObject, TextAnchor.MiddleLeft);
|
var valueTitle = UIFactory.CreateLabel(rowObject, "ValueTitle", $"{vectorValue.ToString().ToUpper()}:", TextAnchor.MiddleLeft, Color.cyan);
|
||||||
var labelText = labelObj.GetComponent<Text>();
|
UIFactory.SetLayoutElement(valueTitle.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 25, flexibleWidth: 0);
|
||||||
labelText.color = Color.cyan;
|
|
||||||
labelText.text = $"{vectorValue.ToString().ToUpper()}:";
|
|
||||||
labelText.fontSize = 14;
|
|
||||||
labelText.resizeTextMaxSize = 14;
|
|
||||||
labelText.resizeTextForBestFit = true;
|
|
||||||
var labelLayout = labelObj.AddComponent<LayoutElement>();
|
|
||||||
labelLayout.minHeight = 25;
|
|
||||||
labelLayout.flexibleHeight = 0;
|
|
||||||
labelLayout.minWidth = 25;
|
|
||||||
labelLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
// actual value label
|
// actual value label
|
||||||
var valueLabelObj = UIFactory.CreateLabel(rowObject, TextAnchor.MiddleLeft);
|
var valueLabel = UIFactory.CreateLabel(rowObject, "ValueLabel", "", TextAnchor.MiddleLeft);
|
||||||
var valueLabel = valueLabelObj.GetComponent<Text>();
|
|
||||||
editor.values[(int)vectorValue] = valueLabel;
|
editor.values[(int)vectorValue] = valueLabel;
|
||||||
var valueLabelLayout = valueLabelObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(valueLabel.gameObject, minWidth: 85, flexibleWidth: 0, minHeight: 25);
|
||||||
valueLabelLayout.minWidth = 85;
|
|
||||||
valueLabelLayout.flexibleWidth = 0;
|
|
||||||
valueLabelLayout.minHeight = 25;
|
|
||||||
|
|
||||||
// input field
|
// input field
|
||||||
|
|
||||||
var inputHolder = UIFactory.CreateVerticalGroup(rowObject, new Color(1, 1, 1, 0));
|
var inputHolder = UIFactory.CreateVerticalGroup(rowObject, "InputFieldGroup", false, false, true, true, 0, default, new Color(1, 1, 1, 0));
|
||||||
var inputHolderGroup = inputHolder.GetComponent<VerticalLayoutGroup>();
|
|
||||||
inputHolderGroup.childForceExpandHeight = false;
|
|
||||||
inputHolderGroup.childControlHeight = true;
|
|
||||||
inputHolderGroup.childForceExpandWidth = false;
|
|
||||||
inputHolderGroup.childControlWidth = true;
|
|
||||||
|
|
||||||
var inputObj = UIFactory.CreateInputField(inputHolder);
|
var inputObj = UIFactory.CreateInputField(inputHolder, "InputField", "...");
|
||||||
var input = inputObj.GetComponent<InputField>();
|
var input = inputObj.GetComponent<InputField>();
|
||||||
input.characterValidation = InputField.CharacterValidation.Decimal;
|
//input.characterValidation = InputField.CharacterValidation.Decimal;
|
||||||
|
|
||||||
var inputLayout = inputObj.AddComponent<LayoutElement>();
|
UIFactory.SetLayoutElement(inputObj, minHeight: 25, flexibleHeight: 0, minWidth: 90, flexibleWidth: 50);
|
||||||
inputLayout.minHeight = 25;
|
|
||||||
inputLayout.flexibleHeight = 0;
|
|
||||||
inputLayout.minWidth = 90;
|
|
||||||
inputLayout.flexibleWidth = 50;
|
|
||||||
|
|
||||||
editor.inputs[(int)vectorValue] = input;
|
editor.inputs[(int)vectorValue] = input;
|
||||||
|
|
||||||
// apply button
|
// apply button
|
||||||
|
|
||||||
var applyBtnObj = UIFactory.CreateButton(rowObject);
|
var applyBtn = UIFactory.CreateButton(rowObject, "ApplyButton", "Apply", () => { OnVectorControlInputApplied(type, vectorValue); });
|
||||||
var applyBtn = applyBtnObj.GetComponent<Button>();
|
UIFactory.SetLayoutElement(applyBtn.gameObject, minWidth: 60, minHeight: 25);
|
||||||
var applyText = applyBtnObj.GetComponentInChildren<Text>();
|
|
||||||
applyText.text = "Apply";
|
|
||||||
applyText.fontSize = 14;
|
|
||||||
var applyLayout = applyBtnObj.AddComponent<LayoutElement>();
|
|
||||||
applyLayout.minWidth = 60;
|
|
||||||
applyLayout.minHeight = 25;
|
|
||||||
|
|
||||||
applyBtn.onClick.AddListener(() => { OnVectorControlInputApplied(type, vectorValue); });
|
|
||||||
|
|
||||||
// Slider
|
// Slider
|
||||||
|
|
||||||
var sliderObj = UIFactory.CreateSlider(rowObject);
|
var sliderObj = UIFactory.CreateSlider(rowObject, "VectorSlider", out Slider slider);
|
||||||
|
UIFactory.SetLayoutElement(sliderObj, minHeight: 20, flexibleHeight: 0, minWidth: 200, flexibleWidth: 9000);
|
||||||
sliderObj.transform.Find("Fill Area").gameObject.SetActive(false);
|
sliderObj.transform.Find("Fill Area").gameObject.SetActive(false);
|
||||||
var sliderLayout = sliderObj.AddComponent<LayoutElement>();
|
slider.colors = RuntimeProvider.Instance.SetColorBlock(slider.colors, new Color(0.65f, 0.65f, 0.65f));
|
||||||
sliderLayout.minHeight = 20;
|
|
||||||
sliderLayout.flexibleHeight = 0;
|
|
||||||
sliderLayout.minWidth = 200;
|
|
||||||
sliderLayout.flexibleWidth = 9000;
|
|
||||||
var slider = sliderObj.GetComponent<Slider>();
|
|
||||||
var sliderColors = slider.colors;
|
|
||||||
sliderColors.normalColor = new Color(0.65f, 0.65f, 0.65f);
|
|
||||||
slider.colors = sliderColors;
|
|
||||||
slider.minValue = -2;
|
slider.minValue = -2;
|
||||||
slider.maxValue = 2;
|
slider.maxValue = 2;
|
||||||
slider.value = 0;
|
slider.value = 0;
|
||||||
@ -553,24 +420,10 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
|
|
||||||
internal void ConstructBottomButtons(GameObject contentObj)
|
internal void ConstructBottomButtons(GameObject contentObj)
|
||||||
{
|
{
|
||||||
var bottomRow = UIFactory.CreateHorizontalGroup(contentObj, new Color(1, 1, 1, 0));
|
var bottomRow = UIFactory.CreateHorizontalGroup(contentObj, "BottomButtons", true, true, false, false, 4, default, new Color(1, 1, 1, 0));
|
||||||
var bottomGroup = bottomRow.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
bottomGroup.childForceExpandWidth = true;
|
|
||||||
bottomGroup.childControlWidth = true;
|
|
||||||
bottomGroup.spacing = 4;
|
|
||||||
var bottomLayout = bottomRow.AddComponent<LayoutElement>();
|
|
||||||
bottomLayout.minHeight = 25;
|
|
||||||
|
|
||||||
var instantiateBtnObj = UIFactory.CreateButton(bottomRow, new Color(0.2f, 0.2f, 0.2f));
|
var instantiateBtn = UIFactory.CreateButton(bottomRow, "InstantiateBtn", "Instantiate", InstantiateBtn, new Color(0.2f, 0.2f, 0.2f));
|
||||||
var instantiateBtn = instantiateBtnObj.GetComponent<Button>();
|
UIFactory.SetLayoutElement(instantiateBtn.gameObject, minWidth: 150);
|
||||||
|
|
||||||
instantiateBtn.onClick.AddListener(InstantiateBtn);
|
|
||||||
|
|
||||||
var instantiateText = instantiateBtnObj.GetComponentInChildren<Text>();
|
|
||||||
instantiateText.text = "Instantiate";
|
|
||||||
instantiateText.fontSize = 14;
|
|
||||||
var instantiateLayout = instantiateBtnObj.AddComponent<LayoutElement>();
|
|
||||||
instantiateLayout.minWidth = 150;
|
|
||||||
|
|
||||||
void InstantiateBtn()
|
void InstantiateBtn()
|
||||||
{
|
{
|
||||||
@ -582,16 +435,9 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
InspectorManager.Instance.Inspect(clone);
|
InspectorManager.Instance.Inspect(clone);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dontDestroyBtnObj = UIFactory.CreateButton(bottomRow, new Color(0.2f, 0.2f, 0.2f));
|
var dontDestroyBtn = UIFactory.CreateButton(bottomRow, "DontDestroyButton", "Set DontDestroyOnLoad", DontDestroyOnLoadBtn,
|
||||||
var dontDestroyBtn = dontDestroyBtnObj.GetComponent<Button>();
|
new Color(0.2f, 0.2f, 0.2f));
|
||||||
|
UIFactory.SetLayoutElement(dontDestroyBtn.gameObject, flexibleWidth: 5000);
|
||||||
dontDestroyBtn.onClick.AddListener(DontDestroyOnLoadBtn);
|
|
||||||
|
|
||||||
var dontDestroyText = dontDestroyBtnObj.GetComponentInChildren<Text>();
|
|
||||||
dontDestroyText.text = "Set DontDestroyOnLoad";
|
|
||||||
dontDestroyText.fontSize = 14;
|
|
||||||
var dontDestroyLayout = dontDestroyBtnObj.AddComponent<LayoutElement>();
|
|
||||||
dontDestroyLayout.flexibleWidth = 5000;
|
|
||||||
|
|
||||||
void DontDestroyOnLoadBtn()
|
void DontDestroyOnLoadBtn()
|
||||||
{
|
{
|
||||||
@ -602,17 +448,10 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
GameObject.DontDestroyOnLoad(go);
|
GameObject.DontDestroyOnLoad(go);
|
||||||
}
|
}
|
||||||
|
|
||||||
var destroyBtnObj = UIFactory.CreateButton(bottomRow, new Color(0.2f, 0.2f, 0.2f));
|
var destroyBtn = UIFactory.CreateButton(bottomRow, "DestroyButton", "Destroy", DestroyBtn, new Color(0.2f, 0.2f, 0.2f));
|
||||||
var destroyBtn = destroyBtnObj.GetComponent<Button>();
|
UIFactory.SetLayoutElement(destroyBtn.gameObject, minWidth: 150);
|
||||||
|
var destroyText = destroyBtn.GetComponentInChildren<Text>();
|
||||||
destroyBtn.onClick.AddListener(DestroyBtn);
|
|
||||||
|
|
||||||
var destroyText = destroyBtnObj.GetComponentInChildren<Text>();
|
|
||||||
destroyText.text = "Destroy";
|
|
||||||
destroyText.fontSize = 14;
|
|
||||||
destroyText.color = Color.red;
|
destroyText.color = Color.red;
|
||||||
var destroyLayout = destroyBtnObj.AddComponent<LayoutElement>();
|
|
||||||
destroyLayout.minWidth = 150;
|
|
||||||
|
|
||||||
void DestroyBtn()
|
void DestroyBtn()
|
||||||
{
|
{
|
||||||
@ -624,6 +463,6 @@ namespace UnityExplorer.UI.Main.Home.Inspectors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
350
src/UI/Main/Home/Inspectors/GameObjects/GameObjectInspector.cs
Normal file
350
src/UI/Main/Home/Inspectors/GameObjects/GameObjectInspector.cs
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
|
using UnityExplorer.Core.Unity;
|
||||||
|
|
||||||
|
namespace UnityExplorer.UI.Main.Home.Inspectors.GameObjects
|
||||||
|
{
|
||||||
|
public class GameObjectInspector : InspectorBase
|
||||||
|
{
|
||||||
|
public override string TabLabel => $" <color=cyan>[G]</color> {TargetGO?.name}";
|
||||||
|
|
||||||
|
public static GameObjectInspector ActiveInstance { get; private set; }
|
||||||
|
|
||||||
|
public GameObject TargetGO;
|
||||||
|
|
||||||
|
// sub modules
|
||||||
|
internal static ChildList s_childList;
|
||||||
|
internal static ComponentList s_compList;
|
||||||
|
internal static GameObjectControls s_controls;
|
||||||
|
|
||||||
|
internal static bool m_UIConstructed;
|
||||||
|
|
||||||
|
public GameObjectInspector(GameObject target) : base(target)
|
||||||
|
{
|
||||||
|
ActiveInstance = this;
|
||||||
|
|
||||||
|
TargetGO = target;
|
||||||
|
|
||||||
|
if (!TargetGO)
|
||||||
|
{
|
||||||
|
ExplorerCore.LogWarning("Target GameObject is null!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// one UI is used for all gameobject inspectors. no point recreating it.
|
||||||
|
if (!m_UIConstructed)
|
||||||
|
{
|
||||||
|
m_UIConstructed = true;
|
||||||
|
|
||||||
|
s_childList = new ChildList();
|
||||||
|
s_compList = new ComponentList();
|
||||||
|
s_controls = new GameObjectControls();
|
||||||
|
|
||||||
|
ConstructUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetActive()
|
||||||
|
{
|
||||||
|
base.SetActive();
|
||||||
|
ActiveInstance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetInactive()
|
||||||
|
{
|
||||||
|
base.SetInactive();
|
||||||
|
ActiveInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ChangeInspectorTarget(GameObject newTarget)
|
||||||
|
{
|
||||||
|
if (!newTarget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.Target = this.TargetGO = newTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
if (m_pendingDestroy || !this.IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RefreshTopInfo();
|
||||||
|
|
||||||
|
s_childList.RefreshChildObjectList();
|
||||||
|
|
||||||
|
s_compList.RefreshComponentList();
|
||||||
|
|
||||||
|
s_controls.RefreshControls();
|
||||||
|
|
||||||
|
if (GameObjectControls.s_sliderChangedWanted)
|
||||||
|
GameObjectControls.UpdateSliderControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject s_content;
|
||||||
|
public override GameObject Content
|
||||||
|
{
|
||||||
|
get => s_content;
|
||||||
|
set => s_content = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string m_lastName;
|
||||||
|
public static InputField m_nameInput;
|
||||||
|
|
||||||
|
private static string m_lastPath;
|
||||||
|
public static InputField m_pathInput;
|
||||||
|
private static RectTransform m_pathInputRect;
|
||||||
|
private static GameObject m_pathGroupObj;
|
||||||
|
private static Text m_hiddenPathText;
|
||||||
|
private static RectTransform m_hiddenPathRect;
|
||||||
|
|
||||||
|
private static Toggle m_enabledToggle;
|
||||||
|
private static Text m_enabledText;
|
||||||
|
private static bool? m_lastEnabledState;
|
||||||
|
|
||||||
|
private static Dropdown m_layerDropdown;
|
||||||
|
private static int m_lastLayer = -1;
|
||||||
|
|
||||||
|
private static Text m_sceneText;
|
||||||
|
private static string m_lastScene;
|
||||||
|
|
||||||
|
internal void RefreshTopInfo()
|
||||||
|
{
|
||||||
|
var target = TargetGO;
|
||||||
|
string name = target.name;
|
||||||
|
|
||||||
|
if (m_lastName != name)
|
||||||
|
{
|
||||||
|
m_lastName = name;
|
||||||
|
m_nameInput.text = m_lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.transform.parent)
|
||||||
|
{
|
||||||
|
if (!m_pathGroupObj.activeSelf)
|
||||||
|
m_pathGroupObj.SetActive(true);
|
||||||
|
|
||||||
|
var path = target.transform.GetTransformPath(true);
|
||||||
|
if (m_lastPath != path)
|
||||||
|
{
|
||||||
|
m_lastPath = path;
|
||||||
|
|
||||||
|
m_pathInput.text = path;
|
||||||
|
m_hiddenPathText.text = path;
|
||||||
|
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(m_pathInputRect);
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(m_hiddenPathRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_pathGroupObj.activeSelf)
|
||||||
|
m_pathGroupObj.SetActive(false);
|
||||||
|
|
||||||
|
if (m_lastEnabledState != target.activeSelf)
|
||||||
|
{
|
||||||
|
m_lastEnabledState = target.activeSelf;
|
||||||
|
|
||||||
|
m_enabledToggle.isOn = target.activeSelf;
|
||||||
|
m_enabledText.text = target.activeSelf ? "Enabled" : "Disabled";
|
||||||
|
m_enabledText.color = target.activeSelf ? Color.green : Color.red;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_lastLayer != target.layer)
|
||||||
|
{
|
||||||
|
m_lastLayer = target.layer;
|
||||||
|
m_layerDropdown.value = target.layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(m_lastScene) || m_lastScene != target.scene.name)
|
||||||
|
{
|
||||||
|
m_lastScene = target.scene.name;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(target.scene.name))
|
||||||
|
m_sceneText.text = m_lastScene;
|
||||||
|
else
|
||||||
|
m_sceneText.text = "None (Asset/Resource)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UI Callbacks
|
||||||
|
|
||||||
|
private static void OnApplyNameClicked()
|
||||||
|
{
|
||||||
|
if (ActiveInstance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ActiveInstance.TargetGO.name = m_nameInput.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnEnableToggled(bool enabled)
|
||||||
|
{
|
||||||
|
if (ActiveInstance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ActiveInstance.TargetGO.SetActive(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnLayerSelected(int layer)
|
||||||
|
{
|
||||||
|
if (ActiveInstance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ActiveInstance.TargetGO.layer = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void OnBackButtonClicked()
|
||||||
|
{
|
||||||
|
if (ActiveInstance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ActiveInstance.ChangeInspectorTarget(ActiveInstance.TargetGO.transform.parent.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
|
internal void ConstructUI()
|
||||||
|
{
|
||||||
|
var parent = InspectorManager.m_inspectorContent;
|
||||||
|
|
||||||
|
s_content = UIFactory.CreateScrollView(parent, "GameObjectInspector_Content", out GameObject scrollContent, out _,
|
||||||
|
new Color(0.1f, 0.1f, 0.1f));
|
||||||
|
|
||||||
|
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent.transform.parent.gameObject, true, true, true, true);
|
||||||
|
|
||||||
|
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, true, true, true, 5);
|
||||||
|
var contentFitter = scrollContent.GetComponent<ContentSizeFitter>();
|
||||||
|
contentFitter.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||||
|
|
||||||
|
ConstructTopArea(scrollContent);
|
||||||
|
|
||||||
|
s_controls.ConstructControls(scrollContent);
|
||||||
|
|
||||||
|
var midGroupObj = ConstructMidGroup(scrollContent);
|
||||||
|
|
||||||
|
s_childList.ConstructChildList(midGroupObj);
|
||||||
|
s_compList.ConstructCompList(midGroupObj);
|
||||||
|
|
||||||
|
LayoutRebuilder.ForceRebuildLayoutImmediate(s_content.GetComponent<RectTransform>());
|
||||||
|
Canvas.ForceUpdateCanvases();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConstructTopArea(GameObject scrollContent)
|
||||||
|
{
|
||||||
|
// path row
|
||||||
|
|
||||||
|
m_pathGroupObj = UIFactory.CreateHorizontalGroup(scrollContent, "TopArea", false, false, true, true, 5, default, new Color(0.1f, 0.1f, 0.1f));
|
||||||
|
|
||||||
|
var pathRect = m_pathGroupObj.GetComponent<RectTransform>();
|
||||||
|
pathRect.sizeDelta = new Vector2(pathRect.sizeDelta.x, 20);
|
||||||
|
UIFactory.SetLayoutElement(m_pathGroupObj, minHeight: 20, flexibleHeight: 75);
|
||||||
|
|
||||||
|
// Back button
|
||||||
|
|
||||||
|
var backButton = UIFactory.CreateButton(m_pathGroupObj, "BackButton", "◄", OnBackButtonClicked, new Color(0.15f, 0.15f, 0.15f));
|
||||||
|
UIFactory.SetLayoutElement(backButton.gameObject, minWidth: 55, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
|
||||||
|
|
||||||
|
m_hiddenPathText = UIFactory.CreateLabel(m_pathGroupObj, "HiddenPathText", "", TextAnchor.MiddleLeft);
|
||||||
|
m_hiddenPathText.color = Color.clear;
|
||||||
|
m_hiddenPathText.fontSize = 14;
|
||||||
|
m_hiddenPathText.raycastTarget = false;
|
||||||
|
|
||||||
|
var hiddenFitter = m_hiddenPathText.gameObject.AddComponent<ContentSizeFitter>();
|
||||||
|
hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(m_hiddenPathText.gameObject, minHeight: 25, flexibleHeight: 125, minWidth: 250, flexibleWidth: 9000);
|
||||||
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(m_hiddenPathText.gameObject, true, true, true, true);
|
||||||
|
|
||||||
|
// Path input
|
||||||
|
|
||||||
|
var pathInputObj = UIFactory.CreateInputField(m_hiddenPathText.gameObject, "PathInputField", "...");
|
||||||
|
UIFactory.SetLayoutElement(pathInputObj, minHeight: 25, flexibleHeight: 75, preferredWidth: 400, flexibleWidth: 9999);
|
||||||
|
var pathInputRect = pathInputObj.GetComponent<RectTransform>();
|
||||||
|
pathInputRect.sizeDelta = new Vector2(pathInputRect.sizeDelta.x, 25);
|
||||||
|
|
||||||
|
m_pathInput = pathInputObj.GetComponent<InputField>();
|
||||||
|
m_pathInput.text = ActiveInstance.TargetGO.transform.GetTransformPath();
|
||||||
|
m_pathInput.readOnly = true;
|
||||||
|
m_pathInput.lineType = InputField.LineType.MultiLineNewline;
|
||||||
|
m_pathInput.textComponent.color = new Color(0.75f, 0.75f, 0.75f);
|
||||||
|
|
||||||
|
var textRect = m_pathInput.textComponent.GetComponent<RectTransform>();
|
||||||
|
textRect.offsetMin = new Vector2(3, 3);
|
||||||
|
textRect.offsetMax = new Vector2(3, 3);
|
||||||
|
|
||||||
|
m_pathInputRect = m_pathInput.GetComponent<RectTransform>();
|
||||||
|
m_hiddenPathRect = m_hiddenPathText.GetComponent<RectTransform>();
|
||||||
|
|
||||||
|
// name and enabled row
|
||||||
|
|
||||||
|
var nameRowObj = UIFactory.CreateHorizontalGroup(scrollContent, "NameGroup", false, false, true, true, 5, default, new Color(0.1f, 0.1f, 0.1f));
|
||||||
|
UIFactory.SetLayoutElement(nameRowObj, minHeight: 25, flexibleHeight: 0);
|
||||||
|
var nameRect = nameRowObj.GetComponent<RectTransform>();
|
||||||
|
nameRect.sizeDelta = new Vector2(nameRect.sizeDelta.x, 25);
|
||||||
|
|
||||||
|
var nameLabel = UIFactory.CreateLabel(nameRowObj, "NameLabel", "Name:", TextAnchor.MiddleCenter, Color.grey, true, 14);
|
||||||
|
UIFactory.SetLayoutElement(nameLabel.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 55, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var nameInputObj = UIFactory.CreateInputField(nameRowObj, "NameInput", "...");
|
||||||
|
var nameInputRect = nameInputObj.GetComponent<RectTransform>();
|
||||||
|
nameInputRect.sizeDelta = new Vector2(nameInputRect.sizeDelta.x, 25);
|
||||||
|
m_nameInput = nameInputObj.GetComponent<InputField>();
|
||||||
|
m_nameInput.text = ActiveInstance.TargetGO.name;
|
||||||
|
|
||||||
|
var applyNameBtn = UIFactory.CreateButton(nameRowObj, "ApplyNameButton", "Apply", OnApplyNameClicked);
|
||||||
|
UIFactory.SetLayoutElement(applyNameBtn.gameObject, minWidth: 65, minHeight: 25, flexibleHeight: 0);
|
||||||
|
var applyNameRect = applyNameBtn.GetComponent<RectTransform>();
|
||||||
|
applyNameRect.sizeDelta = new Vector2(applyNameRect.sizeDelta.x, 25);
|
||||||
|
|
||||||
|
var activeLabel = UIFactory.CreateLabel(nameRowObj, "ActiveLabel", "Active:", TextAnchor.MiddleCenter, Color.grey, true, 14);
|
||||||
|
UIFactory.SetLayoutElement(activeLabel.gameObject, minWidth: 55, minHeight: 25);
|
||||||
|
|
||||||
|
var enabledToggleObj = UIFactory.CreateToggle(nameRowObj, "EnabledToggle", out m_enabledToggle, out m_enabledText);
|
||||||
|
UIFactory.SetLayoutElement(enabledToggleObj, minHeight: 25, minWidth: 100, flexibleWidth: 0);
|
||||||
|
m_enabledText.text = "Enabled";
|
||||||
|
m_enabledText.color = Color.green;
|
||||||
|
m_enabledToggle.onValueChanged.AddListener(OnEnableToggled);
|
||||||
|
|
||||||
|
// layer and scene row
|
||||||
|
|
||||||
|
var sceneLayerRow = UIFactory.CreateHorizontalGroup(scrollContent, "SceneLayerRow", false, true, true, true, 5, default, new Color(0.1f, 0.1f, 0.1f));
|
||||||
|
|
||||||
|
// layer
|
||||||
|
|
||||||
|
var layerLabel = UIFactory.CreateLabel(sceneLayerRow, "LayerLabel", "Layer:", TextAnchor.MiddleCenter, Color.grey, true, 14);
|
||||||
|
UIFactory.SetLayoutElement(layerLabel.gameObject, minWidth: 55, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var layerDropdownObj = UIFactory.CreateDropdown(sceneLayerRow, out m_layerDropdown, "", 14, OnLayerSelected);
|
||||||
|
m_layerDropdown.options.Clear();
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
var layer = RuntimeProvider.Instance.LayerToName(i);
|
||||||
|
m_layerDropdown.options.Add(new Dropdown.OptionData { text = $"{i}: {layer}" });
|
||||||
|
}
|
||||||
|
UIFactory.SetLayoutElement(layerDropdownObj, minWidth: 120, flexibleWidth: 2000, minHeight: 25);
|
||||||
|
|
||||||
|
// scene
|
||||||
|
|
||||||
|
var sceneLabel = UIFactory.CreateLabel(sceneLayerRow, "SceneLabel", "Scene:", TextAnchor.MiddleCenter, Color.grey, true, 14);
|
||||||
|
UIFactory.SetLayoutElement(sceneLabel.gameObject, minWidth: 55, flexibleWidth: 0);
|
||||||
|
|
||||||
|
m_sceneText = UIFactory.CreateLabel(sceneLayerRow, "SceneText", "", TextAnchor.MiddleLeft);
|
||||||
|
UIFactory.SetLayoutElement(m_sceneText.gameObject, minWidth: 120, flexibleWidth: 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameObject ConstructMidGroup(GameObject parent)
|
||||||
|
{
|
||||||
|
var midGroupObj = UIFactory.CreateHorizontalGroup(parent, "MidGroup", true, true, true, true, 5, default, new Color(1, 1, 1, 0));
|
||||||
|
UIFactory.SetLayoutElement(midGroupObj, minHeight: 300, flexibleHeight: 3000);
|
||||||
|
return midGroupObj;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -1,378 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityExplorer.Core.Unity;
|
|
||||||
using UnityExplorer.Core.Inspectors;
|
|
||||||
using UnityExplorer.Core.Runtime;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main.Home.Inspectors
|
|
||||||
{
|
|
||||||
public class GameObjectInspectorUI : InspectorBaseUI
|
|
||||||
{
|
|
||||||
private static GameObject s_content;
|
|
||||||
public override GameObject Content
|
|
||||||
{
|
|
||||||
get => s_content;
|
|
||||||
set => s_content = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string m_lastName;
|
|
||||||
public static InputField m_nameInput;
|
|
||||||
|
|
||||||
private static string m_lastPath;
|
|
||||||
public static InputField m_pathInput;
|
|
||||||
private static RectTransform m_pathInputRect;
|
|
||||||
private static GameObject m_pathGroupObj;
|
|
||||||
private static Text m_hiddenPathText;
|
|
||||||
private static RectTransform m_hiddenPathRect;
|
|
||||||
|
|
||||||
private static Toggle m_enabledToggle;
|
|
||||||
private static Text m_enabledText;
|
|
||||||
private static bool? m_lastEnabledState;
|
|
||||||
|
|
||||||
private static Dropdown m_layerDropdown;
|
|
||||||
private static int m_lastLayer = -1;
|
|
||||||
|
|
||||||
private static Text m_sceneText;
|
|
||||||
private static string m_lastScene;
|
|
||||||
|
|
||||||
internal void RefreshTopInfo()
|
|
||||||
{
|
|
||||||
var target = GameObjectInspector.ActiveInstance.TargetGO;
|
|
||||||
string name = target.name;
|
|
||||||
|
|
||||||
if (m_lastName != name)
|
|
||||||
{
|
|
||||||
m_lastName = name;
|
|
||||||
m_nameInput.text = m_lastName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.transform.parent)
|
|
||||||
{
|
|
||||||
if (!m_pathGroupObj.activeSelf)
|
|
||||||
m_pathGroupObj.SetActive(true);
|
|
||||||
|
|
||||||
var path = target.transform.GetTransformPath(true);
|
|
||||||
if (m_lastPath != path)
|
|
||||||
{
|
|
||||||
m_lastPath = path;
|
|
||||||
|
|
||||||
m_pathInput.text = path;
|
|
||||||
m_hiddenPathText.text = path;
|
|
||||||
|
|
||||||
LayoutRebuilder.ForceRebuildLayoutImmediate(m_pathInputRect);
|
|
||||||
LayoutRebuilder.ForceRebuildLayoutImmediate(m_hiddenPathRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_pathGroupObj.activeSelf)
|
|
||||||
m_pathGroupObj.SetActive(false);
|
|
||||||
|
|
||||||
if (m_lastEnabledState != target.activeSelf)
|
|
||||||
{
|
|
||||||
m_lastEnabledState = target.activeSelf;
|
|
||||||
|
|
||||||
m_enabledToggle.isOn = target.activeSelf;
|
|
||||||
m_enabledText.text = target.activeSelf ? "Enabled" : "Disabled";
|
|
||||||
m_enabledText.color = target.activeSelf ? Color.green : Color.red;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_lastLayer != target.layer)
|
|
||||||
{
|
|
||||||
m_lastLayer = target.layer;
|
|
||||||
m_layerDropdown.value = target.layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(m_lastScene) || m_lastScene != target.scene.name)
|
|
||||||
{
|
|
||||||
m_lastScene = target.scene.name;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(target.scene.name))
|
|
||||||
m_sceneText.text = m_lastScene;
|
|
||||||
else
|
|
||||||
m_sceneText.text = "None (Asset/Resource)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI Callbacks
|
|
||||||
|
|
||||||
private static void OnApplyNameClicked()
|
|
||||||
{
|
|
||||||
if (GameObjectInspector.ActiveInstance == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GameObjectInspector.ActiveInstance.TargetGO.name = m_nameInput.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnEnableToggled(bool enabled)
|
|
||||||
{
|
|
||||||
if (GameObjectInspector.ActiveInstance == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GameObjectInspector.ActiveInstance.TargetGO.SetActive(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnLayerSelected(int layer)
|
|
||||||
{
|
|
||||||
if (GameObjectInspector.ActiveInstance == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GameObjectInspector.ActiveInstance.TargetGO.layer = layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void OnBackButtonClicked()
|
|
||||||
{
|
|
||||||
if (GameObjectInspector.ActiveInstance == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GameObjectInspector.ActiveInstance.ChangeInspectorTarget(
|
|
||||||
GameObjectInspector.ActiveInstance.TargetGO.transform.parent.gameObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region UI CONSTRUCTION
|
|
||||||
|
|
||||||
internal void ConstructUI()
|
|
||||||
{
|
|
||||||
var parent = InspectorManager.UI.m_inspectorContent;
|
|
||||||
|
|
||||||
s_content = UIFactory.CreateScrollView(parent, out GameObject scrollContent, out _, new Color(0.1f, 0.1f, 0.1f));
|
|
||||||
|
|
||||||
var parentLayout = scrollContent.transform.parent.gameObject.AddComponent<VerticalLayoutGroup>();
|
|
||||||
parentLayout.childForceExpandWidth = true;
|
|
||||||
parentLayout.childControlWidth = true;
|
|
||||||
parentLayout.childForceExpandHeight = true;
|
|
||||||
parentLayout.childControlHeight = true;
|
|
||||||
|
|
||||||
var scrollGroup = scrollContent.GetComponent<VerticalLayoutGroup>();
|
|
||||||
scrollGroup.childForceExpandHeight = true;
|
|
||||||
scrollGroup.childControlHeight = true;
|
|
||||||
scrollGroup.childForceExpandWidth = true;
|
|
||||||
scrollGroup.childControlWidth = true;
|
|
||||||
scrollGroup.spacing = 5;
|
|
||||||
var contentFitter = scrollContent.GetComponent<ContentSizeFitter>();
|
|
||||||
contentFitter.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
|
|
||||||
|
|
||||||
ConstructTopArea(scrollContent);
|
|
||||||
|
|
||||||
GameObjectInspector.s_controls.ConstructControls(scrollContent);
|
|
||||||
|
|
||||||
var midGroupObj = ConstructMidGroup(scrollContent);
|
|
||||||
|
|
||||||
GameObjectInspector.s_childList.ConstructChildList(midGroupObj);
|
|
||||||
GameObjectInspector.s_compList.ConstructCompList(midGroupObj);
|
|
||||||
|
|
||||||
LayoutRebuilder.ForceRebuildLayoutImmediate(s_content.GetComponent<RectTransform>());
|
|
||||||
Canvas.ForceUpdateCanvases();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConstructTopArea(GameObject scrollContent)
|
|
||||||
{
|
|
||||||
// path row
|
|
||||||
|
|
||||||
m_pathGroupObj = UIFactory.CreateHorizontalGroup(scrollContent, new Color(0.1f, 0.1f, 0.1f));
|
|
||||||
var pathGroup = m_pathGroupObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
pathGroup.childForceExpandHeight = false;
|
|
||||||
pathGroup.childForceExpandWidth = false;
|
|
||||||
pathGroup.childControlHeight = false;
|
|
||||||
pathGroup.childControlWidth = true;
|
|
||||||
pathGroup.spacing = 5;
|
|
||||||
var pathRect = m_pathGroupObj.GetComponent<RectTransform>();
|
|
||||||
pathRect.sizeDelta = new Vector2(pathRect.sizeDelta.x, 20);
|
|
||||||
var pathLayout = m_pathGroupObj.AddComponent<LayoutElement>();
|
|
||||||
pathLayout.minHeight = 20;
|
|
||||||
pathLayout.flexibleHeight = 75;
|
|
||||||
|
|
||||||
var backButtonObj = UIFactory.CreateButton(m_pathGroupObj);
|
|
||||||
var backButton = backButtonObj.GetComponent<Button>();
|
|
||||||
|
|
||||||
backButton.onClick.AddListener(OnBackButtonClicked);
|
|
||||||
|
|
||||||
var backColors = backButton.colors;
|
|
||||||
backColors.normalColor = new Color(0.15f, 0.15f, 0.15f);
|
|
||||||
backButton.colors = backColors;
|
|
||||||
var backText = backButtonObj.GetComponentInChildren<Text>();
|
|
||||||
backText.text = "◄";
|
|
||||||
var backLayout = backButtonObj.AddComponent<LayoutElement>();
|
|
||||||
backLayout.minWidth = 55;
|
|
||||||
backLayout.flexibleWidth = 0;
|
|
||||||
backLayout.minHeight = 25;
|
|
||||||
backLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
var pathHiddenTextObj = UIFactory.CreateLabel(m_pathGroupObj, TextAnchor.MiddleLeft);
|
|
||||||
m_hiddenPathText = pathHiddenTextObj.GetComponent<Text>();
|
|
||||||
m_hiddenPathText.color = Color.clear;
|
|
||||||
m_hiddenPathText.fontSize = 14;
|
|
||||||
//m_hiddenPathText.lineSpacing = 1.5f;
|
|
||||||
m_hiddenPathText.raycastTarget = false;
|
|
||||||
var hiddenFitter = pathHiddenTextObj.AddComponent<ContentSizeFitter>();
|
|
||||||
hiddenFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
|
||||||
var hiddenLayout = pathHiddenTextObj.AddComponent<LayoutElement>();
|
|
||||||
hiddenLayout.minHeight = 25;
|
|
||||||
hiddenLayout.flexibleHeight = 125;
|
|
||||||
hiddenLayout.minWidth = 250;
|
|
||||||
hiddenLayout.flexibleWidth = 9000;
|
|
||||||
var hiddenGroup = pathHiddenTextObj.AddComponent<HorizontalLayoutGroup>();
|
|
||||||
hiddenGroup.childForceExpandWidth = true;
|
|
||||||
hiddenGroup.childControlWidth = true;
|
|
||||||
hiddenGroup.childForceExpandHeight = true;
|
|
||||||
hiddenGroup.childControlHeight = true;
|
|
||||||
|
|
||||||
var pathInputObj = UIFactory.CreateInputField(pathHiddenTextObj);
|
|
||||||
var pathInputRect = pathInputObj.GetComponent<RectTransform>();
|
|
||||||
pathInputRect.sizeDelta = new Vector2(pathInputRect.sizeDelta.x, 25);
|
|
||||||
m_pathInput = pathInputObj.GetComponent<InputField>();
|
|
||||||
m_pathInput.text = GameObjectInspector.ActiveInstance.TargetGO.transform.GetTransformPath();
|
|
||||||
m_pathInput.readOnly = true;
|
|
||||||
m_pathInput.lineType = InputField.LineType.MultiLineNewline;
|
|
||||||
var pathInputLayout = pathInputObj.AddComponent<LayoutElement>();
|
|
||||||
pathInputLayout.minHeight = 25;
|
|
||||||
pathInputLayout.flexibleHeight = 75;
|
|
||||||
pathInputLayout.preferredWidth = 400;
|
|
||||||
pathInputLayout.flexibleWidth = 9999;
|
|
||||||
var textRect = m_pathInput.textComponent.GetComponent<RectTransform>();
|
|
||||||
textRect.offsetMin = new Vector2(3, 3);
|
|
||||||
textRect.offsetMax = new Vector2(3, 3);
|
|
||||||
m_pathInput.textComponent.color = new Color(0.75f, 0.75f, 0.75f);
|
|
||||||
//m_pathInput.textComponent.lineSpacing = 1.5f;
|
|
||||||
|
|
||||||
m_pathInputRect = m_pathInput.GetComponent<RectTransform>();
|
|
||||||
m_hiddenPathRect = m_hiddenPathText.GetComponent<RectTransform>();
|
|
||||||
|
|
||||||
// name row
|
|
||||||
|
|
||||||
var nameRowObj = UIFactory.CreateHorizontalGroup(scrollContent, new Color(0.1f, 0.1f, 0.1f));
|
|
||||||
var nameGroup = nameRowObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
nameGroup.childForceExpandHeight = false;
|
|
||||||
nameGroup.childForceExpandWidth = false;
|
|
||||||
nameGroup.childControlHeight = true;
|
|
||||||
nameGroup.childControlWidth = true;
|
|
||||||
nameGroup.spacing = 5;
|
|
||||||
var nameRect = nameRowObj.GetComponent<RectTransform>();
|
|
||||||
nameRect.sizeDelta = new Vector2(nameRect.sizeDelta.x, 25);
|
|
||||||
var nameLayout = nameRowObj.AddComponent<LayoutElement>();
|
|
||||||
nameLayout.minHeight = 25;
|
|
||||||
nameLayout.flexibleHeight = 0;
|
|
||||||
|
|
||||||
var nameTextObj = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleCenter);
|
|
||||||
var nameTextText = nameTextObj.GetComponent<Text>();
|
|
||||||
nameTextText.text = "Name:";
|
|
||||||
nameTextText.fontSize = 14;
|
|
||||||
nameTextText.color = Color.grey;
|
|
||||||
var nameTextLayout = nameTextObj.AddComponent<LayoutElement>();
|
|
||||||
nameTextLayout.minHeight = 25;
|
|
||||||
nameTextLayout.flexibleHeight = 0;
|
|
||||||
nameTextLayout.minWidth = 55;
|
|
||||||
nameTextLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
var nameInputObj = UIFactory.CreateInputField(nameRowObj);
|
|
||||||
var nameInputRect = nameInputObj.GetComponent<RectTransform>();
|
|
||||||
nameInputRect.sizeDelta = new Vector2(nameInputRect.sizeDelta.x, 25);
|
|
||||||
m_nameInput = nameInputObj.GetComponent<InputField>();
|
|
||||||
m_nameInput.text = GameObjectInspector.ActiveInstance.TargetGO.name;
|
|
||||||
|
|
||||||
var applyNameBtnObj = UIFactory.CreateButton(nameRowObj);
|
|
||||||
var applyNameBtn = applyNameBtnObj.GetComponent<Button>();
|
|
||||||
|
|
||||||
applyNameBtn.onClick.AddListener(OnApplyNameClicked);
|
|
||||||
|
|
||||||
var applyNameText = applyNameBtnObj.GetComponentInChildren<Text>();
|
|
||||||
applyNameText.text = "Apply";
|
|
||||||
applyNameText.fontSize = 14;
|
|
||||||
var applyNameLayout = applyNameBtnObj.AddComponent<LayoutElement>();
|
|
||||||
applyNameLayout.minWidth = 65;
|
|
||||||
applyNameLayout.minHeight = 25;
|
|
||||||
applyNameLayout.flexibleHeight = 0;
|
|
||||||
var applyNameRect = applyNameBtnObj.GetComponent<RectTransform>();
|
|
||||||
applyNameRect.sizeDelta = new Vector2(applyNameRect.sizeDelta.x, 25);
|
|
||||||
|
|
||||||
var activeLabel = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleCenter);
|
|
||||||
var activeLabelLayout = activeLabel.AddComponent<LayoutElement>();
|
|
||||||
activeLabelLayout.minWidth = 55;
|
|
||||||
activeLabelLayout.minHeight = 25;
|
|
||||||
var activeText = activeLabel.GetComponent<Text>();
|
|
||||||
activeText.text = "Active:";
|
|
||||||
activeText.color = Color.grey;
|
|
||||||
activeText.fontSize = 14;
|
|
||||||
|
|
||||||
var enabledToggleObj = UIFactory.CreateToggle(nameRowObj, out m_enabledToggle, out m_enabledText);
|
|
||||||
var toggleLayout = enabledToggleObj.AddComponent<LayoutElement>();
|
|
||||||
toggleLayout.minHeight = 25;
|
|
||||||
toggleLayout.minWidth = 100;
|
|
||||||
toggleLayout.flexibleWidth = 0;
|
|
||||||
m_enabledText.text = "Enabled";
|
|
||||||
m_enabledText.color = Color.green;
|
|
||||||
|
|
||||||
m_enabledToggle.onValueChanged.AddListener(OnEnableToggled);
|
|
||||||
|
|
||||||
// layer and scene row
|
|
||||||
|
|
||||||
var sceneLayerRow = UIFactory.CreateHorizontalGroup(scrollContent, new Color(0.1f, 0.1f, 0.1f));
|
|
||||||
var sceneLayerGroup = sceneLayerRow.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
sceneLayerGroup.childForceExpandWidth = false;
|
|
||||||
sceneLayerGroup.childControlWidth = true;
|
|
||||||
sceneLayerGroup.spacing = 5;
|
|
||||||
|
|
||||||
var layerLabel = UIFactory.CreateLabel(sceneLayerRow, TextAnchor.MiddleCenter);
|
|
||||||
var layerText = layerLabel.GetComponent<Text>();
|
|
||||||
layerText.text = "Layer:";
|
|
||||||
layerText.fontSize = 14;
|
|
||||||
layerText.color = Color.grey;
|
|
||||||
var layerTextLayout = layerLabel.AddComponent<LayoutElement>();
|
|
||||||
layerTextLayout.minWidth = 55;
|
|
||||||
layerTextLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
var layerDropdownObj = UIFactory.CreateDropdown(sceneLayerRow, out m_layerDropdown);
|
|
||||||
m_layerDropdown.options.Clear();
|
|
||||||
for (int i = 0; i < 32; i++)
|
|
||||||
{
|
|
||||||
var layer = RuntimeProvider.Instance.LayerToName(i);
|
|
||||||
m_layerDropdown.options.Add(new Dropdown.OptionData { text = $"{i}: {layer}" });
|
|
||||||
}
|
|
||||||
//var itemText = layerDropdownObj.transform.Find("Label").GetComponent<Text>();
|
|
||||||
//itemText.resizeTextForBestFit = true;
|
|
||||||
var layerDropdownLayout = layerDropdownObj.AddComponent<LayoutElement>();
|
|
||||||
layerDropdownLayout.minWidth = 120;
|
|
||||||
layerDropdownLayout.flexibleWidth = 2000;
|
|
||||||
layerDropdownLayout.minHeight = 25;
|
|
||||||
|
|
||||||
m_layerDropdown.onValueChanged.AddListener(OnLayerSelected);
|
|
||||||
|
|
||||||
var scenelabelObj = UIFactory.CreateLabel(sceneLayerRow, TextAnchor.MiddleCenter);
|
|
||||||
var sceneLabel = scenelabelObj.GetComponent<Text>();
|
|
||||||
sceneLabel.text = "Scene:";
|
|
||||||
sceneLabel.color = Color.grey;
|
|
||||||
sceneLabel.fontSize = 14;
|
|
||||||
var sceneLabelLayout = scenelabelObj.AddComponent<LayoutElement>();
|
|
||||||
sceneLabelLayout.minWidth = 55;
|
|
||||||
sceneLabelLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
var objectSceneText = UIFactory.CreateLabel(sceneLayerRow, TextAnchor.MiddleLeft);
|
|
||||||
m_sceneText = objectSceneText.GetComponent<Text>();
|
|
||||||
m_sceneText.fontSize = 14;
|
|
||||||
m_sceneText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
|
||||||
var sceneTextLayout = objectSceneText.AddComponent<LayoutElement>();
|
|
||||||
sceneTextLayout.minWidth = 120;
|
|
||||||
sceneTextLayout.flexibleWidth = 2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
private GameObject ConstructMidGroup(GameObject parent)
|
|
||||||
{
|
|
||||||
var midGroupObj = UIFactory.CreateHorizontalGroup(parent, new Color(1, 1, 1, 0));
|
|
||||||
var midGroup = midGroupObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
midGroup.spacing = 5;
|
|
||||||
midGroup.childForceExpandWidth = true;
|
|
||||||
midGroup.childControlWidth = true;
|
|
||||||
midGroup.childForceExpandHeight = true;
|
|
||||||
midGroup.childControlHeight = true;
|
|
||||||
|
|
||||||
var midLayout = midGroupObj.AddComponent<LayoutElement>();
|
|
||||||
midLayout.minHeight = 300;
|
|
||||||
midLayout.flexibleHeight = 5000;
|
|
||||||
|
|
||||||
return midGroupObj;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,21 +2,16 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityExplorer.Core.Unity;
|
using UnityExplorer.Core.Unity;
|
||||||
using UnityExplorer.UI;
|
|
||||||
using UnityExplorer.UI.Main.Home.Inspectors;
|
|
||||||
|
|
||||||
namespace UnityExplorer.Core.Inspectors
|
namespace UnityExplorer.UI.Main.Home.Inspectors
|
||||||
{
|
{
|
||||||
public abstract class InspectorBase
|
public abstract class InspectorBase
|
||||||
{
|
{
|
||||||
public object Target;
|
public object Target;
|
||||||
|
public bool IsActive { get; private set; }
|
||||||
public InspectorBaseUI BaseUI;
|
|
||||||
|
|
||||||
public abstract string TabLabel { get; }
|
public abstract string TabLabel { get; }
|
||||||
|
|
||||||
public bool IsActive { get; private set; }
|
|
||||||
|
|
||||||
internal bool m_pendingDestroy;
|
internal bool m_pendingDestroy;
|
||||||
|
|
||||||
public InspectorBase(object target)
|
public InspectorBase(object target)
|
||||||
@ -29,23 +24,19 @@ namespace UnityExplorer.Core.Inspectors
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateUIModule();
|
AddInspectorTab(this);
|
||||||
|
|
||||||
BaseUI.AddInspectorTab(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void CreateUIModule();
|
|
||||||
|
|
||||||
public virtual void SetActive()
|
public virtual void SetActive()
|
||||||
{
|
{
|
||||||
this.IsActive = true;
|
this.IsActive = true;
|
||||||
BaseUI.Content?.SetActive(true);
|
Content?.SetActive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SetInactive()
|
public virtual void SetInactive()
|
||||||
{
|
{
|
||||||
this.IsActive = false;
|
this.IsActive = false;
|
||||||
BaseUI.Content?.SetActive(false);
|
Content?.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Update()
|
public virtual void Update()
|
||||||
@ -56,19 +47,17 @@ namespace UnityExplorer.Core.Inspectors
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseUI.tabText.text = TabLabel;
|
m_tabText.text = TabLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Destroy()
|
public virtual void Destroy()
|
||||||
{
|
{
|
||||||
m_pendingDestroy = true;
|
m_pendingDestroy = true;
|
||||||
|
|
||||||
GameObject tabGroup = BaseUI.tabButton?.transform.parent.gameObject;
|
GameObject tabGroup = m_tabButton?.transform.parent.gameObject;
|
||||||
|
|
||||||
if (tabGroup)
|
if (tabGroup)
|
||||||
{
|
|
||||||
GameObject.Destroy(tabGroup);
|
GameObject.Destroy(tabGroup);
|
||||||
}
|
|
||||||
|
|
||||||
int thisIndex = -1;
|
int thisIndex = -1;
|
||||||
if (InspectorManager.Instance.m_currentInspectors.Contains(this))
|
if (InspectorManager.Instance.m_currentInspectors.Contains(this))
|
||||||
@ -88,5 +77,44 @@ namespace UnityExplorer.Core.Inspectors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region UI
|
||||||
|
|
||||||
|
public abstract GameObject Content { get; set; }
|
||||||
|
public Button m_tabButton;
|
||||||
|
public Text m_tabText;
|
||||||
|
|
||||||
|
public void AddInspectorTab(InspectorBase parent)
|
||||||
|
{
|
||||||
|
var tabContent = InspectorManager.m_tabBarContent;
|
||||||
|
|
||||||
|
var tabGroupObj = UIFactory.CreateHorizontalGroup(tabContent, "TabObject", true, true, true, true);
|
||||||
|
UIFactory.SetLayoutElement(tabGroupObj, minWidth: 185, flexibleWidth: 0);
|
||||||
|
tabGroupObj.AddComponent<Mask>();
|
||||||
|
|
||||||
|
m_tabButton = UIFactory.CreateButton(tabGroupObj,
|
||||||
|
"TabButton",
|
||||||
|
"",
|
||||||
|
() => { InspectorManager.Instance.SetInspectorTab(parent); });
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(m_tabButton.gameObject, minWidth: 165, flexibleWidth: 0);
|
||||||
|
|
||||||
|
m_tabText = m_tabButton.GetComponentInChildren<Text>();
|
||||||
|
m_tabText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
m_tabText.alignment = TextAnchor.MiddleLeft;
|
||||||
|
|
||||||
|
var closeBtn = UIFactory.CreateButton(tabGroupObj,
|
||||||
|
"CloseButton",
|
||||||
|
"X",
|
||||||
|
parent.Destroy,
|
||||||
|
new Color(0.2f, 0.2f, 0.2f, 1));
|
||||||
|
|
||||||
|
UIFactory.SetLayoutElement(closeBtn.gameObject, minWidth: 20, flexibleWidth: 0);
|
||||||
|
|
||||||
|
var closeBtnText = closeBtn.GetComponentInChildren<Text>();
|
||||||
|
closeBtnText.color = new Color(1, 0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,61 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityExplorer.Core.Inspectors;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Main.Home.Inspectors
|
|
||||||
{
|
|
||||||
public abstract class InspectorBaseUI
|
|
||||||
{
|
|
||||||
public abstract GameObject Content { get; set; }
|
|
||||||
public Button tabButton;
|
|
||||||
public Text tabText;
|
|
||||||
|
|
||||||
public void AddInspectorTab(InspectorBase parent)
|
|
||||||
{
|
|
||||||
var tabContent = InspectorManager.UI.m_tabBarContent;
|
|
||||||
|
|
||||||
var tabGroupObj = UIFactory.CreateHorizontalGroup(tabContent);
|
|
||||||
var tabGroup = tabGroupObj.GetComponent<HorizontalLayoutGroup>();
|
|
||||||
tabGroup.childForceExpandWidth = true;
|
|
||||||
tabGroup.childControlWidth = true;
|
|
||||||
var tabLayout = tabGroupObj.AddComponent<LayoutElement>();
|
|
||||||
tabLayout.minWidth = 185;
|
|
||||||
tabLayout.flexibleWidth = 0;
|
|
||||||
tabGroupObj.AddComponent<Mask>();
|
|
||||||
|
|
||||||
var targetButtonObj = UIFactory.CreateButton(tabGroupObj);
|
|
||||||
targetButtonObj.AddComponent<Mask>();
|
|
||||||
var targetButtonLayout = targetButtonObj.AddComponent<LayoutElement>();
|
|
||||||
targetButtonLayout.minWidth = 165;
|
|
||||||
targetButtonLayout.flexibleWidth = 0;
|
|
||||||
|
|
||||||
tabText = targetButtonObj.GetComponentInChildren<Text>();
|
|
||||||
tabText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
|
||||||
tabText.alignment = TextAnchor.MiddleLeft;
|
|
||||||
|
|
||||||
tabButton = targetButtonObj.GetComponent<Button>();
|
|
||||||
|
|
||||||
tabButton.onClick.AddListener(() => { InspectorManager.Instance.SetInspectorTab(parent); });
|
|
||||||
|
|
||||||
var closeBtnObj = UIFactory.CreateButton(tabGroupObj);
|
|
||||||
var closeBtnLayout = closeBtnObj.AddComponent<LayoutElement>();
|
|
||||||
closeBtnLayout.minWidth = 20;
|
|
||||||
closeBtnLayout.flexibleWidth = 0;
|
|
||||||
var closeBtnText = closeBtnObj.GetComponentInChildren<Text>();
|
|
||||||
closeBtnText.text = "X";
|
|
||||||
closeBtnText.color = new Color(1, 0, 0, 1);
|
|
||||||
|
|
||||||
var closeBtn = closeBtnObj.GetComponent<Button>();
|
|
||||||
|
|
||||||
closeBtn.onClick.AddListener(parent.Destroy);
|
|
||||||
|
|
||||||
var closeColors = closeBtn.colors;
|
|
||||||
closeColors.normalColor = new Color(0.2f, 0.2f, 0.2f, 1);
|
|
||||||
closeBtn.colors = closeColors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user