From 708bc6562faec4276ced7ea37dde09867a89e485 Mon Sep 17 00:00:00 2001 From: JLChnToZ Date: Tue, 22 Oct 2024 00:34:41 +0800 Subject: [PATCH] Fixes error when merging same parameter with different type in RC menu item. --- .../AnimationGeneration/ReactiveObjectPass.cs | 70 ++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs index ae77c80f..96c65365 100644 --- a/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs +++ b/Editor/ReactiveObjects/AnimationGeneration/ReactiveObjectPass.cs @@ -26,7 +26,10 @@ namespace nadena.dev.modular_avatar.core.editor private AnimationClip _initialStateClip; private bool _writeDefaults; - + + private AnimatorCombiner _combineSession; + private AnimatorController _animController; + public ReactiveObjectPass(ndmf.BuildContext context) { this.context = context; @@ -34,26 +37,37 @@ namespace nadena.dev.modular_avatar.core.editor internal void Execute() { + var fxController = FindFxController(); + // Having a WD OFF layer after WD ON layers can break WD. We match the behavior of the existing states, // and if mixed, use WD ON to maximize compatibility. - _writeDefaults = MergeAnimatorProcessor.ProbeWriteDefaults(FindFxController().animatorController as AnimatorController) ?? true; - + _writeDefaults = MergeAnimatorProcessor.ProbeWriteDefaults(fxController.animatorController as AnimatorController) ?? true; + + _combineSession = new AnimatorCombiner(context, fxController.animatorController != null ? fxController.animatorController.name : "FX (Reactive Objects)"); + _combineSession.AddController("", fxController.animatorController as AnimatorController, null); + _animController = new AnimatorController(); + var analysis = new ReactiveObjectAnalyzer(context).Analyze(context.AvatarRootObject); var shapes = analysis.Shapes; var initialStates = analysis.InitialStates; - + GenerateActiveSelfProxies(shapes); ProcessMeshDeletion(initialStates, shapes); ProcessInitialStates(initialStates, shapes); ProcessInitialAnimatorVariables(shapes); - + foreach (var groups in shapes.Values) { ProcessShapeKey(groups); } + + _combineSession.AddController("", _animController, null); + FinishCombineSession(); + Object.DestroyImmediate(_animController); // Cleanup + _combineSession = null; } private void GenerateActiveSelfProxies(Dictionary shapes) @@ -562,24 +576,7 @@ namespace nadena.dev.modular_avatar.core.editor private void ApplyController(AnimatorStateMachine asm, string layerName) { - var fx = FindFxController(); - - if (fx.animatorController == null) - { - throw new InvalidOperationException("No FX layer found"); - } - - if (!context.IsTemporaryAsset(fx.animatorController)) - { - throw new InvalidOperationException("FX layer is not a temporary asset"); - } - - if (!(fx.animatorController is AnimatorController animController)) - { - throw new InvalidOperationException("FX layer is not an animator controller"); - } - - var paramList = animController.parameters.ToList(); + var paramList = _animController.parameters.ToList(); var paramSet = paramList.Select(p => p.name).ToHashSet(); foreach (var paramName in initialValues.Keys.Except(paramSet)) @@ -593,9 +590,9 @@ namespace nadena.dev.modular_avatar.core.editor paramSet.Add(paramName); } - animController.parameters = paramList.ToArray(); + _animController.parameters = paramList.ToArray(); - animController.layers = animController.layers.Append( + _animController.layers = _animController.layers.Append( new AnimatorControllerLayer { stateMachine = asm, @@ -612,6 +609,29 @@ namespace nadena.dev.modular_avatar.core.editor return fx; } + + private void FinishCombineSession() + { + for (int i = 0; i < context.AvatarDescriptor.baseAnimationLayers.Length; i++) + { + if (context.AvatarDescriptor.baseAnimationLayers[i].type == VRCAvatarDescriptor.AnimLayerType.FX) + { + context.AvatarDescriptor.baseAnimationLayers[i].animatorController = _combineSession.Finish(); + return; + } + } + + // When we don't have an FX layer, we create one. + context.AvatarDescriptor.baseAnimationLayers = context.AvatarDescriptor.baseAnimationLayers.Append( + new VRCAvatarDescriptor.CustomAnimLayer + { + type = VRCAvatarDescriptor.AnimLayerType.FX, + isDefault = false, + isEnabled = true, + animatorController = _combineSession.Finish(), + } + ).ToArray(); + } } }