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

Added animators panel and toggle hotkey to pause NPCs animations.

This commit is contained in:
originalnicodr
2024-02-10 12:48:47 -03:00
parent 203d0dede8
commit 6c21446dad
6 changed files with 179 additions and 2 deletions
+5
View File
@@ -55,6 +55,7 @@ namespace UnityExplorer.Config
public static ConfigElement<KeyCode> Increase_FOV;
public static ConfigElement<KeyCode> Decrease_FOV;
public static ConfigElement<KeyCode> Reset_FOV;
public static ConfigElement<KeyCode> Toggle_Animations;
// internal configs
internal static InternalConfigHandler InternalHandler { get; private set; }
@@ -279,6 +280,10 @@ namespace UnityExplorer.Config
Reset_FOV = new("Reset FOV",
"Resets the field of view of the current freecam to the original one.",
KeyCode.KeypadMultiply);
Toggle_Animations = new("Toggle NPC animations",
"Toggle NPC animations as selected in the Animator panel.",
KeyCode.Keypad0);
}
}
}
+5
View File
@@ -139,6 +139,11 @@ namespace UnityExplorer
FreeCamPanel.blockFreecamMovementToggle.isOn = !FreeCamPanel.blockFreecamMovementToggle.isOn;
}
if (IInputManager.GetKeyDown(ConfigManager.Toggle_Animations.Value))
{
UIManager.GetPanel<UnityExplorer.UI.Panels.AnimatorPanel>(UIManager.Panels.AnimatorPanel).HotkeyToggleAnimators();
}
if (FreeCamPanel.supportedInput && IInputManager.GetKeyDown(ConfigManager.Toggle_Block_Games_Input.Value))
{
FreeCamPanel.blockGamesInputOnFreecamToggle.isOn = !FreeCamPanel.blockGamesInputOnFreecamToggle.isOn;
@@ -52,6 +52,7 @@ namespace UnityExplorer.Loader.Standalone
public KeyCode Increase_FOV;
public KeyCode Decrease_FOV;
public KeyCode Reset_FOV;
public KeyCode Toggle_Animations;
internal void Awake()
{
@@ -105,6 +106,7 @@ namespace UnityExplorer.Loader.Standalone
ConfigManager.Increase_FOV.Value = this.Increase_FOV;
ConfigManager.Decrease_FOV.Value = this.Decrease_FOV;
ConfigManager.Reset_FOV.Value = this.Reset_FOV;
ConfigManager.Toggle_Animations.Value = this.Toggle_Animations;
}
}
}
+162
View File
@@ -0,0 +1,162 @@
using UnityExplorer.CacheObject;
using UnityExplorer.ObjectExplorer;
using UnityExplorer.Inspectors;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool;
using UnityEngine;
#if UNHOLLOWER
using UnhollowerRuntimeLib;
#endif
#if INTEROP
using Il2CppInterop.Runtime.Injection;
#endif
namespace UnityExplorer.UI.Panels
{
internal class AnimatorPanel : UEPanel
{
public AnimatorPanel(UIBase owner) : base(owner)
{
}
public override string Name => "Animator";
public override UIManager.Panels PanelType => UIManager.Panels.AnimatorPanel;
public override int MinWidth => 500;
public override int MinHeight => 500;
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<GameObject> UIElements = new List<GameObject>();
internal Dictionary<string,List<Behaviour>> animators = new Dictionary<string,List<Behaviour>>();
internal Dictionary<string,List<Toggle>> animatorToggles = new Dictionary<string,List<Toggle>>();
internal Dictionary<string,bool> ignoresMasterToggler = new Dictionary<string,bool>();
Toggle masterAnimatorToggle = new Toggle();
private void FindAllAnimators(){
// Enable all animators on refresh
if (animators.Count != 0) {
masterAnimatorToggle.isOn = true; // Will also trigger "MasterToggleAnimators(true)"
animators.Clear();
animatorToggles.Clear();
ignoresMasterToggler.Clear();
}
List<object> animatorsObjects = SearchProvider.UnityObjectSearch("", "UnityEngine.Animator", ChildFilter.Any, SceneFilter.ActivelyLoaded);
List<Behaviour> animatorsList = new List<Behaviour>(animatorsObjects.Select(obj => obj.TryCast<Behaviour>())
.Where(a => a.GetComponentsInChildren<SkinnedMeshRenderer>(false).Length != 0 && a.enabled && a.GetComponentsInChildren<Rigidbody>(false).Length != 0));
foreach(Behaviour animator in animatorsList){
GameObject gObj = animator.gameObject;
string key = getNameWithoutClone(gObj.name);
if (!animators.ContainsKey(key)){
animators.Add(key, new List<Behaviour>());
}
animators[key].Add(animator);
}
BuildAnimatorsTogglers();
}
private string getNameWithoutClone(string name){
string newName = name;
while (newName.EndsWith("(Clone)")){
newName = newName.Substring(0, newName.Length - 7);
}
return newName;
}
private void BuildAnimatorsTogglers(){
foreach (var comp in UIElements){
UnityEngine.Object.Destroy(comp);
//UIElements.Remove(comp);
}
foreach (KeyValuePair<string, List<Behaviour>> entry in animators)
{
// A weird canse insensitive "Contains" to identify the player
ignoresMasterToggler[entry.Key] = entry.Key.IndexOf("play", 0, StringComparison.OrdinalIgnoreCase) >= 0;
GameObject horiGroup = UIFactory.CreateHorizontalGroup(ContentRoot, $"{entry.Key}_Group", false, false, true, false, 4,
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(horiGroup, minHeight: 25, flexibleWidth: 9999);
UIElements.Add(horiGroup);
// is Affected by Master Toggler toggle
Toggle ignoresMasterTogglerToggle;
GameObject ignoresMasterTogglerObj = UIFactory.CreateToggle(horiGroup, $"Toggle {entry.Key}", out ignoresMasterTogglerToggle, out Text ignoresMasterTogglerText);
UIFactory.SetLayoutElement(ignoresMasterTogglerObj, minHeight: 25);
ignoresMasterTogglerToggle.isOn = ignoresMasterToggler[entry.Key];
ignoresMasterTogglerToggle.onValueChanged.AddListener(value => ignoresMasterToggler[entry.Key] = value);
ignoresMasterTogglerText.text = entry.Key;
foreach (Behaviour entityAnimator in entry.Value){
Toggle animatorToggle;
GameObject animatorObj = UIFactory.CreateToggle(horiGroup, $"Toggle {entry.Key}", out animatorToggle, out Text animatorToggleText);
if (!animatorToggles.ContainsKey(entry.Key)){
animatorToggles.Add(entry.Key, new List<Toggle>());
}
animatorToggles[entry.Key].Add(animatorToggle);
UIFactory.SetLayoutElement(animatorObj, minHeight: 25);
animatorToggle.isOn = true;
animatorToggle.onValueChanged.AddListener(value => entityAnimator.enabled = value);
}
}
}
public void MasterToggleAnimators(bool enable){
// Load animators for the first time if there are not any
if (animators.Count == 0) FindAllAnimators();
foreach (KeyValuePair<string, List<Behaviour>> entry in animators)
{
if (!ignoresMasterToggler[entry.Key]){
foreach (Toggle animatorToggle in animatorToggles[entry.Key]){
animatorToggle.isOn = enable;
}
}
}
}
public void HotkeyToggleAnimators(){
masterAnimatorToggle.isOn = !masterAnimatorToggle.isOn;
}
// ~~~~~~~~ UI construction / callbacks ~~~~~~~~
protected override void ConstructPanelContent()
{
GameObject firstGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "MainOptions", false, false, true, true, 3,
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(firstGroup, minHeight: 25, flexibleWidth: 9999);
//UIElements.Add(horiGroup);
ButtonRef updateAnimators = UIFactory.CreateButton(firstGroup, "RefreshAnimators", "Refresh Animators");
UIFactory.SetLayoutElement(updateAnimators.GameObject, minWidth: 150, minHeight: 25);
updateAnimators.OnClick += FindAllAnimators;
GameObject animatorObj = UIFactory.CreateToggle(firstGroup, $"Master Animation Toggle", out masterAnimatorToggle, out Text masterAnimatorText);
UIFactory.SetLayoutElement(animatorObj, minHeight: 25);
masterAnimatorToggle.isOn = true;
masterAnimatorToggle.onValueChanged.AddListener(value => MasterToggleAnimators(value));
masterAnimatorText.text = "Master Toggler";
GameObject secondGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "MainOptions", false, false, true, true, 3,
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(firstGroup, minHeight: 25, flexibleWidth: 9999);
Text isPlayerLabel = UIFactory.CreateLabel(secondGroup, "IsAffectedByMasterToggler", "Ignores Master Toggler", TextAnchor.MiddleLeft, Color.white, false, 15);
UIFactory.SetLayoutElement(isPlayerLabel.gameObject, minHeight: 25, minWidth: 25, flexibleWidth: 0);
Text enableLabel = UIFactory.CreateLabel(secondGroup, "EnableLabel", "Enable ", TextAnchor.MiddleRight, Color.white, false, 15);
UIFactory.SetLayoutElement(enableLabel.gameObject, minHeight: 25, minWidth: 75, flexibleWidth: 9999);
}
}
}
+2 -1
View File
@@ -358,7 +358,8 @@ namespace UnityExplorer.UI.Panels
(supportedInput ? $"- {ConfigManager.Toggle_Block_Games_Input.Value}: Toggle games input on Freecam\n" : "") +
$"- {ConfigManager.HUD_Toggle.Value}: HUD toggle\n" +
$"- {ConfigManager.Pause.Value}: Pause\n" +
$"- {ConfigManager.Frameskip.Value}: Frameskip\n";
$"- {ConfigManager.Frameskip.Value}: Frameskip\n" +
$"- {ConfigManager.Toggle_Animations.Value}: Toggle NPC animations";
if (ConfigManager.Frameskip.Value != KeyCode.None) instructions = instructions + $"- {ConfigManager.Screenshot.Value}: Screenshot\n";
+3 -1
View File
@@ -26,6 +26,7 @@ namespace UnityExplorer.UI
LightsManager,
CamPaths,
PostProcessingPanel,
AnimatorPanel,
Misc,
}
@@ -48,7 +49,7 @@ namespace UnityExplorer.UI
public static RectTransform NavBarRect;
public static GameObject NavbarTabButtonHolder;
private static readonly Vector2 NAVBAR_DIMENSIONS = new(1500f, 35f);
private static readonly Vector2 NAVBAR_DIMENSIONS = new(1600f, 35f);
private static ButtonRef closeBtn;
private static TimeScaleWidget timeScaleWidget;
@@ -99,6 +100,7 @@ namespace UnityExplorer.UI
UIPanels.Add(Panels.LightsManager, new LightsManager(UiBase));
UIPanels.Add(Panels.CamPaths, new CamPaths(UiBase));
UIPanels.Add(Panels.PostProcessingPanel, new PostProcessingPanel(UiBase));
UIPanels.Add(Panels.AnimatorPanel, new AnimatorPanel(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));