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; return _combined;
} }
public void AddController(String basePath, AnimatorController controller) public void AddController(string basePath, AnimatorController controller, bool? writeDefaults)
{ {
foreach (var param in controller.parameters) foreach (var param in controller.parameters)
{ {
@ -80,12 +80,12 @@ namespace net.fushizen.modular_avatar.core.editor
bool first = true; bool first = true;
foreach (var layer in controller.layers) foreach (var layer in controller.layers)
{ {
insertLayer(basePath, layer, first); insertLayer(basePath, layer, first, writeDefaults);
first = false; 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() var newLayer = new AnimatorControllerLayer()
{ {
@ -99,9 +99,32 @@ namespace net.fushizen.modular_avatar.core.editor
stateMachine = mapStateMachine(basePath, layer.stateMachine), stateMachine = mapStateMachine(basePath, layer.stateMachine),
}; };
UpdateWriteDefaults(newLayer.stateMachine, writeDefaults);
_layers.Add(newLayer); _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) private AnimatorStateMachine mapStateMachine(string basePath, AnimatorStateMachine layerStateMachine)
{ {
var cacheKey = new KeyValuePair<string, AnimatorStateMachine>(basePath, layerStateMachine); var cacheKey = new KeyValuePair<string, AnimatorStateMachine>(basePath, layerStateMachine);

View File

@ -22,11 +22,13 @@
* SOFTWARE. * SOFTWARE.
*/ */
using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEditor; using UnityEditor;
using UnityEditor.Animations; using UnityEditor.Animations;
using UnityEngine; using UnityEngine;
using VRC.SDK3.Avatars.Components; using VRC.SDK3.Avatars.Components;
using Object = UnityEngine.Object;
namespace net.fushizen.modular_avatar.core.editor namespace net.fushizen.modular_avatar.core.editor
{ {
@ -40,6 +42,9 @@ namespace net.fushizen.modular_avatar.core.editor
private Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController> defaultControllers_ = private Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController> defaultControllers_ =
new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController>(); new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController>();
private Dictionary<VRCAvatarDescriptor.AnimLayerType, bool?> writeDefaults_ =
new Dictionary<VRCAvatarDescriptor.AnimLayerType, bool?>();
Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner> mergeSessions = Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner> mergeSessions =
new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner>(); new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner>();
@ -76,11 +81,13 @@ namespace net.fushizen.modular_avatar.core.editor
mergeSessions[merge.layerType] = session; mergeSessions[merge.layerType] = session;
if (defaultControllers_.ContainsKey(merge.layerType)) 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) if (merge.deleteAttachedAnimator)
{ {
@ -119,9 +126,40 @@ namespace net.fushizen.modular_avatar.core.editor
if (controller == null) controller = new AnimatorController(); if (controller == null) controller = new AnimatorController();
defaultControllers_[layer.type] = controller; 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) private static AnimatorController ResolveLayerController(VRCAvatarDescriptor.CustomAnimLayer layer)
{ {

View File

@ -39,5 +39,6 @@ namespace net.fushizen.modular_avatar.core
public VRCAvatarDescriptor.AnimLayerType layerType; public VRCAvatarDescriptor.AnimLayerType layerType;
public bool deleteAttachedAnimator; public bool deleteAttachedAnimator;
public MergeAnimatorPathMode pathMode = MergeAnimatorPathMode.Relative; public MergeAnimatorPathMode pathMode = MergeAnimatorPathMode.Relative;
public bool matchAvatarWriteDefaults;
} }
} }