From af2ad057fbf5567ad897c7f083cd5f430fefae4b Mon Sep 17 00:00:00 2001 From: originalnicodr Date: Thu, 20 Jun 2024 18:30:31 -0300 Subject: [PATCH] Added mesh togglers for each bone, added non-bone meshes to the BoneManager, captured multiple skinnedMeshRenderers, and restored the mesh scale when enabling the animator again. --- src/Cinematic/Cells/AnimatorCell.cs | 3 +-- src/Cinematic/Cells/AnimatorPlayer.cs | 33 +++++++++++++++++++++++---- src/Cinematic/Cells/BonesCell.cs | 17 ++++++++++---- src/UI/Panels/AnimatorPanel.cs | 2 +- src/UI/Panels/BonesPanel.cs | 13 ++++++++++- 5 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/Cinematic/Cells/AnimatorCell.cs b/src/Cinematic/Cells/AnimatorCell.cs index 51a9abe..d7d6252 100644 --- a/src/Cinematic/Cells/AnimatorCell.cs +++ b/src/Cinematic/Cells/AnimatorCell.cs @@ -43,7 +43,6 @@ namespace UnityExplorer.UI.Panels inspectButton.ButtonText.text = animatorPlayer.animator.name; IgnoreMasterToggle.isOn = animatorPlayer.shouldIgnoreMasterToggle; AnimatorToggle.isOn = animatorPlayer.animator.speed != 0; - MeshToggle.isOn = animatorPlayer.skinnedMesh.enabled; UpdateDropdownOptions(); } @@ -195,7 +194,7 @@ namespace UnityExplorer.UI.Panels } internal void EnableMesh(bool value){ - animatorPlayer.skinnedMesh.enabled = value; + animatorPlayer.SetMeshesEnabled(value); } } } diff --git a/src/Cinematic/Cells/AnimatorPlayer.cs b/src/Cinematic/Cells/AnimatorPlayer.cs index 255c3cb..4e77c06 100644 --- a/src/Cinematic/Cells/AnimatorPlayer.cs +++ b/src/Cinematic/Cells/AnimatorPlayer.cs @@ -22,7 +22,8 @@ namespace UnityExplorer.UI.Panels BonesManager bonesManager; private List bones = new List(); - public SkinnedMeshRenderer skinnedMesh; + private List skinnedMeshes = new(); + private List extraMeshes = new(); public IAnimationClip overridingAnimation; private IAnimationClip lastCurrentAnimation; @@ -46,7 +47,9 @@ namespace UnityExplorer.UI.Panels this.overridingAnimation = lastCurrentAnimation != null ? lastCurrentAnimation : (animations.Count > 0 ? animations[0] : null); this.favAnimations = new List(); - this.skinnedMesh = this.animator.wrappedObject.gameObject.GetComponentInChildren(); + + this.skinnedMeshes.AddRange(this.animator.wrappedObject.gameObject.GetComponentsInChildren(false)); + this.extraMeshes.AddRange(this.animator.wrappedObject.gameObject.GetComponentsInChildren(false)); } // Include the animations being played in other layers @@ -122,13 +125,35 @@ namespace UnityExplorer.UI.Panels } } + private List GetMeshes(){ + List meshes = new List(); + + foreach (SkinnedMeshRenderer skinnedMesh in skinnedMeshes) { + meshes.AddRange(skinnedMesh.bones); + } + meshes.AddRange(extraMeshes.Select(m => m.transform)); + + return meshes.GroupBy(b => b.name).Select(b => b.First()).ToList().OrderBy(b => b.name).ToList(); + } + public void OpenBonesPanel(){ - if (skinnedMesh == null) return; + if (skinnedMeshes.Count == 0 && extraMeshes.Count == 0) return; if (bonesManager == null){ - bonesManager = new BonesManager(UIManager.GetPanel(UIManager.Panels.AnimatorPanel).Owner, new List(skinnedMesh.bones), animator); + bonesManager = new BonesManager(UIManager.GetPanel(UIManager.Panels.AnimatorPanel).Owner, GetMeshes(), animator); } bonesManager.SetActive(true); } + + public void SetMeshesEnabled(bool value){ + PropertyInfo enabledProperty = typeof(SkinnedMeshRenderer).GetProperty("enabled"); + foreach (SkinnedMeshRenderer skinnedMesh in skinnedMeshes) { + enabledProperty.SetValue(skinnedMesh, value, null); + } + + foreach (MeshRenderer meshRenderer in extraMeshes) { + meshRenderer.enabled = value; + } + } } public class IAnimator diff --git a/src/Cinematic/Cells/BonesCell.cs b/src/Cinematic/Cells/BonesCell.cs index 3de1719..26357ec 100644 --- a/src/Cinematic/Cells/BonesCell.cs +++ b/src/Cinematic/Cells/BonesCell.cs @@ -11,12 +11,12 @@ namespace UnityExplorer.UI.Panels public Transform bone; public TransformControls transformControls; - Text boneName; ComponentControl positionControl; ComponentControl rotationControl; ComponentControl scaleControl; public AxisComponentControl CurrentSlidingAxisControl { get; set; } public BonesManager Owner; + private ButtonRef inspectButton; // ICell public float DefaultHeight => 25f; @@ -29,7 +29,7 @@ namespace UnityExplorer.UI.Panels public void SetBone(Transform bone, BonesManager bonesManager){ this.bone = bone; - boneName.text = bone.name; + inspectButton.ButtonText.text = bone.name; Owner = bonesManager; } @@ -44,8 +44,13 @@ namespace UnityExplorer.UI.Panels UIFactory.SetLayoutGroup(header, false, false, true, true, 4, childAlignment: TextAnchor.MiddleLeft); UIFactory.SetLayoutElement(header, minHeight: 25, flexibleWidth: 9999, flexibleHeight: 800); - boneName = UIFactory.CreateLabel(header, "BoneLabel", ""); - UIFactory.SetLayoutElement(boneName.gameObject, minWidth: 100, minHeight: 25); + GameObject MeshToggleObj = UIFactory.CreateToggle(header, "MeshToggle", out Toggle MeshToggle, out Text MeshToggleText); + UIFactory.SetLayoutElement(MeshToggleObj, minHeight: 30); + MeshToggle.onValueChanged.AddListener(SetBoneEnabled); + + inspectButton = UIFactory.CreateButton(header, "InspectButton", ""); + UIFactory.SetLayoutElement(inspectButton.GameObject, minWidth: 150, minHeight: 25); + inspectButton.OnClick += () => InspectorManager.Inspect(bone.gameObject); GameObject headerButtons = UIFactory.CreateUIObject("BoneHeader", header); UIFactory.SetLayoutGroup(headerButtons, false, false, true, true, 4, childAlignment: TextAnchor.MiddleRight); @@ -66,6 +71,10 @@ namespace UnityExplorer.UI.Panels Owner.RestoreBoneState(bone.name); } + private void SetBoneEnabled(bool value){ + bone.gameObject.SetActive(value); + } + // TransformControls-like functions public void UpdateTransformControlValues(bool force){ positionControl.Update(force); diff --git a/src/UI/Panels/AnimatorPanel.cs b/src/UI/Panels/AnimatorPanel.cs index c5bff0e..dc7b279 100644 --- a/src/UI/Panels/AnimatorPanel.cs +++ b/src/UI/Panels/AnimatorPanel.cs @@ -112,7 +112,7 @@ namespace UnityExplorer.UI.Panels foreach (AnimatorPlayer animatorPlayer in animators){ if (!animatorPlayer.shouldIgnoreMasterToggle){ - animatorPlayer.skinnedMesh.enabled = enable; + animatorPlayer.SetMeshesEnabled(enable); } } diff --git a/src/UI/Panels/BonesPanel.cs b/src/UI/Panels/BonesPanel.cs index 41100b0..29fb88e 100644 --- a/src/UI/Panels/BonesPanel.cs +++ b/src/UI/Panels/BonesPanel.cs @@ -59,7 +59,18 @@ namespace UnityExplorer.UI.Panels private void OnTurnOffAnimatorToggle(bool value) { - if (!value){ + if (value){ + // Restore meshes manually in case some are not part of a skeleton and won't get restored automatically. + // Besides, this restores the scale, which the animator doesn't. + foreach (Transform bone in bones){ + CachedBonesTransform CachedBonesTransform = bonesOriginalState[bone.name]; + bone.localPosition = CachedBonesTransform.position; + bone.localEulerAngles = CachedBonesTransform.angles; + bone.localScale = CachedBonesTransform.scale; + // We assume these were on before. If not we should save its state beforehand. + bone.gameObject.SetEnabled(true); + } + } else { bonesOriginalState.Clear(); foreach (Transform bone in bones){ bonesOriginalState[bone.name] = new CachedBonesTransform(bone.localPosition, bone.localEulerAngles, bone.localScale);