From 20742b7e4531959604fb1a8343e2ba58db8f8202 Mon Sep 17 00:00:00 2001 From: bd_ Date: Sun, 2 Oct 2022 19:08:23 -0700 Subject: [PATCH] Add option to match avatar write defaults settings (#41) --- .../Editor/AnimatorMerger.cs | 29 +++++++++++-- .../Editor/MergeAnimatorProcessor.cs | 42 ++++++++++++++++++- .../Runtime/ModularAvatarMergeAnimator.cs | 1 + 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/Packages/net.fushizen.modular-avatar/Editor/AnimatorMerger.cs b/Packages/net.fushizen.modular-avatar/Editor/AnimatorMerger.cs index e51bd09c..9db2fdba 100644 --- a/Packages/net.fushizen.modular-avatar/Editor/AnimatorMerger.cs +++ b/Packages/net.fushizen.modular-avatar/Editor/AnimatorMerger.cs @@ -59,7 +59,7 @@ namespace net.fushizen.modular_avatar.core.editor return _combined; } - public void AddController(String basePath, AnimatorController controller) + public void AddController(string basePath, AnimatorController controller, bool? writeDefaults) { foreach (var param in controller.parameters) { @@ -80,12 +80,12 @@ namespace net.fushizen.modular_avatar.core.editor bool first = true; foreach (var layer in controller.layers) { - insertLayer(basePath, layer, first); + insertLayer(basePath, layer, first, writeDefaults); first = false; } } - private void insertLayer(string basePath, AnimatorControllerLayer layer, bool first) + private void insertLayer(string basePath, AnimatorControllerLayer layer, bool first, bool? writeDefaults) { var newLayer = new AnimatorControllerLayer() { @@ -99,9 +99,32 @@ namespace net.fushizen.modular_avatar.core.editor stateMachine = mapStateMachine(basePath, layer.stateMachine), }; + UpdateWriteDefaults(newLayer.stateMachine, writeDefaults); + _layers.Add(newLayer); } + private void UpdateWriteDefaults(AnimatorStateMachine stateMachine, bool? writeDefaults) + { + if (!writeDefaults.HasValue) return; + + var queue = new Queue(); + queue.Enqueue(stateMachine); + while (queue.Count > 0) + { + var sm = queue.Dequeue(); + foreach (var state in sm.states) + { + state.state.writeDefaultValues = writeDefaults.Value; + } + + foreach (var child in sm.stateMachines) + { + queue.Enqueue(child.stateMachine); + } + } + } + private AnimatorStateMachine mapStateMachine(string basePath, AnimatorStateMachine layerStateMachine) { var cacheKey = new KeyValuePair(basePath, layerStateMachine); diff --git a/Packages/net.fushizen.modular-avatar/Editor/MergeAnimatorProcessor.cs b/Packages/net.fushizen.modular-avatar/Editor/MergeAnimatorProcessor.cs index d67b62ae..776ef557 100644 --- a/Packages/net.fushizen.modular-avatar/Editor/MergeAnimatorProcessor.cs +++ b/Packages/net.fushizen.modular-avatar/Editor/MergeAnimatorProcessor.cs @@ -22,11 +22,13 @@ * SOFTWARE. */ +using System; using System.Collections.Generic; using UnityEditor; using UnityEditor.Animations; using UnityEngine; using VRC.SDK3.Avatars.Components; +using Object = UnityEngine.Object; namespace net.fushizen.modular_avatar.core.editor { @@ -40,6 +42,9 @@ namespace net.fushizen.modular_avatar.core.editor private Dictionary defaultControllers_ = new Dictionary(); + private Dictionary writeDefaults_ = + new Dictionary(); + Dictionary mergeSessions = new Dictionary(); @@ -76,11 +81,13 @@ namespace net.fushizen.modular_avatar.core.editor mergeSessions[merge.layerType] = session; if (defaultControllers_.ContainsKey(merge.layerType)) { - session.AddController("", defaultControllers_[merge.layerType]); + session.AddController("", defaultControllers_[merge.layerType], null); } } - mergeSessions[merge.layerType].AddController(basePath, (AnimatorController) merge.animator); + bool? writeDefaults = merge.matchAvatarWriteDefaults ? writeDefaults_[merge.layerType] : null; + mergeSessions[merge.layerType] + .AddController(basePath, (AnimatorController) merge.animator, writeDefaults); if (merge.deleteAttachedAnimator) { @@ -119,9 +126,40 @@ namespace net.fushizen.modular_avatar.core.editor if (controller == null) controller = new AnimatorController(); defaultControllers_[layer.type] = controller; + writeDefaults_[layer.type] = ProbeWriteDefaults(controller); } } + private bool? ProbeWriteDefaults(AnimatorController controller) + { + bool hasWDOn = false; + bool hasWDOff = false; + + var stateMachineQueue = new Queue(); + foreach (var layer in controller.layers) + { + stateMachineQueue.Enqueue(layer.stateMachine); + } + + while (stateMachineQueue.Count > 0) + { + var stateMachine = stateMachineQueue.Dequeue(); + foreach (var state in stateMachine.states) + { + if (state.state.writeDefaultValues) hasWDOn = true; + else hasWDOff = true; + } + + foreach (var child in stateMachine.stateMachines) + { + stateMachineQueue.Enqueue(child.stateMachine); + } + } + + if (hasWDOn == hasWDOff) return null; + return hasWDOn; + } + private static AnimatorController ResolveLayerController(VRCAvatarDescriptor.CustomAnimLayer layer) { diff --git a/Packages/net.fushizen.modular-avatar/Runtime/ModularAvatarMergeAnimator.cs b/Packages/net.fushizen.modular-avatar/Runtime/ModularAvatarMergeAnimator.cs index 714dfc61..7c4672a4 100644 --- a/Packages/net.fushizen.modular-avatar/Runtime/ModularAvatarMergeAnimator.cs +++ b/Packages/net.fushizen.modular-avatar/Runtime/ModularAvatarMergeAnimator.cs @@ -39,5 +39,6 @@ namespace net.fushizen.modular_avatar.core public VRCAvatarDescriptor.AnimLayerType layerType; public bool deleteAttachedAnimator; public MergeAnimatorPathMode pathMode = MergeAnimatorPathMode.Relative; + public bool matchAvatarWriteDefaults; } } \ No newline at end of file