Support absolute referenced animator merging (#22)

also fix a bug where only one animator per layer could be merged, oops.
This commit is contained in:
bd_ 2022-09-17 09:52:59 -07:00
parent 5455e0da87
commit 79be8774a9
2 changed files with 31 additions and 16 deletions

View File

@ -27,37 +27,49 @@ using UnityEditor;
using UnityEditor.Animations; using UnityEditor.Animations;
using UnityEngine; using UnityEngine;
using VRC.SDK3.Avatars.Components; using VRC.SDK3.Avatars.Components;
using VRC.SDKBase.Editor.BuildPipeline;
namespace net.fushizen.modular_avatar.core.editor namespace net.fushizen.modular_avatar.core.editor
{ {
internal class MergeAnimatorProcessor internal class MergeAnimatorProcessor
{ {
private const string SAMPLE_PATH_PACKAGE = "Packages/com.vrchat.avatars/Samples/AV3 Demo Assets/Animation/Controllers"; private const string SAMPLE_PATH_PACKAGE =
"Packages/com.vrchat.avatars/Samples/AV3 Demo Assets/Animation/Controllers";
private const string SAMPLE_PATH_LEGACY = "Assets/VRCSDK/Examples3/Animation/Controllers"; private const string SAMPLE_PATH_LEGACY = "Assets/VRCSDK/Examples3/Animation/Controllers";
private Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController> defaultControllers_ = private Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController> defaultControllers_ =
new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController>(); new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorController>();
Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner> mergeSessions = Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner> mergeSessions =
new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner>(); new Dictionary<VRCAvatarDescriptor.AnimLayerType, AnimatorCombiner>();
internal void OnPreprocessAvatar(GameObject avatarGameObject) internal void OnPreprocessAvatar(GameObject avatarGameObject)
{ {
defaultControllers_.Clear(); defaultControllers_.Clear();
mergeSessions.Clear(); mergeSessions.Clear();
var descriptor = avatarGameObject.GetComponent<VRCAvatarDescriptor>(); var descriptor = avatarGameObject.GetComponent<VRCAvatarDescriptor>();
InitSessions(descriptor.baseAnimationLayers); InitSessions(descriptor.baseAnimationLayers);
InitSessions(descriptor.specialAnimationLayers); InitSessions(descriptor.specialAnimationLayers);
var toMerge = avatarGameObject.transform.GetComponentsInChildren<ModularAvatarMergeAnimator>(true); var toMerge = avatarGameObject.transform.GetComponentsInChildren<ModularAvatarMergeAnimator>(true);
foreach (var merge in toMerge) foreach (var merge in toMerge)
{ {
if (merge.animator == null) continue; if (merge.animator == null) continue;
string basePath;
if (merge.pathMode == MergeAnimatorPathMode.Relative)
{
var relativePath = RuntimeUtil.RelativePath(avatarGameObject, merge.gameObject);
basePath = relativePath != "" ? relativePath + "/" : "";
}
else
{
basePath = "";
}
if (!mergeSessions.TryGetValue(merge.layerType, out var session)) if (!mergeSessions.TryGetValue(merge.layerType, out var session))
{ {
session = new AnimatorCombiner(); session = new AnimatorCombiner();
@ -66,13 +78,10 @@ namespace net.fushizen.modular_avatar.core.editor
{ {
session.AddController("", defaultControllers_[merge.layerType]); session.AddController("", defaultControllers_[merge.layerType]);
} }
var relativePath = RuntimeUtil.RelativePath(avatarGameObject, merge.gameObject);
mergeSessions[merge.layerType].AddController(
relativePath != "" ? relativePath + "/" : "",
(AnimatorController) merge.animator
);
} }
mergeSessions[merge.layerType].AddController(basePath, (AnimatorController) merge.animator);
if (merge.deleteAttachedAnimator) if (merge.deleteAttachedAnimator)
{ {
var animator = merge.GetComponent<Animator>(); var animator = merge.GetComponent<Animator>();
@ -95,7 +104,7 @@ namespace net.fushizen.modular_avatar.core.editor
if (mergeSessions.TryGetValue(layers[i].type, out var session)) if (mergeSessions.TryGetValue(layers[i].type, out var session))
{ {
layers[i].isDefault = false; layers[i].isDefault = false;
layers[i].animatorController = session.Finish(); layers[i].animatorController = session.Finish();
} }
} }
@ -108,12 +117,11 @@ namespace net.fushizen.modular_avatar.core.editor
{ {
var controller = ResolveLayerController(layer); var controller = ResolveLayerController(layer);
if (controller == null) controller = new AnimatorController(); if (controller == null) controller = new AnimatorController();
defaultControllers_[layer.type] = controller; defaultControllers_[layer.type] = controller;
} }
} }
private static AnimatorController ResolveLayerController(VRCAvatarDescriptor.CustomAnimLayer layer) private static AnimatorController ResolveLayerController(VRCAvatarDescriptor.CustomAnimLayer layer)
{ {

View File

@ -27,10 +27,17 @@ using VRC.SDK3.Avatars.Components;
namespace net.fushizen.modular_avatar.core namespace net.fushizen.modular_avatar.core
{ {
public enum MergeAnimatorPathMode
{
Relative,
Absolute
}
public class ModularAvatarMergeAnimator : AvatarTagComponent public class ModularAvatarMergeAnimator : AvatarTagComponent
{ {
public RuntimeAnimatorController animator; public RuntimeAnimatorController animator;
public VRCAvatarDescriptor.AnimLayerType layerType; public VRCAvatarDescriptor.AnimLayerType layerType;
public bool deleteAttachedAnimator; public bool deleteAttachedAnimator;
public MergeAnimatorPathMode pathMode = MergeAnimatorPathMode.Relative;
} }
} }