Add option to match avatar write defaults settings (#41)

This commit is contained in:
bd_ 2022-10-02 19:08:23 -07:00
parent ca19f86347
commit 20742b7e45
3 changed files with 67 additions and 5 deletions

View File

@ -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<AnimatorStateMachine>();
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<string, AnimatorStateMachine>(basePath, layerStateMachine);

View File

@ -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<VRCAvatarDescriptor.AnimLayerType, AnimatorController> defaultControllers_ =
new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController>();
private Dictionary<VRCAvatarDescriptor.AnimLayerType, bool?> writeDefaults_ =
new Dictionary<VRCAvatarDescriptor.AnimLayerType, bool?>();
Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner> mergeSessions =
new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner>();
@ -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<AnimatorStateMachine>();
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)
{

View File

@ -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;
}
}