mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-04-04 03:29:02 +08:00
feat: support merging animation clips in Merge Blend Tree
This renames Merge Blend Tree to Merge Motion, and expands it to support arbitrary motions. Closes: #1438
This commit is contained in:
parent
04c3f10144
commit
7ce8363ae3
@ -2,6 +2,8 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.ScriptableObjects;
|
||||
@ -41,7 +43,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
|
||||
var parameters = context.AvatarDescriptor.expressionParameters.parameters
|
||||
?? new VRCExpressionParameters.Parameter[0];
|
||||
?? Array.Empty<VRCExpressionParameters.Parameter>();
|
||||
var parameterNames = parameters.Select(p => p.name).ToImmutableHashSet();
|
||||
|
||||
if (!context.PluginBuildContext.IsTemporaryAsset(expressionsMenu))
|
||||
|
@ -1,7 +1,7 @@
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
using static nadena.dev.modular_avatar.core.editor.Localization;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core.editor
|
||||
@ -15,7 +15,9 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
_blendTree = serializedObject.FindProperty(nameof(ModularAvatarMergeBlendTree.BlendTree));
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
_pathMode = serializedObject.FindProperty(nameof(ModularAvatarMergeBlendTree.PathMode));
|
||||
_relativePathRoot = serializedObject.FindProperty(nameof(ModularAvatarMergeBlendTree.RelativePathRoot));
|
||||
}
|
||||
@ -24,7 +26,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.ObjectField(_blendTree, typeof(BlendTree), G("merge_blend_tree.blend_tree"));
|
||||
EditorGUILayout.ObjectField(_blendTree, typeof(Motion), G("merge_blend_tree.motion"));
|
||||
EditorGUILayout.PropertyField(_pathMode, G("merge_blend_tree.path_mode"));
|
||||
if (_pathMode.enumValueIndex == (int) MergeAnimatorPathMode.Relative)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@
|
||||
"merge_armature.reset_pos.execute": "Do it!",
|
||||
"merge_armature.reset_pos.heuristic_scale": "Adjust outfit overall scale to match base avatar",
|
||||
"merge_armature.reset_pos.heuristic_scale.tooltip": "Will set the overall scale of the outfit as a whole based on armspan measurements. Recommended for setting up outfits.",
|
||||
"merge_blend_tree.blend_tree": "Blend Tree",
|
||||
"merge_blend_tree.motion": "Motion (or Blend Tree) to merge",
|
||||
"merge_blend_tree.path_mode": "Path Mode",
|
||||
"merge_blend_tree.path_mode.tooltip": "How to interpret paths in animations. Using relative mode lets you record animations from an animator on this object.",
|
||||
"merge_blend_tree.relative_path_root": "Relative Path Root",
|
||||
|
@ -2,23 +2,41 @@
|
||||
|
||||
using System;
|
||||
using API;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace nadena.dev.modular_avatar.core
|
||||
{
|
||||
[AddComponentMenu("Modular Avatar/MA Merge Blend Tree")]
|
||||
[AddComponentMenu("Modular Avatar/MA Merge Motion (Blend Tree)")]
|
||||
[HelpURL("https://modular-avatar.nadena.dev/docs/reference/merge-blend-tree?lang=auto")]
|
||||
public sealed class ModularAvatarMergeBlendTree : AvatarTagComponent, IVirtualizeMotion
|
||||
{
|
||||
internal static Func<ModularAvatarMergeBlendTree, object, string> GetMotionBasePathCallback
|
||||
= (_, _) => "";
|
||||
|
||||
// We can't actually reference a BlendTree here because it's not available when building a player build
|
||||
|
||||
// Previous versions of this component expected a BlendTree, which is not available in player builds, so this
|
||||
// field was made an Object. This can now become a Motion, but unfortunately that would be a breaking change.
|
||||
|
||||
/// <summary>
|
||||
/// The blend tree or other motion to merge.
|
||||
/// </summary>
|
||||
[Obsolete("Use Motion property instead; this field will be removed in 2.0")] [PublicAPI]
|
||||
public Object BlendTree;
|
||||
|
||||
[PublicAPI]
|
||||
public MergeAnimatorPathMode PathMode = MergeAnimatorPathMode.Relative;
|
||||
|
||||
[PublicAPI]
|
||||
public AvatarObjectReference RelativePathRoot = new AvatarObjectReference();
|
||||
|
||||
[PublicAPI]
|
||||
public Motion Motion
|
||||
{
|
||||
get => ((IVirtualizeMotion)this).Motion;
|
||||
set => ((IVirtualizeMotion)this).Motion = value;
|
||||
}
|
||||
|
||||
Motion IVirtualizeMotion.Motion
|
||||
{
|
||||
get => (Motion)BlendTree;
|
||||
|
@ -97,6 +97,28 @@ namespace modular_avatar_tests
|
||||
AnimationTestUtil.AssertAnimationHasPath(((BlendTree)motion.children[0].motion).children[0].motion as AnimationClip, "child2/a");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SupportsMergingMotions()
|
||||
{
|
||||
AnimationClip clip = new AnimationClip();
|
||||
clip.name = "test clip";
|
||||
|
||||
var root = CreateRoot("root");
|
||||
var c1 = CreateChild(root, "child1");
|
||||
var mergeComponent = c1.AddComponent<ModularAvatarMergeBlendTree>();
|
||||
mergeComponent.Motion = clip;
|
||||
mergeComponent.PathMode = MergeAnimatorPathMode.Relative;
|
||||
mergeComponent.RelativePathRoot.referencePath = "child2";
|
||||
CreateChild(c1, "a");
|
||||
|
||||
AvatarProcessor.ProcessAvatar(root);
|
||||
|
||||
var fx = findFxLayer(root, MergeBlendTreePass.BlendTreeLayerName);
|
||||
var motion = fx.stateMachine.states[0].state.motion as BlendTree;
|
||||
|
||||
Assert.IsTrue(motion!.children.Any(m => m.motion.name == clip.name));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergeOrderTest()
|
||||
{
|
||||
|
@ -1,32 +1,48 @@
|
||||
# Merge Blend Tree
|
||||
# Merge Motion (Blend Tree)
|
||||
|
||||

|
||||
|
||||
The merge blend tree component allows you to merge multiple blend trees into a single FX layer.
|
||||
The merge motion component allows you to merge multiple blend trees into a single FX layer.
|
||||
This is an advanced component that allows for building lower-overhead animators by merging multiple gimmicks into a
|
||||
single layer.
|
||||
It can also be used to set an animation that is always running.
|
||||
|
||||
:::info
|
||||
|
||||
Prior to 1.12, this component was called "Merge Blend Tree". In 1.12 it was expanded to support merging animation clips
|
||||
as well; as such the name was changed to "Merge Motion". Existing assets created using 1.11 or earlier's Merge Blend Tree
|
||||
will automatically be upgraded to use the new Merge Motion component.
|
||||
|
||||
For API compatibility purposes, this component is still internally called `ModularAvatarMergeBlendTree`.
|
||||
|
||||
:::
|
||||
|
||||
## When should I use it?
|
||||
|
||||
You should use Merge Blend Tree when you have a blend tree that you want to be always active on the avatar.
|
||||
You should use Merge Motion when you have a motion (animation clip or blend tree) that you want to be always active
|
||||
n the avatar.
|
||||
|
||||
## When shouldn't I use it?
|
||||
|
||||
You should not use Merge Blend Tree if you need to disable/enable the blend tree, or have control over motion time.
|
||||
You should not use Merge Motion if you need to disable/enable the Motion, or have control over motion time.
|
||||
|
||||
## Setting up Merge Blend Tree
|
||||
## Merging a Blend Tree
|
||||
|
||||
First, create a Blend Tree asset. You can do this by right clicking on the project window and selecting
|
||||
Create -> BlendTree.
|
||||
|
||||
Configure your blend tree as desired, then add a Merge Blend Tree component and specify the Blend Tree in the Blend
|
||||
Tree field.
|
||||
Configure your blend tree as desired, then add a Merge Motion component and specify the Blend Tree in the Motion
|
||||
field.
|
||||
|
||||
You can configure Path Mode and Relative Path Root similarly to Merge Animator; for more details, see the
|
||||
[Merge Animator documentation](merge-animator.md).
|
||||
|
||||
## How blend trees are merged
|
||||
## Merging animations
|
||||
|
||||
Simply put the animation in the "Motion (or Blend Tree) to merge" field. The animation will be constantly played.
|
||||
|
||||
## How motions are merged
|
||||
|
||||
Modular Avatar will create a new layer at the top of the FX controller. This layer will contain a single state, with
|
||||
Write Defaults on, and containing a Direct Blend Tree. Each merged blend tree will be attached to this Direct Blend
|
||||
Write Defaults on, and containing a Direct Blend Tree. Each merged motion will be attached to this Direct Blend
|
||||
Tree, with its parameter always set to one.
|
@ -1,19 +1,30 @@
|
||||
# Merge Blend Tree
|
||||
# Merge Motion (Blend Tree)
|
||||
|
||||

|
||||
|
||||
Merge Blend Treeは、複数のブレンドツリーを1つのFXレイヤーにマージすることができます。
|
||||
複数のギミックを1つのレイヤーにまとめて、負荷を低減するための高度なコンポーネントです。
|
||||
また、常に実行されるアニメーションを設定するためにも使用できます。
|
||||
|
||||
:::info
|
||||
|
||||
1.12以前では、このコンポーネントは「Merge Blend Tree」と呼ばれていました。1.12では、アニメーションクリップのマージにも
|
||||
対応するように拡張されたため、名前が「Merge Motion」に変更されました。1.11以前のMerge Blend Treeで作成された
|
||||
既存のアセットは、新しいMerge Motionコンポーネントを使用するように自動的にアップグレードされます。
|
||||
|
||||
なお、APIでは、互換性のためこのコンポーネントは引き続き`ModularAvatarMergeBlendTree`と呼ばれています。
|
||||
|
||||
:::
|
||||
|
||||
## いつ使うもの?
|
||||
|
||||
ブレンドツリーを常にアバターで稼働させたい場合に使います。
|
||||
常に再生させるモーション(アニメーションクリップ、またはブレンドツリー)を設定したい場合に、Merge Motionを使用してください。
|
||||
|
||||
## いつ使わないもの?
|
||||
|
||||
ブレンドツリーを無効にしたり、モーションタイムを制御したりする必要がある場合は、Merge Blend Treeを使わないでください。
|
||||
モーションを無効にしたり、モーションタイムを制御したりする必要がある場合は、Merge Motionを使わないでください。
|
||||
|
||||
## セットアップ方法
|
||||
## ブレンドツリーでのセットアップ方法
|
||||
|
||||
まず、ブレンドツリーのアセットを作成します。プロジェクトウィンドウで右クリックして、Create -> BlendTreeを選択してください。
|
||||
|
||||
@ -22,8 +33,12 @@ Merge Blend Treeは、複数のブレンドツリーを1つのFXレイヤーに
|
||||
パスモードと相対パスルートは、Merge Animatorと同様に設定できます。
|
||||
詳細は、[Merge Animatorのドキュメント](merge-animator.md)を参照してください。
|
||||
|
||||
## ブレンドツリーのマージ方法
|
||||
## アニメーションのマージ
|
||||
|
||||
アニメーションを「モーション(またはブレンドツリー)」フィールドに配置するだけです。アニメーションは常に再生されます。
|
||||
|
||||
## マージ方法について
|
||||
|
||||
Modular Avatarは、FXコントローラーの一番上に新しいレイヤーを作成します。
|
||||
このレイヤーには、Write Defaultsがオンになっている単一のステートが含まれています。
|
||||
マージされたブレンドツリーは、パラメーターが常に1に設定されているこのDirect Blend Treeに接続されます。
|
||||
マージされたモーションは、パラメーターが常に1に設定されているこのDirect Blend Treeに接続されます。
|
Loading…
x
Reference in New Issue
Block a user