mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 18:55:06 +08:00
feat: delay GameObjects turning OFF by one frame, when they control ShapeChangers (#934)
Closes: #918
This commit is contained in:
parent
0bc64eb755
commit
d8e01234f0
@ -299,12 +299,12 @@ namespace nadena.dev.modular_avatar.animation
|
|||||||
_pathToClip = new Dictionary<string, HashSet<ClipHolder>>();
|
_pathToClip = new Dictionary<string, HashSet<ClipHolder>>();
|
||||||
foreach (var clip in _clips)
|
foreach (var clip in _clips)
|
||||||
{
|
{
|
||||||
recordPaths(clip);
|
RecordPaths(clip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordPaths(ClipHolder holder)
|
private void RecordPaths(ClipHolder holder)
|
||||||
{
|
{
|
||||||
var clip = holder.GetCurrentClipUnsafe() as AnimationClip;
|
var clip = holder.GetCurrentClipUnsafe() as AnimationClip;
|
||||||
|
|
||||||
|
@ -84,6 +84,8 @@ namespace nadena.dev.modular_avatar.animation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(EditorCurveBinding, string)> BoundReadableProperties => _readableProperty.BoundProperties;
|
||||||
|
|
||||||
// HACK: This is a temporary crutch until we rework the entire animator services system
|
// HACK: This is a temporary crutch until we rework the entire animator services system
|
||||||
public void AddPropertyDefinition(AnimatorControllerParameter paramDef)
|
public void AddPropertyDefinition(AnimatorControllerParameter paramDef)
|
||||||
{
|
{
|
||||||
|
75
Editor/Animation/GameObjectDisableDelayPass.cs
Normal file
75
Editor/Animation/GameObjectDisableDelayPass.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using nadena.dev.ndmf;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.Animations;
|
||||||
|
using UnityEngine;
|
||||||
|
using VRC.SDK3.Avatars.Components;
|
||||||
|
|
||||||
|
namespace nadena.dev.modular_avatar.animation
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This pass delays turning GameObjects OFF by one frame when those objects control a ReadableProperty. This
|
||||||
|
/// ensures that we don't expose hidden meshes when removing articles of clothing, for example.
|
||||||
|
/// </summary>
|
||||||
|
internal class GameObjectDelayDisablePass : Pass<GameObjectDelayDisablePass>
|
||||||
|
{
|
||||||
|
protected override void Execute(BuildContext context)
|
||||||
|
{
|
||||||
|
var asc = context.Extension<AnimationServicesContext>();
|
||||||
|
if (!asc.BoundReadableProperties.Any()) return;
|
||||||
|
|
||||||
|
var fx = (AnimatorController)context.AvatarDescriptor.baseAnimationLayers
|
||||||
|
.FirstOrDefault(l => l.type == VRCAvatarDescriptor.AnimLayerType.FX).animatorController;
|
||||||
|
|
||||||
|
if (fx == null) return;
|
||||||
|
|
||||||
|
var blendTree = new BlendTree();
|
||||||
|
blendTree.blendType = BlendTreeType.Direct;
|
||||||
|
blendTree.useAutomaticThresholds = false;
|
||||||
|
|
||||||
|
blendTree.children = asc.BoundReadableProperties.Select(GenerateDelayChild).ToArray();
|
||||||
|
|
||||||
|
var asm = new AnimatorStateMachine();
|
||||||
|
var state = new AnimatorState();
|
||||||
|
state.name = "DelayDisable";
|
||||||
|
state.motion = blendTree;
|
||||||
|
state.writeDefaultValues = true;
|
||||||
|
|
||||||
|
asm.defaultState = state;
|
||||||
|
asm.states = new[]
|
||||||
|
{
|
||||||
|
new ChildAnimatorState
|
||||||
|
{
|
||||||
|
state = state,
|
||||||
|
position = Vector3.zero
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fx.layers = fx.layers.Append(new AnimatorControllerLayer
|
||||||
|
{
|
||||||
|
name = "DelayDisable",
|
||||||
|
stateMachine = asm,
|
||||||
|
defaultWeight = 1,
|
||||||
|
blendingMode = AnimatorLayerBlendingMode.Override
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChildMotion GenerateDelayChild((EditorCurveBinding, string) binding)
|
||||||
|
{
|
||||||
|
var ecb = binding.Item1;
|
||||||
|
var prop = binding.Item2;
|
||||||
|
|
||||||
|
var motion = new AnimationClip();
|
||||||
|
var curve = new AnimationCurve();
|
||||||
|
curve.AddKey(0, 1);
|
||||||
|
AnimationUtility.SetEditorCurve(motion, ecb, curve);
|
||||||
|
|
||||||
|
return new ChildMotion
|
||||||
|
{
|
||||||
|
motion = motion,
|
||||||
|
directBlendParameter = prop,
|
||||||
|
timeScale = 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Editor/Animation/GameObjectDisableDelayPass.cs.meta
Normal file
3
Editor/Animation/GameObjectDisableDelayPass.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9b3eb561f76b459fbfbcf29fc4484261
|
||||||
|
timeCreated: 1722222066
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using nadena.dev.ndmf;
|
using nadena.dev.ndmf;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.Animations;
|
using UnityEditor.Animations;
|
||||||
@ -23,6 +24,9 @@ namespace nadena.dev.modular_avatar.animation
|
|||||||
_asc = asc;
|
_asc = asc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(EditorCurveBinding, string)> BoundProperties =>
|
||||||
|
_alreadyBound.Select(kv => (kv.Key, kv.Value));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an animator parameter which tracks the effective value of a property on a component. This only
|
/// Creates an animator parameter which tracks the effective value of a property on a component. This only
|
||||||
/// tracks FX layer properties.
|
/// tracks FX layer properties.
|
||||||
|
@ -69,6 +69,7 @@ namespace nadena.dev.modular_avatar.core.editor.plugin
|
|||||||
#if MA_VRCSDK3_AVATARS
|
#if MA_VRCSDK3_AVATARS
|
||||||
seq.Run(BlendshapeSyncAnimationPluginPass.Instance);
|
seq.Run(BlendshapeSyncAnimationPluginPass.Instance);
|
||||||
#endif
|
#endif
|
||||||
|
seq.Run(GameObjectDelayDisablePass.Instance);
|
||||||
});
|
});
|
||||||
#if MA_VRCSDK3_AVATARS
|
#if MA_VRCSDK3_AVATARS
|
||||||
seq.Run(PhysbonesBlockerPluginPass.Instance);
|
seq.Run(PhysbonesBlockerPluginPass.Instance);
|
||||||
|
Loading…
Reference in New Issue
Block a user