mirror of
https://github.com/originalnicodr/CinematicUnityExplorer.git
synced 2025-07-19 01:57:56 +08:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
e3584654a6 | |||
388c9fbc29 | |||
2f35b9d2c7 | |||
b82cc62186 | |||
9429b84cfa | |||
2719c69753 | |||
9144f89e32 | |||
3bc1268444 | |||
4c100daf83 | |||
e7d591176e | |||
ca46607c49 | |||
7fb67b4e28 | |||
c0f42ad983 | |||
6111c1743b |
30
.github/workflows/dotnet.yml
vendored
30
.github/workflows/dotnet.yml
vendored
@ -29,79 +29,79 @@ jobs:
|
||||
|
||||
# Upload artifacts
|
||||
- name: Upload BepInEx.IL2CPP
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.BepInEx.IL2CPP.zip
|
||||
path: ./Release/CinematicUnityExplorer.BepInEx.IL2CPP/
|
||||
|
||||
- name: Upload BepInEx.IL2CPP.CoreCLR
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.BepInEx.IL2CPP.CoreCLR.zip
|
||||
path: ./Release/CinematicUnityExplorer.BepInEx.IL2CPP.CoreCLR/
|
||||
|
||||
- name: Upload BepInEx.Unity.IL2CPP.CoreCLR
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.BepInEx.Unity.IL2CPP.CoreCLR.zip
|
||||
path: ./Release/CinematicUnityExplorer.BepInEx.Unity.IL2CPP.CoreCLR/
|
||||
|
||||
- name: Upload BepInEx5.Mono
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.BepInEx5.Mono.zip
|
||||
path: ./Release/CinematicUnityExplorer.BepInEx5.Mono/
|
||||
|
||||
- name: Upload BepInEx6.Mono
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.BepInEx6.Mono.zip
|
||||
path: ./Release/CinematicUnityExplorer.BepInEx6.Mono/
|
||||
|
||||
- name: Upload BepInEx6.Unity.Mono
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.BepInEx6.Unity.Mono.zip
|
||||
path: ./Release/CinematicUnityExplorer.BepInEx6.Unity.Mono/
|
||||
|
||||
- name: Upload MelonLoader.IL2CPP
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.MelonLoader.IL2CPP.zip
|
||||
path: ./Release/CinematicUnityExplorer.MelonLoader.IL2CPP/
|
||||
|
||||
- name: Upload MelonLoader.IL2CPP.net6preview
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.MelonLoader.IL2CPP.net6preview.zip
|
||||
path: ./Release/CinematicUnityExplorer.MelonLoader.IL2CPP.net6preview/
|
||||
|
||||
- name: Upload MelonLoader.IL2CPP.CoreCLR
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.MelonLoader.IL2CPP.CoreCLR.zip
|
||||
path: ./Release/CinematicUnityExplorer.MelonLoader.IL2CPP.CoreCLR/
|
||||
|
||||
- name: Upload MelonLoader.Mono
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.MelonLoader.Mono.zip
|
||||
path: ./Release/CinematicUnityExplorer.MelonLoader.Mono/
|
||||
|
||||
- name: Upload Standalone.IL2CPP
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.Standalone.IL2CPP.zip
|
||||
path: ./Release/CinematicUnityExplorer.Standalone.IL2CPP/
|
||||
|
||||
- name: Upload Standalone.Mono
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.Standalone.Mono.zip
|
||||
path: ./Release/CinematicUnityExplorer.Standalone.Mono/
|
||||
|
||||
- name: Upload Editor
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: CinematicUnityExplorer.Editor.zip
|
||||
path: ./UnityEditorPackage/
|
||||
@ -127,13 +127,13 @@ jobs:
|
||||
run: ./build_connector.ps1
|
||||
|
||||
- name: Upload Unity IGCS Connector
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: UnityIGCSConnector.dll
|
||||
path: ./Release/UnityIGCSConnector.dll
|
||||
|
||||
- name: Upload Unity IGCS Connector 32bit
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: UnityIGCSConnector.32.dll
|
||||
path: ./Release/UnityIGCSConnector.32.dll
|
||||
|
Binary file not shown.
@ -1,6 +1,7 @@
|
||||
using HarmonyLib;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.Config;
|
||||
#if UNHOLLOWER
|
||||
using IL2CPPUtils = UnhollowerBaseLib.UnhollowerUtils;
|
||||
#endif
|
||||
@ -12,8 +13,12 @@ namespace UnityExplorer
|
||||
{
|
||||
public class ArrowGenerator
|
||||
{
|
||||
public static GameObject CreateArrow(Vector3 arrowPosition, Quaternion arrowRotation, Color color){
|
||||
public static GameObject CreateArrow(Vector3 arrowPosition, Quaternion arrowRotation, Color color)
|
||||
{
|
||||
try {
|
||||
float arrowSizeValue = ConfigManager.Arrow_Size.Value;
|
||||
Vector3 arrowSize = new Vector3(Math.Max(arrowSizeValue, 0.1f), Math.Max(arrowSizeValue, 0.1f), Math.Max(arrowSizeValue, 0.1f));
|
||||
|
||||
GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
|
||||
cylinder.GetComponent<Collider>().enabled = false;
|
||||
cylinder.GetComponent<MeshFilter>().mesh = CreateCylinderMesh(0.01f, 20, 2);
|
||||
@ -34,6 +39,7 @@ namespace UnityExplorer
|
||||
|
||||
GameObject arrow = new GameObject("CUE-Arrow");
|
||||
cylinder.transform.SetParent(arrow.transform, true);
|
||||
arrow.transform.localScale = arrowSize;
|
||||
arrow.transform.position = arrowPosition;
|
||||
arrow.transform.rotation = arrowRotation;
|
||||
arrow.transform.position += 0.5f * arrow.transform.forward; // Move the arrow forward so the cylinder starts on the wanted position
|
||||
|
@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UnityExplorer.Config;
|
||||
using UniverseLib.UI;
|
||||
using UniverseLib.UI.Models;
|
||||
using UniverseLib.UI.Widgets.ScrollView;
|
||||
@ -69,6 +70,9 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
private void ToggleVisualizer(){
|
||||
GameObject visualizer = light.transform.GetChild(0).gameObject;
|
||||
float arrowSize = ConfigManager.Arrow_Size.Value;
|
||||
Vector3 arrowSizeVec = new Vector3(Math.Max(arrowSize, 0.1f), Math.Max(arrowSize, 0.1f), Math.Max(arrowSize, 0.1f));
|
||||
light.transform.GetChild(0).localScale = arrowSizeVec;
|
||||
visualizer.SetActive(!visualizer.activeSelf);
|
||||
}
|
||||
|
||||
|
@ -75,9 +75,10 @@ namespace UnityExplorer.Serializers
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public readonly Vector3 position;
|
||||
public readonly Vector3 angles;
|
||||
public readonly Vector3 scale;
|
||||
// They cant be read-only because it causes problems with XML serialization in older versions of .NET
|
||||
public Vector3 position { get; set; }
|
||||
public Vector3 angles { get; set; }
|
||||
public Vector3 scale { get; set; }
|
||||
|
||||
public void CopyToTransform(Transform transform){
|
||||
transform.localPosition = position;
|
||||
|
@ -32,8 +32,9 @@ namespace UnityExplorer.Config
|
||||
public static ConfigElement<bool> Reflection_Hide_NativeInfoPtrs;
|
||||
public static ConfigElement<bool> Auto_Scale_UI;
|
||||
public static ConfigElement<bool> Reset_Camera_Transform;
|
||||
public static ConfigElement<float> Arrow_Size;
|
||||
public static ConfigElement<bool> Advanced_Freecam_Selection;
|
||||
|
||||
public static ConfigElement<FreeCamPanel.FreeCameraType> Default_Freecam;
|
||||
public static ConfigElement<KeyCode> Pause;
|
||||
public static ConfigElement<KeyCode> Frameskip;
|
||||
public static ConfigElement<KeyCode> Screenshot;
|
||||
@ -61,6 +62,10 @@ namespace UnityExplorer.Config
|
||||
public static ConfigElement<KeyCode> Reset_FOV;
|
||||
public static ConfigElement<KeyCode> Toggle_Animations;
|
||||
|
||||
public static ConfigElement<FreeCamPanel.FreeCameraType> Default_Freecam;
|
||||
public static ConfigElement<string> Custom_Components_To_Disable;
|
||||
public static ConfigElement<string> Preferred_Target_Camera;
|
||||
|
||||
// internal configs
|
||||
internal static InternalConfigHandler InternalHandler { get; private set; }
|
||||
internal static readonly Dictionary<UIManager.Panels, ConfigElement<string>> PanelSaveData = new();
|
||||
@ -189,11 +194,15 @@ namespace UnityExplorer.Config
|
||||
|
||||
Reset_Camera_Transform = new("Reset Camera transform on freecam disable",
|
||||
"Reset the camera position and rotation between freecam sessions, so the freecam always starts from the gameplay position and rotation.",
|
||||
false);
|
||||
true);
|
||||
|
||||
Default_Freecam = new("Default Freecam mode",
|
||||
"Default type of freecam selected on startup.",
|
||||
FreeCamPanel.FreeCameraType.New);
|
||||
Arrow_Size = new("Visualizers arrows size",
|
||||
"Cam Paths nodes and Lights Manager lights visualizers' arrow size (must be positive) (needs visualizer toggled to reflect changes).",
|
||||
1f);
|
||||
|
||||
Advanced_Freecam_Selection = new("Advanced Freecam Selection",
|
||||
"Enables certain advanced settings on the Freecam panel, in case the user can't get the freecam to work properly (requires game reset).",
|
||||
false);
|
||||
|
||||
Pause = new("Pause",
|
||||
"Toggle the pause of the game.",
|
||||
@ -300,6 +309,19 @@ namespace UnityExplorer.Config
|
||||
Toggle_Animations = new("Toggle NPC animations",
|
||||
"Toggle NPC animations as selected in the Animator panel.",
|
||||
KeyCode.Keypad0);
|
||||
|
||||
Default_Freecam = new("Default Freecam mode",
|
||||
"Default type of freecam selected on startup (gets automatically updated with the last type of camera used).",
|
||||
FreeCamPanel.FreeCameraType.New);
|
||||
|
||||
Custom_Components_To_Disable = new("Custom components to disable",
|
||||
"List of custom components to disable when enabling the freecam (gets automatically updated when editing it from the freecam panel).",
|
||||
"");
|
||||
|
||||
Preferred_Target_Camera = new("Preferred Target Camera",
|
||||
"The camera that will be targeted by the freecam methods.\n" +
|
||||
"Only used when Advanced Freecam Selection is enabled.",
|
||||
"\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +100,9 @@ namespace UnityExplorer
|
||||
|
||||
public static void InspectWithFilters(object target, string filterInputField, UnityExplorer.Inspectors.MemberFilter memberFilterFlags = UnityExplorer.Inspectors.MemberFilter.All, bool staticReflection = false, CacheObjectBase parent = null)
|
||||
{
|
||||
if (TryFocusActiveInspector(target))
|
||||
return;
|
||||
|
||||
ReflectionInspector inspector = CreateInspector<ReflectionInspector>(target, staticReflection, parent);
|
||||
inspector.filterInputField.Text = filterInputField;
|
||||
//TODO: Update the member flags visually on the inspector.
|
||||
|
@ -46,9 +46,10 @@ namespace UnityExplorer.Inspectors
|
||||
public override bool CanDragAndResize => false;
|
||||
private Action<GameObject> inspectorAction = null;
|
||||
|
||||
internal Text objNameLabel;
|
||||
internal Text objPathLabel;
|
||||
internal Text mousePosLabel;
|
||||
private Text inspectorLabelTitle;
|
||||
private Text objNameLabel;
|
||||
private Text objPathLabel;
|
||||
private Text mousePosLabel;
|
||||
|
||||
public MouseInspector(UIBase owner) : base(owner)
|
||||
{
|
||||
@ -125,6 +126,43 @@ namespace UnityExplorer.Inspectors
|
||||
return Inspecting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the title text in the inspector UI, if the inspector title label is assigned.
|
||||
/// </summary>
|
||||
/// <param name="title">The new title text to display in the inspector.</param>
|
||||
internal void UpdateInspectorTitle(string title)
|
||||
{
|
||||
// Unity null check - if inspectorLabelTitle is assigned, update its text.
|
||||
if (inspectorLabelTitle)
|
||||
{
|
||||
inspectorLabelTitle.text = title;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Updates the object name label in the inspector UI, if the label is assigned.
|
||||
/// </summary>
|
||||
/// <param name="name">The new object name to display.</param>
|
||||
internal void UpdateObjectNameLabel(string name)
|
||||
{
|
||||
// Unity null check - if objNameLabel is assigned, update its text.
|
||||
if (objNameLabel)
|
||||
{
|
||||
objNameLabel.text = name;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Updates the object path label in the inspector UI, if the label is assigned.
|
||||
/// </summary>
|
||||
/// <param name="path">The new object path to display.</param>
|
||||
internal void UpdateObjectPathLabel(string path)
|
||||
{
|
||||
// Unity null check - if objPathLabel is assigned, update its text.
|
||||
if (objPathLabel)
|
||||
{
|
||||
objPathLabel.text = path;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateInspect()
|
||||
{
|
||||
if (IInputManager.GetKeyDown(KeyCode.Escape))
|
||||
@ -156,7 +194,7 @@ namespace UnityExplorer.Inspectors
|
||||
lastMousePos = mousePos;
|
||||
|
||||
// use the raw mouse pos for the label
|
||||
mousePosLabel.text = $"<color=grey>Mouse Position:</color> {mousePos.ToString()}";
|
||||
mousePosLabel.text = $"<color=grey>Mouse Position:</color> {mousePos.x}, {mousePos.y}";
|
||||
|
||||
// constrain the mouse pos we use within certain bounds
|
||||
if (mousePos.x < 350)
|
||||
@ -196,11 +234,11 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
// Title text
|
||||
|
||||
Text title = UIFactory.CreateLabel(inspectContent,
|
||||
inspectorLabelTitle = UIFactory.CreateLabel(inspectContent,
|
||||
"InspectLabel",
|
||||
"<b>Mouse Inspector</b> (press <b>ESC</b> to cancel)",
|
||||
"",
|
||||
TextAnchor.MiddleCenter);
|
||||
UIFactory.SetLayoutElement(title.gameObject, flexibleWidth: 9999);
|
||||
UIFactory.SetLayoutElement(inspectorLabelTitle.gameObject, flexibleWidth: 9999);
|
||||
|
||||
mousePosLabel = UIFactory.CreateLabel(inspectContent, "MousePosLabel", "Mouse Position:", TextAnchor.MiddleCenter);
|
||||
|
||||
|
@ -17,10 +17,13 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
private static readonly List<CanvasGroup> wasDisabledCanvasGroups = new();
|
||||
private static readonly List<GameObject> objectsAddedCastersTo = new();
|
||||
|
||||
private const string DEFAULT_INSPECTOR_TITLE = "<b>UI Inspector</b> (press <b>ESC</b> to cancel)";
|
||||
|
||||
public override void OnBeginMouseInspect()
|
||||
{
|
||||
SetupUIRaycast();
|
||||
MouseInspector.Instance.objPathLabel.text = "";
|
||||
MouseInspector.Instance.UpdateInspectorTitle(DEFAULT_INSPECTOR_TITLE);
|
||||
MouseInspector.Instance.UpdateObjectPathLabel("");
|
||||
}
|
||||
|
||||
public override void ClearHitData()
|
||||
@ -71,9 +74,9 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
}
|
||||
|
||||
if (currentHitObjects.Any())
|
||||
MouseInspector.Instance.objNameLabel.text = $"Click to view UI Objects under mouse: {currentHitObjects.Count}";
|
||||
MouseInspector.Instance.UpdateObjectNameLabel($"Click to view UI Objects under mouse: {currentHitObjects.Count}");
|
||||
else
|
||||
MouseInspector.Instance.objNameLabel.text = $"No UI objects under mouse.";
|
||||
MouseInspector.Instance.UpdateObjectNameLabel( $"No UI objects under mouse.");
|
||||
}
|
||||
|
||||
private static void SetupUIRaycast()
|
||||
|
@ -1,4 +1,6 @@
|
||||
namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
using UnityExplorer.UI.Panels;
|
||||
|
||||
namespace UnityExplorer.Inspectors.MouseInspectors
|
||||
{
|
||||
public class WorldInspector : MouseInspectorBase
|
||||
{
|
||||
@ -7,15 +9,26 @@
|
||||
|
||||
public override void OnBeginMouseInspect()
|
||||
{
|
||||
MainCamera = Camera.main;
|
||||
|
||||
if (!MainCamera)
|
||||
if (!EnsureMainCamera())
|
||||
{
|
||||
ExplorerCore.LogWarning("No MainCamera found! Cannot inspect world!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns it as the MainCamera and updates the inspector title.
|
||||
/// </summary>
|
||||
/// <param name="cam">The camera to assign.</param>
|
||||
private static void AssignCamAndUpdateTitle(Camera cam)
|
||||
{
|
||||
MainCamera = cam;
|
||||
MouseInspector.Instance.UpdateInspectorTitle(
|
||||
$"<b>World Inspector ({MainCamera.name})</b> (press <b>ESC</b> to cancel)"
|
||||
);
|
||||
}
|
||||
|
||||
public override void ClearHitData()
|
||||
{
|
||||
lastHitObject = null;
|
||||
@ -26,11 +39,52 @@
|
||||
inspectorAction(lastHitObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to ensure that MainCamera is assigned. If not then attempts to find it.
|
||||
/// If no cameras are available, logs a warning and returns null.
|
||||
/// </summary>
|
||||
private static Camera EnsureMainCamera()
|
||||
{
|
||||
if (MainCamera){
|
||||
// We still call this in case the last title was from the UIInspector
|
||||
AssignCamAndUpdateTitle(MainCamera);
|
||||
return MainCamera;
|
||||
}
|
||||
|
||||
if (Camera.main){
|
||||
AssignCamAndUpdateTitle(Camera.main);
|
||||
return MainCamera;
|
||||
}
|
||||
|
||||
ExplorerCore.LogWarning("No Camera.main found, trying to find a camera named 'Main Camera' or 'MainCamera'...");
|
||||
Camera namedCam = Camera.allCameras.FirstOrDefault(c => c.name is "Main Camera" or "MainCamera");
|
||||
if (namedCam) {
|
||||
AssignCamAndUpdateTitle(namedCam);
|
||||
return MainCamera;
|
||||
}
|
||||
|
||||
if (FreeCamPanel.inFreeCamMode && FreeCamPanel.GetFreecam()){
|
||||
AssignCamAndUpdateTitle(FreeCamPanel.GetFreecam());
|
||||
return MainCamera;
|
||||
}
|
||||
|
||||
ExplorerCore.LogWarning("No camera named found, using the first camera created...");
|
||||
var fallbackCam = Camera.allCameras.FirstOrDefault();
|
||||
if (fallbackCam) {
|
||||
AssignCamAndUpdateTitle(fallbackCam);
|
||||
return MainCamera;
|
||||
}
|
||||
|
||||
// If we reach here, no cameras were found at all.
|
||||
ExplorerCore.LogWarning("No valid cameras found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void UpdateMouseInspect(Vector2 mousePos)
|
||||
{
|
||||
if (!MainCamera)
|
||||
MainCamera = Camera.main;
|
||||
if (!MainCamera)
|
||||
// Attempt to ensure camera each time UpdateMouseInspect is called
|
||||
// in case something changed or wasn't set initially.
|
||||
if (!EnsureMainCamera())
|
||||
{
|
||||
ExplorerCore.LogWarning("No Main Camera was found, unable to inspect world!");
|
||||
MouseInspector.Instance.StopInspect();
|
||||
@ -51,8 +105,8 @@
|
||||
if (obj != lastHitObject)
|
||||
{
|
||||
lastHitObject = obj;
|
||||
MouseInspector.Instance.objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
|
||||
MouseInspector.Instance.objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
|
||||
MouseInspector.Instance.UpdateObjectNameLabel($"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>");
|
||||
MouseInspector.Instance.UpdateObjectPathLabel($"Path: {obj.transform.GetTransformPath(true)}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,10 @@ namespace UnityExplorer.Loader.Standalone
|
||||
public bool Auto_Scale_UI;
|
||||
public bool Reset_Camera_Transform;
|
||||
public FreeCamPanel.FreeCameraType Default_Freecam;
|
||||
public string Custom_Components_To_Disable;
|
||||
public string Preferred_Target_Camera;
|
||||
public float Arrow_Size = 1f;
|
||||
public bool Advanced_Freecam_Selection;
|
||||
|
||||
public KeyCode Pause;
|
||||
public KeyCode Frameskip;
|
||||
@ -87,6 +91,11 @@ namespace UnityExplorer.Loader.Standalone
|
||||
ConfigManager.Auto_Scale_UI.Value = this.Auto_Scale_UI;
|
||||
ConfigManager.Reset_Camera_Transform.Value = this.Reset_Camera_Transform;
|
||||
ConfigManager.Default_Freecam.Value = this.Default_Freecam;
|
||||
ConfigManager.Custom_Components_To_Disable.Value = this.Custom_Components_To_Disable;
|
||||
ConfigManager.Preferred_Target_Camera.Value = this.Preferred_Target_Camera;
|
||||
|
||||
ConfigManager.Arrow_Size.Value = this.Arrow_Size;
|
||||
ConfigManager.Advanced_Freecam_Selection.Value = this.Advanced_Freecam_Selection;
|
||||
|
||||
ConfigManager.Pause.Value = this.Pause;
|
||||
ConfigManager.Frameskip.Value = this.Frameskip;
|
||||
|
@ -37,7 +37,7 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
public override string Name => "Freecam";
|
||||
public override UIManager.Panels PanelType => UIManager.Panels.Freecam;
|
||||
public override int MinWidth => 450;
|
||||
public override int MinWidth => 500;
|
||||
public override int MinHeight => 750;
|
||||
public override Vector2 DefaultAnchorMin => new(0.4f, 0.4f);
|
||||
public override Vector2 DefaultAnchorMax => new(0.6f, 0.6f);
|
||||
@ -68,15 +68,20 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
static ButtonRef startStopButton;
|
||||
public static Dropdown cameraTypeDropdown;
|
||||
internal static Dropdown targetCameraDropdown;
|
||||
internal static FreeCameraType currentCameraType;
|
||||
public static Toggle blockFreecamMovementToggle;
|
||||
public static Toggle blockGamesInputOnFreecamToggle;
|
||||
static InputFieldRef positionInput;
|
||||
static InputFieldRef moveSpeedInput;
|
||||
static InputFieldRef componentsToDisableInput;
|
||||
static Text followLookAtObjectLabel;
|
||||
static ButtonRef inspectButton;
|
||||
public static Toggle followRotationToggle;
|
||||
static bool disabledCinemachine;
|
||||
static bool disabledOrthographic;
|
||||
static List<string> stringComponentsToDisable = new();
|
||||
static List<Behaviour> componentsToDisable = new();
|
||||
|
||||
public static bool supportedInput => InputManager.CurrentType == InputType.Legacy;
|
||||
|
||||
@ -99,14 +104,15 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
internal static void BeginFreecam()
|
||||
{
|
||||
inFreeCamMode = true;
|
||||
connector?.UpdateFreecamStatus(true);
|
||||
|
||||
previousMousePosition = IInputManager.MousePosition;
|
||||
|
||||
CacheMainCamera();
|
||||
SetupFreeCamera();
|
||||
|
||||
// Need to be done after CacheMainCamera to not trigger targetCameraDropdown onValueChanged
|
||||
inFreeCamMode = true;
|
||||
|
||||
inspectButton.GameObject.SetActive(true);
|
||||
|
||||
UpdateClippingPlanes();
|
||||
@ -115,9 +121,78 @@ namespace UnityExplorer.UI.Panels
|
||||
freecamCursorUnlocker.Enable();
|
||||
}
|
||||
|
||||
private static Camera[] GetAvailableCameras()
|
||||
{
|
||||
Camera[] cameras = {};
|
||||
try
|
||||
{
|
||||
cameras = Camera.allCameras;
|
||||
}
|
||||
// Some ILCPP games might not have Camera.allCameras available
|
||||
catch {
|
||||
cameras = RuntimeHelper.FindObjectsOfTypeAll<Camera>();
|
||||
}
|
||||
|
||||
return cameras.Where(c => c.name != "CUE Camera").ToArray();
|
||||
}
|
||||
|
||||
private static Camera GetTargetCamera()
|
||||
{
|
||||
if (!ConfigManager.Advanced_Freecam_Selection.Value && !targetCameraDropdown)
|
||||
{
|
||||
return Camera.main;
|
||||
}
|
||||
|
||||
Camera[] cameras = GetAvailableCameras();
|
||||
|
||||
int selectedCameraTargetIndex = -1;
|
||||
|
||||
// If the list of camera was updated since the last time we checked, update the dropdown and select the current main camera if available
|
||||
if (!cameras.Select(c => c.name).SequenceEqual(targetCameraDropdown.options.ToArray().Select(c => c.text)))
|
||||
{
|
||||
targetCameraDropdown.options.Clear();
|
||||
for (int i = 0; i < cameras.Length; i++)
|
||||
{
|
||||
Camera cam = cameras[i];
|
||||
targetCameraDropdown.options.Add(new Dropdown.OptionData(cam.name));
|
||||
|
||||
// The user selected a target camera at some point, default to that
|
||||
if (ConfigManager.Preferred_Target_Camera.Value == GetGameObjectPath(cam.gameObject)) {
|
||||
selectedCameraTargetIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
// If couldn't find the user selected camera default to the main camera
|
||||
if (selectedCameraTargetIndex == -1)
|
||||
{
|
||||
for (int i = 0; i < cameras.Length; i++)
|
||||
{
|
||||
if (cameras[i] == Camera.main)
|
||||
{
|
||||
selectedCameraTargetIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetTargetDropdownValueWithoutNotify(selectedCameraTargetIndex);
|
||||
targetCameraDropdown.captionText.text = cameras[selectedCameraTargetIndex].name;
|
||||
}
|
||||
|
||||
// Fallback to the first camera
|
||||
if (targetCameraDropdown.value >= cameras.Length)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Selected camera index {targetCameraDropdown.value} is out of bounds, resetting to 0.");
|
||||
targetCameraDropdown.value = 0;
|
||||
}
|
||||
|
||||
return cameras[targetCameraDropdown.value];
|
||||
}
|
||||
|
||||
static void CacheMainCamera()
|
||||
{
|
||||
Camera currentMain = Camera.main;
|
||||
Camera currentMain = GetTargetCamera();
|
||||
|
||||
if (currentMain)
|
||||
{
|
||||
lastMainCamera = currentMain;
|
||||
@ -151,6 +226,8 @@ namespace UnityExplorer.UI.Panels
|
||||
currentCameraType = FreeCameraType.Gameplay;
|
||||
ourCamera = lastMainCamera;
|
||||
MaybeToggleCinemachine(false);
|
||||
MaybeToggleOrthographic(false);
|
||||
ToggleCustomComponents(false);
|
||||
|
||||
// If the farClipPlaneValue is the default one try to use the one from the gameplay camera
|
||||
if (farClipPlaneValue == 2000){
|
||||
@ -169,7 +246,7 @@ namespace UnityExplorer.UI.Panels
|
||||
lastMainCamera.enabled = false;
|
||||
}
|
||||
|
||||
ourCamera = new GameObject("UE_Freecam").AddComponent<Camera>();
|
||||
ourCamera = new GameObject("CUE Camera").AddComponent<Camera>();
|
||||
ourCamera.gameObject.tag = "MainCamera";
|
||||
GameObject.DontDestroyOnLoad(ourCamera.gameObject);
|
||||
ourCamera.gameObject.hideFlags = HideFlags.HideAndDontSave;
|
||||
@ -185,7 +262,9 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
ourCamera = GameObject.Instantiate(lastMainCamera);
|
||||
lastMainCamera.enabled = false;
|
||||
MaybeToggleCinemachine(false);
|
||||
MaybeDeleteCinemachine();
|
||||
MaybeToggleOrthographic(false);
|
||||
ToggleCustomComponents(false);
|
||||
|
||||
// If the farClipPlaneValue is the default one try to use the one from the gameplay camera
|
||||
if (farClipPlaneValue == 2000){
|
||||
@ -208,8 +287,10 @@ namespace UnityExplorer.UI.Panels
|
||||
// HDRP might introduce problems when moving the camera when replacing the worldToCameraMatrix,
|
||||
// so we will try to move the real camera as well.
|
||||
MaybeToggleCinemachine(false);
|
||||
MaybeToggleOrthographic(false);
|
||||
ToggleCustomComponents(false);
|
||||
|
||||
cameraMatrixOverrider = new GameObject("[CUE] Camera Matrix Overrider").AddComponent<Camera>();
|
||||
cameraMatrixOverrider = new GameObject("CUE Camera").AddComponent<Camera>();
|
||||
cameraMatrixOverrider.enabled = false;
|
||||
cameraMatrixOverrider.transform.position = lastMainCamera.transform.position;
|
||||
cameraMatrixOverrider.transform.rotation = lastMainCamera.transform.rotation;
|
||||
@ -224,7 +305,7 @@ namespace UnityExplorer.UI.Panels
|
||||
// Fallback in case we couldn't find the main camera for some reason
|
||||
if (!ourCamera)
|
||||
{
|
||||
ourCamera = new GameObject("UE_Freecam").AddComponent<Camera>();
|
||||
ourCamera = new GameObject("CUE Camera").AddComponent<Camera>();
|
||||
ourCamera.gameObject.tag = "MainCamera";
|
||||
GameObject.DontDestroyOnLoad(ourCamera.gameObject);
|
||||
ourCamera.gameObject.hideFlags = HideFlags.HideAndDontSave;
|
||||
@ -258,6 +339,8 @@ namespace UnityExplorer.UI.Panels
|
||||
switch(currentCameraType) {
|
||||
case FreeCameraType.Gameplay:
|
||||
MaybeToggleCinemachine(true);
|
||||
MaybeToggleOrthographic(true);
|
||||
ToggleCustomComponents(true);
|
||||
ourCamera = null;
|
||||
|
||||
if (lastMainCamera)
|
||||
@ -277,6 +360,8 @@ namespace UnityExplorer.UI.Panels
|
||||
break;
|
||||
case FreeCameraType.ForcedMatrix:
|
||||
MaybeToggleCinemachine(true);
|
||||
MaybeToggleOrthographic(true);
|
||||
ToggleCustomComponents(true);
|
||||
MethodInfo resetCullingMatrixMethod = typeof(Camera).GetMethod("ResetCullingMatrix", new Type[] {});
|
||||
resetCullingMatrixMethod.Invoke(ourCamera, null);
|
||||
|
||||
@ -315,6 +400,49 @@ namespace UnityExplorer.UI.Panels
|
||||
freecamCursorUnlocker.Disable();
|
||||
}
|
||||
|
||||
internal static void MaybeResetFreecam()
|
||||
{
|
||||
if (inFreeCamMode) {
|
||||
EndFreecam();
|
||||
BeginFreecam();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdateTargetCameraAction(int newCameraIndex)
|
||||
{
|
||||
Camera[] cameras = GetAvailableCameras();
|
||||
Camera cam = cameras[newCameraIndex];
|
||||
ConfigManager.Preferred_Target_Camera.Value = GetGameObjectPath(cam.gameObject);
|
||||
MaybeResetFreecam();
|
||||
}
|
||||
|
||||
internal static void SetTargetDropdownValueWithoutNotify(int selectedCameraTargetIndex)
|
||||
{
|
||||
// Some build types don't have a reference to Dropdown.SetValueWithoutNotify
|
||||
MethodInfo SetValueWithoutNotifyMethod = targetCameraDropdown.GetType().GetMethod("SetValueWithoutNotify", new[] { typeof(int) });
|
||||
if (SetValueWithoutNotifyMethod != null)
|
||||
{
|
||||
SetValueWithoutNotifyMethod.Invoke(targetCameraDropdown, new object[] { selectedCameraTargetIndex });
|
||||
}
|
||||
else
|
||||
{
|
||||
targetCameraDropdown.onValueChanged.RemoveListener(UpdateTargetCameraAction);
|
||||
targetCameraDropdown.value = selectedCameraTargetIndex;
|
||||
targetCameraDropdown.onValueChanged.AddListener(UpdateTargetCameraAction);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetGameObjectPath(GameObject obj)
|
||||
{
|
||||
string path = "/" + obj.name;
|
||||
while (obj.transform.parent != null)
|
||||
{
|
||||
obj = obj.transform.parent.gameObject;
|
||||
path = "/" + obj.name + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
// Experimental feature to automatically disable cinemachine when turning on the gameplay freecam.
|
||||
// If it causes problems in some games we should consider removing it or making it a toggle.
|
||||
// Also, if there are more generic Unity components that control the camera we should include them here.
|
||||
@ -338,6 +466,37 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
}
|
||||
|
||||
static void MaybeDeleteCinemachine(){
|
||||
if (ourCamera){
|
||||
IEnumerable<Behaviour> comps = ourCamera.GetComponentsInChildren<Behaviour>();
|
||||
foreach (Behaviour comp in comps)
|
||||
{
|
||||
string comp_type = comp.GetActualType().ToString();
|
||||
if (comp_type == "Cinemachine.CinemachineBrain" || comp_type == "Il2CppCinemachine.CinemachineBrain"){
|
||||
GameObject.Destroy(comp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void MaybeToggleOrthographic(bool enable){
|
||||
if (ourCamera) {
|
||||
if (enable) {
|
||||
// Only re-enable orthographic mode if we previously disabled it
|
||||
if (disabledOrthographic) {
|
||||
ourCamera.orthographic = true;
|
||||
disabledOrthographic = false;
|
||||
}
|
||||
} else {
|
||||
if (ourCamera.orthographic) {
|
||||
disabledOrthographic = true;
|
||||
ourCamera.orthographic = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SetCameraPositionInput(Vector3 pos)
|
||||
{
|
||||
if (!ourCamera || lastSetCameraPosition == pos)
|
||||
@ -388,13 +547,11 @@ namespace UnityExplorer.UI.Panels
|
||||
GameObject CameraModeRow = UIFactory.CreateHorizontalGroup(ContentRoot, "CameraModeRow", false, false, true, true, 3, default, new(1, 1, 1, 0));
|
||||
|
||||
Text CameraMode = UIFactory.CreateLabel(CameraModeRow, "Camera Mode", "Camera Mode:");
|
||||
UIFactory.SetLayoutElement(CameraMode.gameObject, minWidth: 100, minHeight: 25);
|
||||
UIFactory.SetLayoutElement(CameraMode.gameObject, minWidth: 75, minHeight: 25);
|
||||
|
||||
GameObject cameraTypeDropdownObj = UIFactory.CreateDropdown(CameraModeRow, "CameraType_Dropdown", out cameraTypeDropdown, null, 14, (idx) => {
|
||||
if (inFreeCamMode) {
|
||||
EndFreecam();
|
||||
BeginFreecam();
|
||||
}
|
||||
ConfigManager.Default_Freecam.Value = (FreeCameraType)idx;
|
||||
MaybeResetFreecam();
|
||||
});
|
||||
foreach (FreeCameraType type in Enum.GetValues(typeof(FreeCameraType)).Cast<FreeCameraType>()) {
|
||||
cameraTypeDropdown.options.Add(new Dropdown.OptionData(Enum.GetName(typeof(FreeCameraType), type)));
|
||||
@ -402,6 +559,32 @@ namespace UnityExplorer.UI.Panels
|
||||
UIFactory.SetLayoutElement(cameraTypeDropdownObj, minHeight: 25, minWidth: 150);
|
||||
cameraTypeDropdown.value = (int)ConfigManager.Default_Freecam.Value;
|
||||
|
||||
if (ConfigManager.Advanced_Freecam_Selection.Value)
|
||||
{
|
||||
Text TargetCamLabel = UIFactory.CreateLabel(CameraModeRow, "Target_cam_label", " Target cam:");
|
||||
UIFactory.SetLayoutElement(TargetCamLabel.gameObject, minWidth: 75, minHeight: 25);
|
||||
|
||||
GameObject targetCameraDropdownObj = UIFactory.CreateDropdown(CameraModeRow, "TargetCamera_Dropdown", out targetCameraDropdown, null, 14, null);
|
||||
targetCameraDropdown.onValueChanged.AddListener(UpdateTargetCameraAction);
|
||||
|
||||
try {
|
||||
Camera[] cameras = GetAvailableCameras();
|
||||
foreach (Camera cam in cameras) {
|
||||
targetCameraDropdown.options.Add(new Dropdown.OptionData(cam.name));
|
||||
}
|
||||
if (Camera.main) {
|
||||
SetTargetDropdownValueWithoutNotify(Array.IndexOf(cameras, Camera.main));
|
||||
targetCameraDropdown.captionText.text = Camera.main.name;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ExplorerCore.LogWarning(ex);
|
||||
}
|
||||
|
||||
UIFactory.SetLayoutElement(targetCameraDropdownObj, minHeight: 25, minWidth: 150);
|
||||
}
|
||||
|
||||
|
||||
AddSpacer(5);
|
||||
|
||||
GameObject posRow = AddInputField("Position", "Freecam Pos:", "eg. 0 0 0", out positionInput, PositionInput_OnEndEdit);
|
||||
@ -417,6 +600,12 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
AddSpacer(5);
|
||||
|
||||
AddInputField("ComponentsToDisable", "Components To Disable:", "CinemachineBrain", out componentsToDisableInput, ComponentsToDisableInput_OnEndEdit, 175);
|
||||
componentsToDisableInput.Text = ConfigManager.Custom_Components_To_Disable.Value;
|
||||
stringComponentsToDisable = ConfigManager.Custom_Components_To_Disable.Value.Split(',').Select(c => c.Trim()).Where(x => !string.IsNullOrEmpty(x)).ToList();
|
||||
|
||||
AddSpacer(5);
|
||||
|
||||
GameObject togglesRow = UIFactory.CreateHorizontalGroup(ContentRoot, "TogglesRow", false, false, true, true, 3, default, new(1, 1, 1, 0));
|
||||
|
||||
GameObject blockFreecamMovement = UIFactory.CreateToggle(togglesRow, "blockFreecamMovement", out blockFreecamMovementToggle, out Text blockFreecamMovementText);
|
||||
@ -553,12 +742,12 @@ namespace UnityExplorer.UI.Panels
|
||||
UIFactory.SetLayoutElement(obj, minHeight: height, flexibleHeight: 0);
|
||||
}
|
||||
|
||||
GameObject AddInputField(string name, string labelText, string placeHolder, out InputFieldRef inputField, Action<string> onInputEndEdit)
|
||||
GameObject AddInputField(string name, string labelText, string placeHolder, out InputFieldRef inputField, Action<string> onInputEndEdit, int minTextWidth = 100)
|
||||
{
|
||||
GameObject row = UIFactory.CreateHorizontalGroup(ContentRoot, $"{name}_Group", false, false, true, true, 3, default, new(1, 1, 1, 0));
|
||||
|
||||
Text posLabel = UIFactory.CreateLabel(row, $"{name}_Label", labelText);
|
||||
UIFactory.SetLayoutElement(posLabel.gameObject, minWidth: 100, minHeight: 25);
|
||||
UIFactory.SetLayoutElement(posLabel.gameObject, minWidth: minTextWidth, minHeight: 25);
|
||||
|
||||
inputField = UIFactory.CreateInputField(row, $"{name}_Input", placeHolder);
|
||||
UIFactory.SetLayoutElement(inputField.GameObject, minWidth: 50, minHeight: 25, flexibleWidth: 9999);
|
||||
@ -700,6 +889,121 @@ namespace UnityExplorer.UI.Panels
|
||||
desiredMoveSpeed = parsed;
|
||||
}
|
||||
|
||||
void ComponentsToDisableInput_OnEndEdit(string input)
|
||||
{
|
||||
EventSystemHelper.SetSelectedGameObject(null);
|
||||
|
||||
ConfigManager.Custom_Components_To_Disable.Value = input;
|
||||
stringComponentsToDisable = input.Split(',').Select(c => c.Trim()).Where(x => !string.IsNullOrEmpty(x)).ToList();
|
||||
}
|
||||
|
||||
static List<Behaviour> GetComponentsToDisable()
|
||||
{
|
||||
List<Behaviour> components = new();
|
||||
if (stringComponentsToDisable == null || stringComponentsToDisable.Count == 0)
|
||||
{
|
||||
return components;
|
||||
}
|
||||
|
||||
foreach (string stringComponent in stringComponentsToDisable)
|
||||
{
|
||||
List<string> pathToComponent = stringComponent.Split('/').Where(x => !string.IsNullOrEmpty(x)).ToList();
|
||||
GameObject currentGameObject = ourCamera.gameObject;
|
||||
for (var i = 0; i < pathToComponent.Count; i++)
|
||||
{
|
||||
string pathStep = pathToComponent[i];
|
||||
if (i == 0 && pathStep == "~")
|
||||
{
|
||||
// Check if we can find the next steps game object in the path
|
||||
i++;
|
||||
pathStep = pathToComponent[i];
|
||||
GameObject foundNextPathStep = null;
|
||||
foreach (GameObject obj in SceneManager.GetActiveScene().GetRootGameObjects()) {
|
||||
if (obj.name == pathStep)
|
||||
{
|
||||
foundNextPathStep = obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundNextPathStep)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Couldn't find {stringComponent} component to disable it.");
|
||||
break;
|
||||
}
|
||||
currentGameObject = foundNextPathStep;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pathStep == "..") {
|
||||
if (!currentGameObject.transform.parent)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Couldn't find {stringComponent} component to disable it.");
|
||||
break;
|
||||
}
|
||||
|
||||
currentGameObject = currentGameObject.transform.parent.gameObject;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Last member of the path, should be a component
|
||||
if (i == pathToComponent.Count - 1) {
|
||||
Behaviour comp = GetComponentByName(currentGameObject, pathStep);
|
||||
if (!comp)
|
||||
{
|
||||
// Should we allow to disable entire GameObjects here if it can't find the right component?
|
||||
ExplorerCore.LogWarning($"Couldn't find {stringComponent} component to disable it.");
|
||||
break;
|
||||
}
|
||||
|
||||
components.Add(comp);
|
||||
}
|
||||
else {
|
||||
Transform nextGameObjectTransform = currentGameObject.transform.Find(pathStep);
|
||||
if (!nextGameObjectTransform)
|
||||
{
|
||||
ExplorerCore.LogWarning($"Couldn't find {stringComponent} component to disable it.");
|
||||
break;
|
||||
}
|
||||
|
||||
currentGameObject = nextGameObjectTransform.gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
static void ToggleCustomComponents(bool enable)
|
||||
{
|
||||
// If disable get the components again
|
||||
if (!enable)
|
||||
{
|
||||
componentsToDisable = GetComponentsToDisable();
|
||||
}
|
||||
|
||||
foreach(Behaviour comp in componentsToDisable)
|
||||
{
|
||||
// We could outright delete the components if on Cloned freecam mode
|
||||
comp.enabled = enable;
|
||||
}
|
||||
}
|
||||
|
||||
static Behaviour GetComponentByName(GameObject obj, string componentsName)
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
IEnumerable<Behaviour> comps = obj.GetComponents<Behaviour>();
|
||||
foreach (Behaviour comp in comps)
|
||||
{
|
||||
string comp_type = comp.GetActualType().ToString();
|
||||
if (comp_type == componentsName){
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void NearClipInput_OnEndEdit(string input)
|
||||
{
|
||||
EventSystemHelper.SetSelectedGameObject(null);
|
||||
@ -834,7 +1138,7 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
Transform movingTransform = FreeCamPanel.GetFreecam().transform;
|
||||
|
||||
if (!FreeCamPanel.blockFreecamMovementToggle.isOn && !FreeCamPanel.cameraPathMover.playingPath && FreeCamPanel.connector?.IsActive != true) {
|
||||
if (!FreeCamPanel.blockFreecamMovementToggle.isOn && !FreeCamPanel.cameraPathMover.playingPath && FreeCamPanel.connector?.IsActive != true && !IsInputFieldInFocus()) {
|
||||
ProcessInput(movingTransform);
|
||||
}
|
||||
|
||||
@ -868,6 +1172,20 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsInputFieldInFocus()
|
||||
{
|
||||
GameObject currentObject = EventSystemHelper.CurrentEventSystem.currentSelectedGameObject;
|
||||
if (currentObject != null)
|
||||
{
|
||||
UnityEngine.UI.InputField selectedInputField = currentObject.GetComponent<UnityEngine.UI.InputField>();
|
||||
if (selectedInputField != null)
|
||||
{
|
||||
return selectedInputField.isFocused;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnPreCull()
|
||||
{
|
||||
UpdateRelativeMatrix();
|
||||
@ -950,11 +1268,25 @@ namespace UnityExplorer.UI.Panels
|
||||
if (IInputManager.GetKey(ConfigManager.Down.Value))
|
||||
transform.position += transform.up * -1 * moveSpeed;
|
||||
|
||||
if (IInputManager.GetKey(ConfigManager.Tilt_Left.Value))
|
||||
// 90 degrees tilt when pressing the speed down hotkey
|
||||
if (IInputManager.GetKey(ConfigManager.Speed_Down_Movement.Value))
|
||||
{
|
||||
if (IInputManager.GetKeyDown(ConfigManager.Tilt_Left.Value)) {
|
||||
transform.Rotate(0, 0, 90, Space.Self);
|
||||
}
|
||||
else if (IInputManager.GetKeyDown(ConfigManager.Tilt_Right.Value)) {
|
||||
transform.Rotate(0, 0, - 90, Space.Self);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IInputManager.GetKey(ConfigManager.Tilt_Left.Value)) {
|
||||
transform.Rotate(0, 0, moveSpeed * 10, Space.Self);
|
||||
|
||||
if (IInputManager.GetKey(ConfigManager.Tilt_Right.Value))
|
||||
}
|
||||
else if (IInputManager.GetKey(ConfigManager.Tilt_Right.Value)) {
|
||||
transform.Rotate(0, 0, - moveSpeed * 10, Space.Self);
|
||||
}
|
||||
}
|
||||
|
||||
if (IInputManager.GetKey(ConfigManager.Tilt_Reset.Value)){
|
||||
// Extract the forward direction of the original quaternion
|
||||
@ -1030,42 +1362,67 @@ namespace UnityExplorer.UI.Panels
|
||||
ExplorerCore.LogWarning($"Failed to listen to BeforeRender: {exception}");
|
||||
}
|
||||
#endif
|
||||
|
||||
// These doesn't exist for Unity <2017 nor when using HDRP
|
||||
Type renderPipelineManagerType = ReflectionUtility.GetTypeByName("RenderPipelineManager");
|
||||
if (renderPipelineManagerType != null){
|
||||
try {
|
||||
EventInfo beginFrameRenderingEvent = renderPipelineManagerType.GetEvent("beginFrameRendering");
|
||||
if (beginFrameRenderingEvent != null) {
|
||||
beginFrameRenderingEvent.AddEventHandler(null, OnBeforeEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo endFrameRenderingEvent = renderPipelineManagerType.GetEvent("endFrameRendering");
|
||||
if (endFrameRenderingEvent != null) {
|
||||
endFrameRenderingEvent.AddEventHandler(null, OnAfterEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo beginCameraRenderingEvent = renderPipelineManagerType.GetEvent("beginCameraRendering");
|
||||
if (beginCameraRenderingEvent != null) {
|
||||
beginCameraRenderingEvent.AddEventHandler(null, OnBeforeEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo endCameraRenderingEvent = renderPipelineManagerType.GetEvent("endCameraRendering");
|
||||
if (endCameraRenderingEvent != null) {
|
||||
endCameraRenderingEvent.AddEventHandler(null, OnAfterEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo beginContextRenderingEvent = renderPipelineManagerType.GetEvent("beginContextRendering");
|
||||
if (beginContextRenderingEvent != null) {
|
||||
beginContextRenderingEvent.AddEventHandler(null, OnBeforeEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo endContextRenderingEvent = renderPipelineManagerType.GetEvent("endContextRendering");
|
||||
if (endContextRenderingEvent != null) {
|
||||
endContextRenderingEvent.AddEventHandler(null, OnAfterEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
try {
|
||||
EventInfo onBeforeRenderEvent = typeof(Application).GetEvent("onBeforeRender");
|
||||
if (onBeforeRenderEvent != null) {
|
||||
onBeforeRenderEvent.AddEventHandler(null, onBeforeRenderAction);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
@ -1079,37 +1436,58 @@ namespace UnityExplorer.UI.Panels
|
||||
ExplorerCore.LogWarning($"Failed to unlisten from BeforeRender: {exception}");
|
||||
}
|
||||
#endif
|
||||
|
||||
// These doesn't exist for Unity <2017 nor when using HDRP
|
||||
Type renderPipelineManagerType = ReflectionUtility.GetTypeByName("RenderPipelineManager");
|
||||
|
||||
if (renderPipelineManagerType != null){
|
||||
try {
|
||||
EventInfo beginFrameRenderingEvent = renderPipelineManagerType.GetEvent("beginFrameRendering");
|
||||
if (beginFrameRenderingEvent != null) {
|
||||
beginFrameRenderingEvent.RemoveEventHandler(null, OnBeforeEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo endFrameRenderingEvent = renderPipelineManagerType.GetEvent("endFrameRendering");
|
||||
if (endFrameRenderingEvent != null) {
|
||||
endFrameRenderingEvent.RemoveEventHandler(null, OnAfterEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo beginCameraRenderingEvent = renderPipelineManagerType.GetEvent("beginCameraRendering");
|
||||
if (beginCameraRenderingEvent != null) {
|
||||
beginCameraRenderingEvent.RemoveEventHandler(null, OnBeforeEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo endCameraRenderingEvent = renderPipelineManagerType.GetEvent("endCameraRendering");
|
||||
if (endCameraRenderingEvent != null) {
|
||||
endCameraRenderingEvent.RemoveEventHandler(null, OnAfterEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo beginContextRenderingEvent = renderPipelineManagerType.GetEvent("beginContextRendering");
|
||||
if (beginContextRenderingEvent != null) {
|
||||
beginContextRenderingEvent.RemoveEventHandler(null, OnBeforeEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try {
|
||||
EventInfo endContextRenderingEvent = renderPipelineManagerType.GetEvent("endContextRendering");
|
||||
if (endContextRenderingEvent != null) {
|
||||
endContextRenderingEvent.RemoveEventHandler(null, OnAfterEvent);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
EventInfo onBeforeRenderEvent = typeof(Application).GetEvent("onBeforeRender");
|
||||
if (onBeforeRenderEvent != null) {
|
||||
|
Reference in New Issue
Block a user