1
0
mirror of https://github.com/originalnicodr/CinematicUnityExplorer.git synced 2026-10-10 13:03:15 +08:00

Added misc panel with HUD toggle and screenshot support. Added more hotkeys and changed the order of panels in the navbar.

This commit is contained in:
originalnicodr
2024-01-27 17:10:15 -03:00
parent 78c8a41e22
commit 252521061b
5 changed files with 257 additions and 10 deletions
+21
View File
@@ -102,6 +102,7 @@ namespace UnityExplorer
// Continous checks and actions
stopFrameSkip();
maybeForcePause();
UIManager.GetPanel<UnityExplorer.UI.Panels.Misc>(UIManager.Panels.Misc).MaybeTakeScreenshot();
if (InputManager.GetKeyDown(KeyCode.Pause))
{
@@ -116,6 +117,26 @@ namespace UnityExplorer
frameSkip = true;
}
}
if (InputManager.GetKeyDown(KeyCode.F12))
{
UIManager.GetPanel<UnityExplorer.UI.Panels.Misc>(UIManager.Panels.Misc).screenshotStatus = UnityExplorer.UI.Panels.Misc.ScreenshotState.TurnOffUI;
}
if (InputManager.GetKeyDown(KeyCode.Delete))
{
UIManager.GetPanel<UnityExplorer.UI.Panels.Misc>(UIManager.Panels.Misc).ToggleHUDElements();
}
if (InputManager.GetKeyDown(KeyCode.Insert))
{
FreeCamPanel.StartStopButton_OnClick();
}
if (InputManager.GetKeyDown(KeyCode.Home))
{
FreeCamPanel.blockFreecamMovementToggle.isOn = !FreeCamPanel.blockFreecamMovementToggle.isOn;
}
}
void stopFrameSkip(){
+2 -2
View File
@@ -311,7 +311,7 @@ namespace UnityExplorer.UI.Panels
return row;
}
void StartStopButton_OnClick()
public static void StartStopButton_OnClick()
{
EventSystemHelper.SetSelectedGameObject(null);
@@ -342,7 +342,7 @@ namespace UnityExplorer.UI.Panels
}
}
void SetToggleButtonState()
static void SetToggleButtonState()
{
if (inFreeCamMode)
{
+223
View File
@@ -0,0 +1,223 @@
using UnityExplorer.CacheObject;
using UnityExplorer.Inspectors;
using UnityExplorer.ObjectExplorer;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool;
#if UNHOLLOWER
using UnhollowerRuntimeLib;
#endif
#if INTEROP
using Il2CppInterop.Runtime.Injection;
#endif
namespace UnityExplorer.UI.Panels
{
public class Misc : UEPanel
{
public enum ScreenshotState
{
DoNothing,
TurnOffUI,
TakeScreenshot,
TurnOnUI,
}
public class UIElement
{
public UIElement(object obj)
{
Object = obj;
ReflectionInspector inspector = Pool<ReflectionInspector>.Borrow();
inspector.Target = obj.TryCast();
Type objType = obj is Type type ? type : obj.GetActualType();
List<CacheMember> members = CacheMemberFactory.GetCacheMembers(objType, inspector);
foreach (CacheMember member in members){
if (member.NameForFiltering.EndsWith(".enabled")){
member.Evaluate();
Enabled = member;
}
if (member.NameForFiltering.EndsWith(".name")){
member.Evaluate();
Name = member;
}
if (Enabled != null && Name != null) break;
}
}
public object Object { get; }
public CacheMember Enabled { get; }
public CacheMember Name { get; }
public override string ToString() => $"{Object}";
}
public Misc(UIBase owner) : base(owner)
{
captureScreenshotFunction = null;
FindCaptureScreenshotFunction();
superSizeValue = 2;
hud = new List<UIElement>();
screenshotStatus = ScreenshotState.DoNothing;
}
public override string Name => "Misc";
public override UIManager.Panels PanelType => UIManager.Panels.Misc;
public override int MinWidth => 275;
public override int MinHeight => 100;
public override Vector2 DefaultAnchorMin => new(0.4f, 0.4f);
public override Vector2 DefaultAnchorMax => new(0.6f, 0.6f);
public override bool NavButtonWanted => true;
public override bool ShouldSaveActiveState => true;
List<UIElement> hud;
Toggle HUDToggle;
CacheMethod captureScreenshotFunction;
int superSizeValue;
public ScreenshotState screenshotStatus;
private void LoadHUDElements(){
List<object> currentResults = SearchProvider.UnityObjectSearch("", "UnityEngine.Canvas", ChildFilter.Any, SceneFilter.Any);
if (hud.Count > 0){
SetValueHUDElements(true);
HUDToggle.isOn = true;
hud.Clear();
}
foreach (object obj in currentResults){
UIElement entry = new UIElement(obj);
// Ignore non-enabled objects and objects without a name, since those tend to be irrelevant
if ((bool) entry.Enabled.Value && entry.Name.Value.ToString() != ""){
hud.Add(entry);
}
}
}
private void SetValueHUDElements(bool value){
// If its the first time changing the HUD, we look up for UI elements.
if (hud.Count == 0){
LoadHUDElements();
}
foreach (UIElement elem in hud){
elem.Enabled.TrySetUserValue(value);
}
}
public void ToggleHUDElements(){
HUDToggle.isOn = !HUDToggle.isOn;
SetValueHUDElements(HUDToggle.isOn);
}
private void TakeScreenshot(){
MethodInfo methodInfo = captureScreenshotFunction.MethodInfo;
string filename = DateTime.Now.ToString("yyyy-M-d HH-mm-ss");
ExplorerCore.LogWarning(filename);
string screenshotsPath = Path.Combine(ExplorerCore.ExplorerFolder, "Screenshots");
System.IO.Directory.CreateDirectory(screenshotsPath);
object[] args = {$"{screenshotsPath}\\{filename}.png", superSizeValue};
methodInfo.Invoke(captureScreenshotFunction.DeclaringInstance, args);
}
private void FindCaptureScreenshotFunction(){
List<object> results = SearchProvider.ClassSearch("UnityEngine.ScreenCapture");
// We assume it's the first for now. Come back if we need to do something else to get it.
object obj = results[0];
Type objType = obj is Type type ? type : obj.GetActualType();
ReflectionInspector inspector = Pool<ReflectionInspector>.Borrow();
List<CacheMember> members = CacheMemberFactory.GetCacheMembers(objType, inspector);
foreach (CacheMember member in members){
if (member is CacheMethod methodMember && methodMember.NameForFiltering == "ScreenCapture.CaptureScreenshot(string, int)"){
captureScreenshotFunction = methodMember;
break;
}
}
}
// We use an enum to walk a series of steps in each frame, so we can take the screenshot without UnityExplorer UI.
public void MaybeTakeScreenshot(){
switch (screenshotStatus){
case ScreenshotState.TurnOffUI:
screenshotStatus = ScreenshotState.TakeScreenshot;
UIManager.ShowMenu = false;
break;
case ScreenshotState.TakeScreenshot:
TakeScreenshot();
screenshotStatus = ScreenshotState.TurnOnUI;
break;
case ScreenshotState.TurnOnUI:
screenshotStatus = ScreenshotState.DoNothing;
UIManager.ShowMenu = true;
break;
case ScreenshotState.DoNothing:
default:
break;
}
}
// ~~~~~~~~ UI construction / callbacks ~~~~~~~~
protected override void ConstructPanelContent()
{
// HUD toggle
GameObject HUDhoriGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "HUDhoriGroup", false, false, true, true, 3,
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(HUDhoriGroup, minHeight: 25, flexibleWidth: 9999);
ButtonRef loadHUDElements = UIFactory.CreateButton(HUDhoriGroup, "HideUI", "Load HUD elements");
UIFactory.SetLayoutElement(loadHUDElements.GameObject, minWidth: 150, minHeight: 25);
loadHUDElements.OnClick += LoadHUDElements;
HUDToggle = new Toggle();
GameObject HUDToggleObj = UIFactory.CreateToggle(HUDhoriGroup, "Toggle HUD", out HUDToggle, out Text toggleText);
UIFactory.SetLayoutElement(HUDToggleObj, minHeight: 25);
HUDToggle.onValueChanged.AddListener(SetValueHUDElements);
HUDToggle.isOn = true; // we picked up only the active effects
toggleText.text = "Toggle HUD";
// Screenshot function
GameObject TakeScreenshotHoriGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "Take screenshot", false, false, true, true, 3,
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(TakeScreenshotHoriGroup, minHeight: 25, flexibleWidth: 9999);
ButtonRef takeScreenshot = UIFactory.CreateButton(TakeScreenshotHoriGroup, "TakeScreenshot", "Take screenshot");
UIFactory.SetLayoutElement(takeScreenshot.GameObject, minWidth: 150, minHeight: 25);
takeScreenshot.OnClick += () => screenshotStatus = ScreenshotState.TurnOffUI;
AddInputField(TakeScreenshotHoriGroup, "Supersize", "Supersize:", $"{2}", SuperSize_OnEndEdit);
}
GameObject AddInputField(GameObject parent, string name, string labelText, string placeHolder, Action<string> onInputEndEdit)
{
Text posLabel = UIFactory.CreateLabel(parent, $"{name}_Label", labelText);
UIFactory.SetLayoutElement(posLabel.gameObject, minWidth: 75, minHeight: 25);
InputFieldRef inputField = UIFactory.CreateInputField(parent, $"{name}_Input", placeHolder);
UIFactory.SetLayoutElement(inputField.GameObject, minWidth: 25, minHeight: 25);
inputField.Component.GetOnEndEdit().AddListener(onInputEndEdit);
return parent;
}
void SuperSize_OnEndEdit(string input)
{
if (!ParseUtility.TryParse(input, out int parsed, out Exception parseEx))
{
ExplorerCore.LogWarning($"Could not parse value: {parseEx.ReflectionExToString()}");
return;
}
superSizeValue = parsed;
}
}
}
+6 -4
View File
@@ -25,7 +25,8 @@ namespace UnityExplorer.UI
Freecam,
LightsManager,
CamPaths,
PostProcessingPanel
PostProcessingPanel,
Misc,
}
public enum VerticalAnchor
@@ -47,7 +48,7 @@ namespace UnityExplorer.UI
public static RectTransform NavBarRect;
public static GameObject NavbarTabButtonHolder;
private static readonly Vector2 NAVBAR_DIMENSIONS = new(1400f, 35f);
private static readonly Vector2 NAVBAR_DIMENSIONS = new(1500f, 35f);
private static ButtonRef closeBtn;
private static TimeScaleWidget timeScaleWidget;
@@ -92,12 +93,13 @@ namespace UnityExplorer.UI
UIPanels.Add(Panels.Inspector, new InspectorPanel(UiBase));
UIPanels.Add(Panels.CSConsole, new CSConsolePanel(UiBase));
UIPanels.Add(Panels.HookManager, new HookManagerPanel(UiBase));
UIPanels.Add(Panels.Clipboard, new ClipboardPanel(UiBase));
UIPanels.Add(Panels.ConsoleLog, new LogPanel(UiBase));
UIPanels.Add(Panels.Freecam, new FreeCamPanel(UiBase));
UIPanels.Add(Panels.LightsManager, new LightsManager(UiBase));
UIPanels.Add(Panels.CamPaths, new CamPaths(UiBase));
UIPanels.Add(Panels.PostProcessingPanel, new PostProcessingPanel(UiBase));
UIPanels.Add(Panels.Clipboard, new ClipboardPanel(UiBase));
UIPanels.Add(Panels.ConsoleLog, new LogPanel(UiBase));
UIPanels.Add(Panels.Misc, new UnityExplorer.UI.Panels.Misc(UiBase));
UIPanels.Add(Panels.Options, new OptionsPanel(UiBase));
UIPanels.Add(Panels.UIInspectorResults, new MouseInspectorResultsPanel(UiBase));
+5 -4
View File
@@ -228,12 +228,13 @@ namespace UnityExplorer.CatmullRom
bool closedLoopFinalPoint = (closedLoop && currentPoint == splinePoints.Length - 1);
//Had tu add "splinePoints.Length" because C# mod doesnt work well with negative values
// Had tu add "splinePoints.Length" because C# mod doesnt work well with negative values
int previousPoint = closedLoop ? (currentPoint + splinePoints.Length - 1)%(splinePoints.Length) : System.Math.Max(currentPoint - 1, 0);
int endSegmentPoint = closedLoop ? (currentPoint + 1)%(splinePoints.Length) : System.Math.Min(currentPoint + 1, splinePoints.Length - 1);
int nextPoint = closedLoop ? (currentPoint + 2)%(splinePoints.Length) : System.Math.Min(currentPoint + 2, splinePoints.Length - 1);
if (d >= 1) return closedLoop ? splinePoints[0] : splinePoints[splinePoints.Length - 1]; //Ideally we should really loop over tho, maybe d % 1.
// Ideally we should really loop over tho.
if (d >= 1) return closedLoop ? splinePoints[0] : splinePoints[splinePoints.Length - 1];
p0 = splinePoints[previousPoint].position;
r0 = CatmullRomPoint.QuaternionToVector4(splinePoints[previousPoint].rotation);
@@ -247,7 +248,7 @@ namespace UnityExplorer.CatmullRom
p3 = splinePoints[nextPoint].position;
r3 = CatmullRomPoint.QuaternionToVector4(splinePoints[nextPoint].rotation);
//Check if we are using the shortest path on the rotation. If not, change each rotation to represent that shortest path.
// Check if we are using the shortest path on the rotation. If not, change each rotation to represent that shortest path.
if (Vector4.Dot(r0, r1) < 0)
r1 = - r1;
@@ -277,7 +278,7 @@ namespace UnityExplorer.CatmullRom
return new CatmullRomPoint(position, rotation, fov);
}
//Implementation from: https://qroph.github.io/2018/07/30/smooth-paths-using-catmull-rom-splines.html
// Implementation from: https://qroph.github.io/2018/07/30/smooth-paths-using-catmull-rom-splines.html
private Vector3 CatmullRomInterpolation(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t){
float tension = 0;
float alpha = 0.5f;