(BREAKING) Add AnimatorAsCode V1:
- Breaking changes: - Remove dependency to VRChat in the AnimatorAsCode.V1 namespace. The namespace should now be usable in non-VRChat projects. - All VRChat-specific methods are now extension functions in a separate namespace, AnimatorAsCode.V1.VRC. - VRChat methods that modify existing assets are split into a separate namespace, AnimatorAsCode.V1.VRCDestructiveWorkflow. - Breaking fixes: - Fix incorrect type signature on AacFlFloatParameterGroup.ToList() and AacFlIntParameterGroup.ToList(). - Add AacFlBase.NewBlendTree(): - This allows creating blend trees as code. - Add AacFlState.WithAnimation(AacFlBlendTree). - Add AacFlBase.NoAnimator(): - This can be used to obtain AacFlParameter objects for use in the generation of BlendTrees and other systems, without requiring the existence of a backing animator controller. - This can also be used in some cases where there are type casts (Bool to Float, Float to Bool). - Add AacFlBase.NewAnimatorController(): - This is meant to be used for non-destructive workflows. - This creates an animator controller inside the asset container. This animator controller will be reaped in the same way as other assets are reaped.
This commit is contained in:
+245
-106
@@ -16,6 +16,19 @@ namespace AnimatorAsCode.V1
|
||||
return new AacFlBase(configuration);
|
||||
}
|
||||
|
||||
internal static AnimatorController NewAnimatorController(AacConfiguration component, string suffix)
|
||||
{
|
||||
return RegisterAnimatorController(component, suffix, new AnimatorController());
|
||||
}
|
||||
|
||||
internal static AnimatorController RegisterAnimatorController(AacConfiguration component, string suffix, AnimatorController animatorController)
|
||||
{
|
||||
animatorController.name = "zAutogenerated__" + component.AssetKey + "__" + suffix + "_" + Random.Range(0, Int32.MaxValue); // FIXME animation name conflict
|
||||
animatorController.hideFlags = HideFlags.None;
|
||||
AssetDatabase.AddObjectToAsset(animatorController, component.AssetContainer);
|
||||
return animatorController;
|
||||
}
|
||||
|
||||
internal static AnimationClip NewClip(AacConfiguration component, string suffix)
|
||||
{
|
||||
return RegisterClip(component, suffix, new AnimationClip());
|
||||
@@ -77,6 +90,8 @@ namespace AnimatorAsCode.V1
|
||||
public struct AacConfiguration
|
||||
{
|
||||
public string SystemName;
|
||||
// Please consult "MigratingFromV0ToV1.md" on how to migrate this property
|
||||
// public VRCAvatarDescriptor AvatarDescriptor;
|
||||
public Transform AnimatorRoot;
|
||||
public Transform DefaultValueRoot;
|
||||
public AnimatorController AssetContainer;
|
||||
@@ -157,19 +172,18 @@ namespace AnimatorAsCode.V1
|
||||
return _stateMachine.EntryTransitionsTo(destination);
|
||||
}
|
||||
|
||||
public AacFlBoolParameter BoolParameter(string parameterName) => _stateMachine.BackingAnimator().BoolParameter(parameterName);
|
||||
public AacFlBoolParameter TriggerParameterAsBool(string parameterName) => _stateMachine.BackingAnimator().TriggerParameter(parameterName);
|
||||
public AacFlFloatParameter FloatParameter(string parameterName) => _stateMachine.BackingAnimator().FloatParameter(parameterName);
|
||||
public AacFlIntParameter IntParameter(string parameterName) => _stateMachine.BackingAnimator().IntParameter(parameterName);
|
||||
public AacFlBoolParameterGroup BoolParameters(params string[] parameterNames) => _stateMachine.BackingAnimator().BoolParameters(parameterNames);
|
||||
public AacFlBoolParameterGroup TriggerParametersAsBools(params string[] parameterNames) => _stateMachine.BackingAnimator().TriggerParameters(parameterNames);
|
||||
public AacFlFloatParameterGroup FloatParameters(params string[] parameterNames) => _stateMachine.BackingAnimator().FloatParameters(parameterNames);
|
||||
public AacFlIntParameterGroup IntParameters(params string[] parameterNames) => _stateMachine.BackingAnimator().IntParameters(parameterNames);
|
||||
public AacFlBoolParameterGroup BoolParameters(params AacFlBoolParameter[] parameters) => _stateMachine.BackingAnimator().BoolParameters(parameters);
|
||||
public AacFlBoolParameterGroup TriggerParametersAsBools(params AacFlBoolParameter[] parameters) => _stateMachine.BackingAnimator().TriggerParameters(parameters);
|
||||
public AacFlFloatParameterGroup FloatParameters(params AacFlFloatParameter[] parameters) => _stateMachine.BackingAnimator().FloatParameters(parameters);
|
||||
public AacFlIntParameterGroup IntParameters(params AacFlIntParameter[] parameters) => _stateMachine.BackingAnimator().IntParameters(parameters);
|
||||
public AacAv3 Av3() => new AacAv3(_stateMachine.BackingAnimator());
|
||||
public AacFlBoolParameter BoolParameter(string parameterName) => _stateMachine.InternalBackingAnimator().BoolParameter(parameterName);
|
||||
public AacFlBoolParameter TriggerParameterAsBool(string parameterName) => _stateMachine.InternalBackingAnimator().TriggerParameter(parameterName);
|
||||
public AacFlFloatParameter FloatParameter(string parameterName) => _stateMachine.InternalBackingAnimator().FloatParameter(parameterName);
|
||||
public AacFlIntParameter IntParameter(string parameterName) => _stateMachine.InternalBackingAnimator().IntParameter(parameterName);
|
||||
public AacFlBoolParameterGroup BoolParameters(params string[] parameterNames) => _stateMachine.InternalBackingAnimator().BoolParameters(parameterNames);
|
||||
public AacFlBoolParameterGroup TriggerParametersAsBools(params string[] parameterNames) => _stateMachine.InternalBackingAnimator().TriggerParameters(parameterNames);
|
||||
public AacFlFloatParameterGroup FloatParameters(params string[] parameterNames) => _stateMachine.InternalBackingAnimator().FloatParameters(parameterNames);
|
||||
public AacFlIntParameterGroup IntParameters(params string[] parameterNames) => _stateMachine.InternalBackingAnimator().IntParameters(parameterNames);
|
||||
public AacFlBoolParameterGroup BoolParameters(params AacFlBoolParameter[] parameters) => _stateMachine.InternalBackingAnimator().BoolParameters(parameters);
|
||||
public AacFlBoolParameterGroup TriggerParametersAsBools(params AacFlBoolParameter[] parameters) => _stateMachine.InternalBackingAnimator().TriggerParameters(parameters);
|
||||
public AacFlFloatParameterGroup FloatParameters(params AacFlFloatParameter[] parameters) => _stateMachine.InternalBackingAnimator().FloatParameters(parameters);
|
||||
public AacFlIntParameterGroup IntParameters(params AacFlIntParameter[] parameters) => _stateMachine.InternalBackingAnimator().IntParameters(parameters);
|
||||
|
||||
public AacFlLayer OverrideValue(AacFlBoolParameter toBeForced, bool value)
|
||||
{
|
||||
@@ -285,6 +299,11 @@ namespace AnimatorAsCode.V1
|
||||
_stateMachine.WithDefaultState(newDefaultState);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AacFlStateMachine InternalStateMachine()
|
||||
{
|
||||
return _stateMachine;
|
||||
}
|
||||
}
|
||||
|
||||
public class AacFlBase
|
||||
@@ -313,6 +332,11 @@ namespace AnimatorAsCode.V1
|
||||
var clip = AacV1.RegisterClip(_configuration, Guid.NewGuid().ToString(), newClip);
|
||||
return new AacFlClip(_configuration, clip);
|
||||
}
|
||||
|
||||
public AacFlNonInitializedBlendTree NewBlendTree()
|
||||
{
|
||||
return new AacFlNonInitializedBlendTree(AacV1.NewBlendTreeAsRaw(_configuration, Guid.NewGuid().ToString()));
|
||||
}
|
||||
|
||||
public BlendTree NewBlendTreeAsRaw()
|
||||
{
|
||||
@@ -353,6 +377,18 @@ namespace AnimatorAsCode.V1
|
||||
.WithUnit(unit, keyframes => keyframes.Constant(0, 0f).Constant(duration, 0f)));
|
||||
}
|
||||
|
||||
public AacFlController NewAnimatorController()
|
||||
{
|
||||
var animatorController = AacV1.NewAnimatorController(_configuration, Guid.NewGuid().ToString());
|
||||
return new AacFlController(_configuration, animatorController, this);
|
||||
}
|
||||
|
||||
public AacFlController NewAnimatorController(string name)
|
||||
{
|
||||
var animatorController = AacV1.NewAnimatorController(_configuration, name);
|
||||
return new AacFlController(_configuration, animatorController, this);
|
||||
}
|
||||
|
||||
public AacFlLayer CreateMainArbitraryControllerLayer(AnimatorController controller) => InternalDoCreateLayer(controller, _configuration.DefaultsProvider.ConvertLayerName(_configuration.SystemName));
|
||||
public AacFlLayer CreateSupportingArbitraryControllerLayer(AnimatorController controller, string suffix) => InternalDoCreateLayer(controller, _configuration.DefaultsProvider.ConvertLayerNameWithSuffix(_configuration.SystemName, suffix));
|
||||
public AacFlLayer CreateFirstArbitraryControllerLayer(AnimatorController controller) => InternalDoCreateLayer(controller, controller.layers[0].name);
|
||||
@@ -365,17 +401,20 @@ namespace AnimatorAsCode.V1
|
||||
return new AacFlLayer(animator, _configuration, machine, layerName);
|
||||
}
|
||||
|
||||
internal AacFlLayer DoCreateLayerWithoutDeleting(AnimatorController animator, string layerName)
|
||||
{
|
||||
var ag = new AacAnimatorGenerator(animator, CreateEmptyClip().Clip, _configuration.DefaultsProvider);
|
||||
var machine = ag.CreateOrClearLayerAtSameIndex(layerName, 1f, null, false);
|
||||
|
||||
return new AacFlLayer(animator, _configuration, machine, layerName);
|
||||
}
|
||||
|
||||
private AacFlClip CreateEmptyClip()
|
||||
{
|
||||
var emptyClip = AnomalousSingleKeyframeClip();
|
||||
return emptyClip;
|
||||
}
|
||||
|
||||
public AacVrcAssetLibrary VrcAssets()
|
||||
{
|
||||
return new AacVrcAssetLibrary();
|
||||
}
|
||||
|
||||
public void ClearPreviousAssets()
|
||||
{
|
||||
var allSubAssets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(_configuration.AssetContainer));
|
||||
@@ -388,113 +427,209 @@ namespace AnimatorAsCode.V1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AacAv3
|
||||
{
|
||||
private readonly AacBackingAnimator _backingAnimator;
|
||||
|
||||
internal AacAv3(AacBackingAnimator backingAnimator)
|
||||
public AacFlNoAnimator NoAnimator()
|
||||
{
|
||||
_backingAnimator = backingAnimator;
|
||||
}
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
public AacFlBoolParameter IsLocal => _backingAnimator.BoolParameter("IsLocal");
|
||||
public AacFlEnumIntParameter<Av3Viseme> Viseme => _backingAnimator.EnumParameter<Av3Viseme>("Viseme");
|
||||
public AacFlEnumIntParameter<Av3Gesture> GestureLeft => _backingAnimator.EnumParameter<Av3Gesture>("GestureLeft");
|
||||
public AacFlEnumIntParameter<Av3Gesture> GestureRight => _backingAnimator.EnumParameter<Av3Gesture>("GestureRight");
|
||||
public AacFlFloatParameter GestureLeftWeight => _backingAnimator.FloatParameter("GestureLeftWeight");
|
||||
public AacFlFloatParameter GestureRightWeight => _backingAnimator.FloatParameter("GestureRightWeight");
|
||||
public AacFlFloatParameter AngularY => _backingAnimator.FloatParameter("AngularY");
|
||||
public AacFlFloatParameter VelocityX => _backingAnimator.FloatParameter("VelocityX");
|
||||
public AacFlFloatParameter VelocityY => _backingAnimator.FloatParameter("VelocityY");
|
||||
public AacFlFloatParameter VelocityZ => _backingAnimator.FloatParameter("VelocityZ");
|
||||
public AacFlFloatParameter Upright => _backingAnimator.FloatParameter("Upright");
|
||||
public AacFlBoolParameter Grounded => _backingAnimator.BoolParameter("Grounded");
|
||||
public AacFlBoolParameter Seated => _backingAnimator.BoolParameter("Seated");
|
||||
public AacFlBoolParameter AFK => _backingAnimator.BoolParameter("AFK");
|
||||
public AacFlIntParameter TrackingType => _backingAnimator.IntParameter("TrackingType");
|
||||
public AacFlIntParameter VRMode => _backingAnimator.IntParameter("VRMode");
|
||||
public AacFlBoolParameter MuteSelf => _backingAnimator.BoolParameter("MuteSelf");
|
||||
public AacFlBoolParameter InStation => _backingAnimator.BoolParameter("InStation");
|
||||
public AacFlFloatParameter Voice => _backingAnimator.FloatParameter("Voice");
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
public IAacFlCondition ItIsRemote() => IsLocal.IsFalse();
|
||||
public IAacFlCondition ItIsLocal() => IsLocal.IsTrue();
|
||||
|
||||
public enum Av3Gesture
|
||||
{
|
||||
// Specify all the values explicitly because they should be dictated by VRChat, not enumeration order.
|
||||
Neutral = 0,
|
||||
Fist = 1,
|
||||
HandOpen = 2,
|
||||
Fingerpoint = 3,
|
||||
Victory = 4,
|
||||
RockNRoll = 5,
|
||||
HandGun = 6,
|
||||
ThumbsUp = 7
|
||||
}
|
||||
|
||||
public enum Av3Viseme
|
||||
{
|
||||
// Specify all the values explicitly because they should be dictated by VRChat, not enumeration order.
|
||||
// ReSharper disable InconsistentNaming
|
||||
sil = 0,
|
||||
pp = 1,
|
||||
ff = 2,
|
||||
th = 3,
|
||||
dd = 4,
|
||||
kk = 5,
|
||||
ch = 6,
|
||||
ss = 7,
|
||||
nn = 8,
|
||||
rr = 9,
|
||||
aa = 10,
|
||||
e = 11,
|
||||
ih = 12,
|
||||
oh = 13,
|
||||
ou = 14
|
||||
// ReSharper restore InconsistentNaming
|
||||
return new AacFlNoAnimator();
|
||||
}
|
||||
}
|
||||
|
||||
public class AacVrcAssetLibrary
|
||||
public class AacFlNoAnimator
|
||||
{
|
||||
public AvatarMask LeftHandAvatarMask()
|
||||
public AacFlFloatParameter FloatParameter(string parameterName) => AacFlFloatParameter.Internally(parameterName);
|
||||
public AacFlIntParameter IntParameter(string parameterName) => AacFlIntParameter.Internally(parameterName);
|
||||
public AacFlBoolParameter BoolParameter(string parameterName) => AacFlBoolParameter.Internally(parameterName);
|
||||
}
|
||||
|
||||
public class AacFlBlendTree
|
||||
{
|
||||
protected AacFlBlendTree(BlendTree blendTree)
|
||||
{
|
||||
return AssetDatabase.LoadAssetAtPath<AvatarMask>("Packages/com.vrchat.avatars/Samples/AV3 Demo Assets/Animation/Masks/vrc_Hand Left.mask");
|
||||
BlendTree = blendTree;
|
||||
}
|
||||
|
||||
public AvatarMask RightHandAvatarMask()
|
||||
public BlendTree BlendTree { get; }
|
||||
}
|
||||
|
||||
public class AacFlNonInitializedBlendTree : AacFlBlendTree
|
||||
{
|
||||
public AacFlNonInitializedBlendTree(BlendTree blendTree) : base(blendTree)
|
||||
{
|
||||
return AssetDatabase.LoadAssetAtPath<AvatarMask>("Packages/com.vrchat.avatars/Samples/AV3 Demo Assets/Animation/Masks/vrc_Hand Right.mask");
|
||||
}
|
||||
|
||||
public AnimationClip ProxyForGesture(AacAv3.Av3Gesture gesture, bool masculine)
|
||||
public AacFlBlendTree2D FreeformCartesian(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY)
|
||||
{
|
||||
return AssetDatabase.LoadAssetAtPath<AnimationClip>("Packages/com.vrchat.avatars/Samples/AV3 Demo Assets/Animation/ProxyAnim/" + ResolveProxyFilename(gesture, masculine));
|
||||
BlendTree.blendType = BlendTreeType.FreeformCartesian2D;
|
||||
BlendTree.blendParameter = parameterX.Name;
|
||||
BlendTree.blendParameterY = parameterY.Name;
|
||||
|
||||
return new AacFlBlendTree2D(BlendTree);
|
||||
}
|
||||
|
||||
private static string ResolveProxyFilename(AacAv3.Av3Gesture gesture, bool masculine)
|
||||
public AacFlBlendTree2D FreeformDirectional(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY)
|
||||
{
|
||||
switch (gesture)
|
||||
BlendTree.blendType = BlendTreeType.FreeformDirectional2D;
|
||||
BlendTree.blendParameter = parameterX.Name;
|
||||
BlendTree.blendParameterY = parameterY.Name;
|
||||
|
||||
return new AacFlBlendTree2D(BlendTree);
|
||||
}
|
||||
|
||||
public AacFlBlendTree2D SimpleDirectional(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY)
|
||||
{
|
||||
BlendTree.blendType = BlendTreeType.SimpleDirectional2D;
|
||||
BlendTree.blendParameter = parameterX.Name;
|
||||
BlendTree.blendParameterY = parameterY.Name;
|
||||
|
||||
return new AacFlBlendTree2D(BlendTree);
|
||||
}
|
||||
|
||||
public AacFlBlendTree1D Simple(AacFlFloatParameter parameter)
|
||||
{
|
||||
BlendTree.blendType = BlendTreeType.Simple1D;
|
||||
BlendTree.blendParameter = parameter.Name;
|
||||
BlendTree.useAutomaticThresholds = false;
|
||||
|
||||
return new AacFlBlendTree1D(BlendTree);
|
||||
}
|
||||
|
||||
public AacFlBlendTreeDirect Direct()
|
||||
{
|
||||
BlendTree.blendType = BlendTreeType.Direct;
|
||||
|
||||
return new AacFlBlendTreeDirect(BlendTree);
|
||||
}
|
||||
}
|
||||
|
||||
public class AacFlBlendTree2D : AacFlBlendTree
|
||||
{
|
||||
public AacFlBlendTree2D(BlendTree blendTree) : base(blendTree)
|
||||
{
|
||||
}
|
||||
|
||||
public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, Vector2 pos)
|
||||
{
|
||||
return WithAnimation(blendTree.BlendTree, pos);
|
||||
}
|
||||
|
||||
public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, float x, float y)
|
||||
{
|
||||
return WithAnimation(blendTree.BlendTree, x, y);
|
||||
}
|
||||
|
||||
public AacFlBlendTree2D WithAnimation(AacFlClip clip, Vector2 pos)
|
||||
{
|
||||
return WithAnimation(clip.Clip, pos);
|
||||
}
|
||||
|
||||
public AacFlBlendTree2D WithAnimation(AacFlClip clip, float x, float y)
|
||||
{
|
||||
return WithAnimation(clip.Clip, x, y);
|
||||
}
|
||||
|
||||
public AacFlBlendTree2D WithAnimation(Motion motion, Vector2 pos)
|
||||
{
|
||||
return WithAnimation(motion, pos.x, pos.y);
|
||||
}
|
||||
|
||||
public AacFlBlendTree2D WithAnimation(Motion motion, float x, float y)
|
||||
{
|
||||
var children = BlendTree.children ?? new ChildMotion[0];
|
||||
var childrenList = children.ToList();
|
||||
childrenList.Add(new ChildMotion
|
||||
{
|
||||
case AacAv3.Av3Gesture.Neutral: return masculine ? "proxy_hands_idle.anim" : "proxy_hands_idle2.anim";
|
||||
case AacAv3.Av3Gesture.Fist: return "proxy_hands_fist.anim";
|
||||
case AacAv3.Av3Gesture.HandOpen: return "proxy_hands_open.anim";
|
||||
case AacAv3.Av3Gesture.Fingerpoint: return "proxy_hands_point.anim";
|
||||
case AacAv3.Av3Gesture.Victory: return "proxy_hands_peace.anim";
|
||||
case AacAv3.Av3Gesture.RockNRoll: return "proxy_hands_rock.anim";
|
||||
case AacAv3.Av3Gesture.HandGun: return "proxy_hands_gun.anim";
|
||||
case AacAv3.Av3Gesture.ThumbsUp: return "proxy_hands_thumbs_up.anim";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(gesture), gesture, null);
|
||||
}
|
||||
motion = motion,
|
||||
position = new Vector2(x, y),
|
||||
timeScale = 1f
|
||||
});
|
||||
BlendTree.children = childrenList.ToArray();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class AacFlBlendTree1D : AacFlBlendTree
|
||||
{
|
||||
public AacFlBlendTree1D(BlendTree blendTree) : base(blendTree)
|
||||
{
|
||||
}
|
||||
|
||||
public AacFlBlendTree1D WithAnimation(AacFlClip clip, float threshold)
|
||||
{
|
||||
return WithAnimation(clip.Clip, threshold);
|
||||
}
|
||||
|
||||
public AacFlBlendTree1D WithAnimation(AacFlBlendTree blendTree, float threshold)
|
||||
{
|
||||
return WithAnimation(blendTree.BlendTree, threshold);
|
||||
}
|
||||
|
||||
public AacFlBlendTree1D WithAnimation(Motion motion, float threshold)
|
||||
{
|
||||
var children = BlendTree.children ?? new ChildMotion[0];
|
||||
var childrenList = children.ToList();
|
||||
childrenList.Add(new ChildMotion
|
||||
{
|
||||
motion = motion,
|
||||
threshold = threshold,
|
||||
timeScale = 1f
|
||||
});
|
||||
BlendTree.children = childrenList.ToArray();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class AacFlBlendTreeDirect : AacFlBlendTree
|
||||
{
|
||||
public AacFlBlendTreeDirect(BlendTree blendTree) : base(blendTree)
|
||||
{
|
||||
}
|
||||
|
||||
public AacFlBlendTreeDirect WithAnimation(AacFlClip clip, AacFlFloatParameter parameter)
|
||||
{
|
||||
return WithAnimation(clip.Clip, parameter);
|
||||
}
|
||||
|
||||
public AacFlBlendTreeDirect WithAnimation(AacFlBlendTree blendTree, AacFlFloatParameter parameter)
|
||||
{
|
||||
return WithAnimation(blendTree.BlendTree, parameter);
|
||||
}
|
||||
|
||||
public AacFlBlendTreeDirect WithAnimation(Motion motion, AacFlFloatParameter parameter)
|
||||
{
|
||||
var children = BlendTree.children ?? new ChildMotion[0];
|
||||
var childrenList = children.ToList();
|
||||
childrenList.Add(new ChildMotion
|
||||
{
|
||||
motion = motion,
|
||||
directBlendParameter = parameter.Name,
|
||||
timeScale = 1f
|
||||
});
|
||||
BlendTree.children = childrenList.ToArray();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class AacFlController
|
||||
{
|
||||
public AnimatorController AnimatorController;
|
||||
|
||||
private readonly AacConfiguration _configuration;
|
||||
private readonly AacFlBase _base;
|
||||
|
||||
public AacFlController(AacConfiguration configuration, AnimatorController animatorController, AacFlBase originalBase)
|
||||
{
|
||||
AnimatorController = animatorController;
|
||||
_configuration = configuration;
|
||||
_base = originalBase;
|
||||
}
|
||||
|
||||
public AacFlLayer CreateLayer(string suffix) => _base.DoCreateLayerWithoutDeleting(AnimatorController, _configuration.DefaultsProvider.ConvertLayerNameWithSuffix(_configuration.SystemName, suffix));
|
||||
public AacFlLayer CreateLayer() => _base.DoCreateLayerWithoutDeleting(AnimatorController, _configuration.SystemName);
|
||||
}
|
||||
|
||||
public class AacAnimatorRemoval
|
||||
{
|
||||
private readonly AnimatorController _animatorController;
|
||||
@@ -592,11 +727,15 @@ namespace AnimatorAsCode.V1
|
||||
.WithExitPosition(7, -1);
|
||||
}
|
||||
|
||||
internal AacFlStateMachine CreateOrClearLayerAtSameIndex(string layerName, float weightWhenCreating, AvatarMask maskWhenCreating = null)
|
||||
internal AacFlStateMachine CreateOrClearLayerAtSameIndex(string layerName, float weightWhenCreating, AvatarMask maskWhenCreating = null, bool allowDeletion = true)
|
||||
{
|
||||
var originalIndexToPreserveOrdering = FindIndexOf(layerName);
|
||||
if (originalIndexToPreserveOrdering != -1)
|
||||
{
|
||||
if (!allowDeletion)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot create layer with name {layerName} as it already exists. When creating layers using NewAnimatorController, you may only use unique names.");
|
||||
}
|
||||
RecursivelyClearChildrenMachines(_animatorController.layers[originalIndexToPreserveOrdering].stateMachine);
|
||||
|
||||
_animatorController.layers[originalIndexToPreserveOrdering].stateMachine.stateMachines = new ChildAnimatorStateMachine[0];
|
||||
|
||||
Reference in New Issue
Block a user