From 67782b5c8b654d1ba8446881a7d29705e4599691 Mon Sep 17 00:00:00 2001 From: originalnicodr Date: Wed, 13 Mar 2024 19:47:46 -0300 Subject: [PATCH] Fixed some animations not playing in npcs, stopped the game from switching animations when we were manually replacing them, improved the refresh animations feature, and added support for the animator for newer games. --- src/Cinematic/Cells/AnimatorCell.cs | 6 ++-- src/Cinematic/Cells/AnimatorPlayer.cs | 46 +++++++++++++++++++++++---- src/UI/Panels/AnimatorPanel.cs | 2 +- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/Cinematic/Cells/AnimatorCell.cs b/src/Cinematic/Cells/AnimatorCell.cs index 6eebca2..4fe0eda 100644 --- a/src/Cinematic/Cells/AnimatorCell.cs +++ b/src/Cinematic/Cells/AnimatorCell.cs @@ -65,14 +65,16 @@ namespace UnityExplorer.UI.Panels private void PlayButton_OnClick(){ animatorPlayer.PlayOverridingAnimation(); - // Turn the toggle on to play the animation - if (!AnimatorToggle.isOn) AnimatorToggle.isOn = true; + // Needed for the new animation to play for some reason + EnableAnimation(false); + EnableAnimation(true); } public virtual GameObject CreateContent(GameObject parent) { GameObject AnimatorToggleObj = UIFactory.CreateToggle(parent, $"AnimatorToggle", out AnimatorToggle, out Text animatorToggleText); UIFactory.SetLayoutElement(AnimatorToggleObj, minHeight: 25); + AnimatorToggle.isOn = animatorPlayer != null && animatorPlayer.animator.speed == 1; AnimatorToggle.onValueChanged.AddListener(EnableAnimation); UIRoot = AnimatorToggleObj; diff --git a/src/Cinematic/Cells/AnimatorPlayer.cs b/src/Cinematic/Cells/AnimatorPlayer.cs index 146b1af..3d17fef 100644 --- a/src/Cinematic/Cells/AnimatorPlayer.cs +++ b/src/Cinematic/Cells/AnimatorPlayer.cs @@ -54,6 +54,8 @@ namespace UnityExplorer.UI.Panels } public void ResetAnimation(){ + // Let the game change animations again + animator.StopPlayback(); if (originalAnimatorController != null && animator.wrappedObject != null){ if (animator.runtimeAnimatorController != null && originalAnimatorController != null){ animator.runtimeAnimatorController = originalAnimatorController; @@ -64,20 +66,24 @@ namespace UnityExplorer.UI.Panels } public void PlayOverridingAnimation(){ + ResetAnimation(); if (animatorOverrideController == null){ animatorOverrideController = new IAnimatorOverrideController(); animatorOverrideController.runtimeAnimatorController = originalAnimatorController; // Actually uses runtimeAnimatorController on the original object, should make the wrapper class a child of the runtimeAnimatorController instead animator.runtimeAnimatorControllerOverride = animatorOverrideController; + + // Block the game from changing animations + animator.StartPlayback(); } // Restore previous animation if (lastCurrentAnimation != null){ - animatorOverrideController[lastCurrentAnimation.name] = lastCurrentAnimation; + animatorOverrideController[lastCurrentAnimation] = lastCurrentAnimation; } IAnimationClip currentAnimation = animator.GetCurrentAnimatorClipInfo(0)[0].clip; - animatorOverrideController[currentAnimation.name] = overridingAnimation; + animatorOverrideController[currentAnimation] = overridingAnimation; animator.Play(currentAnimation.name); lastCurrentAnimation = currentAnimation; @@ -239,12 +245,22 @@ namespace UnityExplorer.UI.Panels return (GameObject) animatorGameObject.GetValue(_animator.TryCast(), null); } } + + public void StopPlayback(){ + MethodInfo StopPlayBackMethod = realType.GetMethod("StopPlayback", Type.EmptyTypes); + StopPlayBackMethod.Invoke(_animator.TryCast(), null); + } + + public void StartPlayback(){ + MethodInfo StartPlaybackMethod = realType.GetMethod("StartPlayback", Type.EmptyTypes); + StartPlaybackMethod.Invoke(_animator.TryCast(), null); + } } public class IAnimationClip : IEquatable { object _animationClip; - Type realType; + public Type realType; public object wrappedObject => _animationClip; public IAnimationClip(object animationClip){ @@ -414,17 +430,35 @@ namespace UnityExplorer.UI.Panels } } - public IAnimationClip this[string key] + public IAnimationClip this[IAnimationClip clip] { get { PropertyInfo indexerProperty = realType.GetProperty("Item", new[] { typeof(string) }); - return new IAnimationClip(indexerProperty.GetValue(_animatorOverrideController.TryCast(), new object[] { key })); + if (indexerProperty != null){ + return new IAnimationClip(indexerProperty.GetValue(_animatorOverrideController.TryCast(), new object[] { clip.name })); + } + + indexerProperty = realType.GetProperty("Item", new[] { clip.realType }); + if (indexerProperty != null){ + return new IAnimationClip(indexerProperty.GetValue(_animatorOverrideController.TryCast(), new object[] { clip.wrappedObject })); + } + + return null; } set { PropertyInfo indexerProperty = realType.GetProperty("Item", new[] { typeof(string) }); - indexerProperty.SetValue(_animatorOverrideController.TryCast(), value.wrappedObject.TryCast(), new object[] { key }); + if (indexerProperty != null){ + indexerProperty.SetValue(_animatorOverrideController.TryCast(), value.wrappedObject.TryCast(), new object[] { clip.name }); + return; + } + + indexerProperty = realType.GetProperty("Item", new[] { clip.realType }); + if (indexerProperty != null){ + indexerProperty.SetValue(_animatorOverrideController.TryCast(), value.wrappedObject.TryCast(), new object[] { clip.wrappedObject }); + return; + } } } } diff --git a/src/UI/Panels/AnimatorPanel.cs b/src/UI/Panels/AnimatorPanel.cs index bfa13b9..d7cc3f4 100644 --- a/src/UI/Panels/AnimatorPanel.cs +++ b/src/UI/Panels/AnimatorPanel.cs @@ -64,7 +64,7 @@ namespace UnityExplorer.UI.Panels Type searchType = ReflectionUtility.GetTypeByName("UnityEngine.Animator"); searchType = searchType is Type type ? type : searchType.GetActualType(); List newAnimators = RuntimeHelper.FindObjectsOfTypeAll(searchType).Select(obj => obj.TryCast()) - .Where(a => a.GetComponentsInChildren(false).Length != 0 && a.enabled && a.GetComponentsInChildren(false).Length != 0) + .Where(a => a.isActiveAndEnabled && (a.GetComponentsInChildren(false).Length != 0 || a.GetComponentsInChildren(false).Length != 0)) .OrderBy(x=>x.name) .Select(a => new AnimatorPlayer(a)) .ToList();