Do a pass on the documentation:

- Add and update inline documentation.
- Mark some inconsistencies.
- Not everything is reviewed yet.
This commit is contained in:
Haï~
2024-07-01 23:16:51 +02:00
parent c54c377202
commit e50ea684a5
7 changed files with 238 additions and 55 deletions
@@ -9,6 +9,15 @@ using Object = UnityEngine.Object;
// ReSharper disable once CheckNamespace // ReSharper disable once CheckNamespace
namespace AnimatorAsCode.V1 namespace AnimatorAsCode.V1
{ {
/// Starter class for Animator As Code V1. Call this to obtain an instance of AacFlBase.<br/><br/>
/// The intent of the namespace AnimatorAsCode.V1, and the class AacV1,
/// is to allow Animator As Code V1 to be simultaneously installed inside projects where:<br/>
/// - Instances of Animator As Code V0 may exist,<br/>
/// - Instances of Animator As Code V1 derivatives may exist,<br/>
/// - Future instances of Animator As Code V2 might exist.<br/><br/>
/// For this reason, in case of a breaking change, there should be different versions of Animator As Code released
/// with a different package name, namespace, and initializer class name, so that the user may install dependencies
/// that rely on different versions of Animator As Code in the same project.
public static class AacV1 public static class AacV1
{ {
/// Create an Animator As Code (AAC) base. /// Create an Animator As Code (AAC) base.
@@ -20,18 +29,28 @@ namespace AnimatorAsCode.V1
public struct AacConfiguration public struct AacConfiguration
{ {
/// A name that will be used as the prefix of all animators layers created.
public string SystemName; public string SystemName;
// Please consult "https://docs.hai-vr.dev/docs/products/animator-as-code/migrating-v0-to-v1" on how to migrate this property // Please consult "https://docs.hai-vr.dev/docs/products/animator-as-code/migrating-v0-to-v1" on how to migrate this property
// public VRCAvatarDescriptor AvatarDescriptor; // public VRCAvatarDescriptor AvatarDescriptor;
/// A reference to the animator root. All relative paths will be made relative to this animator root.
public Transform AnimatorRoot; public Transform AnimatorRoot;
/// Unused. A reference to a root, where default values will be sampled from.
public Transform DefaultValueRoot; public Transform DefaultValueRoot;
/// A persistent asset where all created assets will be added into, based on the value of ContainerMode.
public Object AssetContainer; public Object AssetContainer;
/// Defines whether created assets should be added to the AssetContainer.
public Container ContainerMode; public Container ContainerMode;
/// A prefix which will be used in name of all assets, so that the created assets can be removed during subsequent executions of AnimatorAsCode, assuming that your process is destructive.
public string AssetKey; public string AssetKey;
/// An object that will provide default values. When in doubt, use `new AacDefaultsProvider(...)`
public IAacDefaultsProvider DefaultsProvider; public IAacDefaultsProvider DefaultsProvider;
private Dictionary<Type, object> _additionalData; // Nullable private Dictionary<Type, object> _additionalData; // Nullable
/// For use by users of extension functions: Store additional data in this configuration.<br/>
/// This additional data can be used during the operation of those extension functions.<br/>
/// Example: Use this to store a reference to a platform-specific avatar component.
public AacConfiguration WithAdditionalData<T>(T value) public AacConfiguration WithAdditionalData<T>(T value)
{ {
var conf = this; var conf = this;
@@ -40,6 +59,8 @@ namespace AnimatorAsCode.V1
return conf; return conf;
} }
/// Attempts to retrieve additional data stored by `WithAdditionalData`.<br/>
/// Returns true when such data is available.
public bool TryGetAdditionalData<T>(out T value) where T : class public bool TryGetAdditionalData<T>(out T value) where T : class
{ {
if (_additionalData != null && _additionalData.TryGetValue(typeof(T), out var result)) if (_additionalData != null && _additionalData.TryGetValue(typeof(T), out var result))
@@ -64,14 +85,20 @@ namespace AnimatorAsCode.V1
public enum Container public enum Container
{ {
/// Store all created assets in the AssetContainer.
Everything, Everything,
/// Only store created assets in the AssetContainer if that asset requires persistence.<br/>
/// Right now, only AnimatorController assets require persistence.
OnlyWhenPersistenceRequired, OnlyWhenPersistenceRequired,
/// Do not store any assets in the AssetContainer.<br/>
/// In this case, the value provided in the AssetContainer of the configuration does not matter.
Never Never
} }
} }
public class AacFlLayer public class AacFlLayer
{ {
/// Exposes the underlying AnimatorAsCode StateMachine object of this layer.
public AacFlStateMachine StateMachine => _stateMachine; public AacFlStateMachine StateMachine => _stateMachine;
private readonly AnimatorController _animatorController; private readonly AnimatorController _animatorController;
@@ -94,7 +121,8 @@ namespace AnimatorAsCode.V1
_stateMachine = stateMachine; _stateMachine = stateMachine;
} }
/// Create a new state, initially positioned below the last generated state of this layer. /// Create a new state, initially positioned below the last generated state of this layer.<br/>
/// 🔺 If the name is already used, a number will be appended at the end.
public AacFlState NewState(string name) public AacFlState NewState(string name)
{ {
var lastState = _stateMachine.LastNodePosition(); var lastState = _stateMachine.LastNodePosition();
@@ -102,19 +130,22 @@ namespace AnimatorAsCode.V1
return state; return state;
} }
/// Create a new state at a specific position x and y, in grid units. The grid size is defined in the DefaultsProvider of the AacConfiguration of AAC. x positive goes right, y positive goes down. /// Create a new state at a specific position x and y, in grid units. The grid size is defined in the DefaultsProvider of the AacConfiguration of AAC. x positive goes right, y positive goes down.<br/>
/// 🔺 If the name is already used, a number will be appended at the end.
public AacFlState NewState(string name, int x, int y) public AacFlState NewState(string name, int x, int y)
{ {
return _stateMachine.NewState(name, x, y); return _stateMachine.NewState(name, x, y);
} }
/// Create a new SSM, initially positioned below the last generated state of this layer. /// Create a new state machine, initially positioned below the last generated state of this layer.<br/>
/// 🔺 If the name is already used, a number will be appended at the end.
public AacFlStateMachine NewSubStateMachine(string name) public AacFlStateMachine NewSubStateMachine(string name)
{ {
return _stateMachine.NewSubStateMachine(name); return _stateMachine.NewSubStateMachine(name);
} }
/// Create a new SSM at a specific position `x` and `y`, in grid units. The grid size is defined in the DefaultsProvider of the AacConfiguration of AAC. `x` positive goes right, `y` positive goes down. /// Create a new state machine at a specific position `x` and `y`, in grid units. The grid size is defined in the DefaultsProvider of the AacConfiguration of AAC. `x` positive goes right, `y` positive goes down.<br/>
/// 🔺 If the name is already used, a number will be appended at the end.
public AacFlStateMachine NewSubStateMachine(string name, int x, int y) public AacFlStateMachine NewSubStateMachine(string name, int x, int y)
{ {
return _stateMachine.NewSubStateMachine(name, x, y); return _stateMachine.NewSubStateMachine(name, x, y);
@@ -126,7 +157,7 @@ namespace AnimatorAsCode.V1
return _stateMachine.AnyTransitionsTo(destination); return _stateMachine.AnyTransitionsTo(destination);
} }
/// Create a transition from Any to the `destination` SSM. /// Create a transition from Any to the `destination` state machine.
public AacFlTransition AnyTransitionsTo(AacFlStateMachine destination) public AacFlTransition AnyTransitionsTo(AacFlStateMachine destination)
{ {
return _stateMachine.AnyTransitionsTo(destination); return _stateMachine.AnyTransitionsTo(destination);
@@ -348,7 +379,8 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// NON-PUBLIC: Internal use only so that extensions can access this. Maybe this can be improved /// <b>FOR USE ONLY BY EXTENSION FUNCTIONS:</b><br/>
/// Exposes the internal state machine.
public AacFlStateMachine InternalStateMachine() public AacFlStateMachine InternalStateMachine()
{ {
return _stateMachine; return _stateMachine;
@@ -589,7 +621,7 @@ namespace AnimatorAsCode.V1
return AacFlFloatParameter.Internally(parameterName); return AacFlFloatParameter.Internally(parameterName);
} }
/// Create a Int parameter, for use without a backing animator. /// Create an Int parameter, for use without a backing animator.
public AacFlIntParameter IntParameter(string parameterName) public AacFlIntParameter IntParameter(string parameterName)
{ {
_intParameters.Add(parameterName); _intParameters.Add(parameterName);
@@ -649,6 +681,7 @@ namespace AnimatorAsCode.V1
public class AacFlController public class AacFlController
{ {
/// Exposes the underlying Unity AnimatorController.
public AnimatorController AnimatorController; public AnimatorController AnimatorController;
private readonly AacConfiguration _configuration; private readonly AacConfiguration _configuration;
@@ -661,10 +694,15 @@ namespace AnimatorAsCode.V1
_base = originalBase; _base = originalBase;
} }
/// Create a new layer with a specific suffix. You cannot create multiple layers with the same suffix on the same controller.
public AacFlLayer NewLayer(string suffix) => _base.DoCreateLayerWithoutDeleting(AnimatorController, _configuration.DefaultsProvider.ConvertLayerNameWithSuffix(_configuration.SystemName, suffix)); public AacFlLayer NewLayer(string suffix) => _base.DoCreateLayerWithoutDeleting(AnimatorController, _configuration.DefaultsProvider.ConvertLayerNameWithSuffix(_configuration.SystemName, suffix));
/// Create a new layer. You cannot invoke this method multiple times on the same controller.
public AacFlLayer NewLayer() => _base.DoCreateLayerWithoutDeleting(AnimatorController, _configuration.SystemName); public AacFlLayer NewLayer() => _base.DoCreateLayerWithoutDeleting(AnimatorController, _configuration.SystemName);
} }
/// Removes animators from an animator controller.<br/>
/// This class is exposed for use by extension functions that need to remove layers.
public class AacAnimatorRemoval public class AacAnimatorRemoval
{ {
private readonly AnimatorController _animatorController; private readonly AnimatorController _animatorController;
@@ -674,6 +712,7 @@ namespace AnimatorAsCode.V1
_animatorController = animatorController; _animatorController = animatorController;
} }
/// Remove a single layer having that exact name.
public void RemoveLayer(string layerName) public void RemoveLayer(string layerName)
{ {
var index = FindIndexOf(layerName); var index = FindIndexOf(layerName);
@@ -1,3 +1,4 @@
using System;
using UnityEngine; using UnityEngine;
// ReSharper disable once CheckNamespace // ReSharper disable once CheckNamespace
@@ -22,22 +23,38 @@ namespace AnimatorAsCode.V1
AnimatorRoot = animatorRoot; AnimatorRoot = animatorRoot;
} }
/// Move the node the left of the other node in the graph.
public TNode LeftOf(AacAnimatorNode otherNode) => MoveNextTo(otherNode, -1, 0); public TNode LeftOf(AacAnimatorNode otherNode) => MoveNextTo(otherNode, -1, 0);
/// Move the node the right of the other node in the graph.
public TNode RightOf(AacAnimatorNode otherNode) => MoveNextTo(otherNode, 1, 0); public TNode RightOf(AacAnimatorNode otherNode) => MoveNextTo(otherNode, 1, 0);
/// Move the node to be over the other node in the graph.
public TNode Over(AacAnimatorNode otherNode) => MoveNextTo(otherNode, 0, -1); public TNode Over(AacAnimatorNode otherNode) => MoveNextTo(otherNode, 0, -1);
/// Move the node to be under the other node in the graph.
public TNode Under(AacAnimatorNode otherNode) => MoveNextTo(otherNode, 0, 1); public TNode Under(AacAnimatorNode otherNode) => MoveNextTo(otherNode, 0, 1);
/// Move the node to the left of the last created node of the state machine this belongs to in the graph.
public TNode LeftOf() => MoveNextTo(null, -1, 0); public TNode LeftOf() => MoveNextTo(null, -1, 0);
/// Move the node to the right of the last created node of the state machine this belongs to in the graph.
public TNode RightOf() => MoveNextTo(null, 1, 0); public TNode RightOf() => MoveNextTo(null, 1, 0);
/// Move the node to be over the last created node of the state machine this belongs to in the graph.
public TNode Over() => MoveNextTo(null, 0, -1); public TNode Over() => MoveNextTo(null, 0, -1);
/// Move the node to be under the last created node of the state machine this belongs to in the graph.
public TNode Under() => MoveNextTo(null, 0, 1); public TNode Under() => MoveNextTo(null, 0, 1);
/// Move the node to be at a specific position in grid units, where x positive goes right, and y positive goes down.
public TNode At(int x, int y) public TNode At(int x, int y)
{ {
SetPosition(new Vector3(x * DefaultsProvider.Grid().x, y * DefaultsProvider.Grid().y, 0)); SetPosition(new Vector3(x * DefaultsProvider.Grid().x, y * DefaultsProvider.Grid().y, 0));
return (TNode) this; return (TNode) this;
} }
/// Move the state to be shifted next to the other state in the graph, in grid units. shiftX positive goes right, shiftY positive goes down.
public TNode Shift(AacAnimatorNode otherState, int shiftX, int shiftY) => MoveNextTo(otherState, shiftX, shiftY); public TNode Shift(AacAnimatorNode otherState, int shiftX, int shiftY) => MoveNextTo(otherState, shiftX, shiftY);
private TNode MoveNextTo(AacAnimatorNode otherStateOrSecondToLastWhenNull, int x, int y) private TNode MoveNextTo(AacAnimatorNode otherStateOrSecondToLastWhenNull, int x, int y)
@@ -55,20 +72,25 @@ namespace AnimatorAsCode.V1
return (TNode) this; return (TNode) this;
} }
// FIXME API: Vector3 is really odd as a type.
/// Given another position in non-grid units, move the state to be shifted next to that position, in grid units. shiftX positive goes right, shiftY positive goes down.
public TNode Shift(Vector3 otherPosition, int shiftX, int shiftY) public TNode Shift(Vector3 otherPosition, int shiftX, int shiftY)
{ {
SetPosition(otherPosition + new Vector3(shiftX * DefaultsProvider.Grid().x, shiftY * DefaultsProvider.Grid().y, 0)); SetPosition(otherPosition + new Vector3(shiftX * DefaultsProvider.Grid().x, shiftY * DefaultsProvider.Grid().y, 0));
return (TNode) this; return (TNode) this;
} }
/// Resolve the path of an item relative to the AnimatorRoot.
public string ResolveRelativePath(Transform item) public string ResolveRelativePath(Transform item)
{ {
return AacInternals.ResolveRelativePath(AnimatorRoot, item); return AacInternals.ResolveRelativePath(AnimatorRoot, item);
} }
/// Create a behaviour of the given type if it doesn't exist, or returns the first behaviour of that type.
public abstract TBehaviour EnsureBehaviour<TBehaviour>() where TBehaviour : StateMachineBehaviour; public abstract TBehaviour EnsureBehaviour<TBehaviour>() where TBehaviour : StateMachineBehaviour;
/// Create a behaviour of the given type.
public abstract TBehaviour CreateNewBehaviour<TBehaviour>() where TBehaviour : StateMachineBehaviour; public abstract TBehaviour CreateNewBehaviour<TBehaviour>() where TBehaviour : StateMachineBehaviour;
} }
} }
@@ -11,6 +11,8 @@ namespace AnimatorAsCode.V1
public class AacFlClip public class AacFlClip
{ {
private readonly AacConfiguration _component; private readonly AacConfiguration _component;
/// Exposes the underlying Unity Clip asset.
public AnimationClip Clip { get; } public AnimationClip Clip { get; }
public AacFlClip(AacConfiguration component, AnimationClip clip) public AacFlClip(AacConfiguration component, AnimationClip clip)
@@ -19,6 +21,7 @@ namespace AnimatorAsCode.V1
Clip = clip; Clip = clip;
} }
/// Set the clip to be looping.
public AacFlClip Looping() public AacFlClip Looping()
{ {
var settings = AnimationUtility.GetAnimationClipSettings(Clip); var settings = AnimationUtility.GetAnimationClipSettings(Clip);
@@ -27,7 +30,8 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Set the clip to be non-looping.
public AacFlClip NonLooping() public AacFlClip NonLooping()
{ {
var settings = AnimationUtility.GetAnimationClipSettings(Clip); var settings = AnimationUtility.GetAnimationClipSettings(Clip);
@@ -37,12 +41,14 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Start editing the clip with a lambda expression.
public AacFlClip Animating(Action<AacFlEditClip> action) public AacFlClip Animating(Action<AacFlEditClip> action)
{ {
action.Invoke(new AacFlEditClip(_component, Clip)); action.Invoke(new AacFlEditClip(_component, Clip));
return this; return this;
} }
/// Enable or disable GameObjects. This lasts one frame. The array can safely contain null values.
public AacFlClip Toggling(GameObject[] gameObjectsWithNulls, bool value) public AacFlClip Toggling(GameObject[] gameObjectsWithNulls, bool value)
{ {
var defensiveObjects = gameObjectsWithNulls.Where(o => o != null); // Allow users to remove an item in the middle of the array var defensiveObjects = gameObjectsWithNulls.Where(o => o != null); // Allow users to remove an item in the middle of the array
@@ -56,6 +62,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Enable or disable a GameObject. This lasts one frame.
public AacFlClip Toggling(GameObject gameObject, bool value) public AacFlClip Toggling(GameObject gameObject, bool value)
{ {
var binding = AacInternals.Binding(_component, typeof(GameObject), gameObject.transform, "m_IsActive"); var binding = AacInternals.Binding(_component, typeof(GameObject), gameObject.transform, "m_IsActive");
@@ -65,6 +72,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Change a blendShape of a skinned mesh. This lasts one frame.
public AacFlClip BlendShape(SkinnedMeshRenderer renderer, string blendShapeName, float value) public AacFlClip BlendShape(SkinnedMeshRenderer renderer, string blendShapeName, float value)
{ {
var binding = AacInternals.Binding(_component, typeof(SkinnedMeshRenderer), renderer.transform, $"blendShape.{blendShapeName}"); var binding = AacInternals.Binding(_component, typeof(SkinnedMeshRenderer), renderer.transform, $"blendShape.{blendShapeName}");
@@ -74,6 +82,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Change a blendShape of multiple skinned meshes. This lasts one frame. The array can safely contain null values.
public AacFlClip BlendShape(SkinnedMeshRenderer[] rendererWithNulls, string blendShapeName, float value) public AacFlClip BlendShape(SkinnedMeshRenderer[] rendererWithNulls, string blendShapeName, float value)
{ {
var defensiveObjects = rendererWithNulls.Where(o => o != null); // Allow users to remove an item in the middle of the array var defensiveObjects = rendererWithNulls.Where(o => o != null); // Allow users to remove an item in the middle of the array
@@ -87,6 +96,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Change a blendShape of a skinned mesh, with an animation curve.
public AacFlClip BlendShape(SkinnedMeshRenderer renderer, string blendShapeName, AnimationCurve animationCurve) public AacFlClip BlendShape(SkinnedMeshRenderer renderer, string blendShapeName, AnimationCurve animationCurve)
{ {
var binding = AacInternals.Binding(_component, typeof(SkinnedMeshRenderer), renderer.transform, $"blendShape.{blendShapeName}"); var binding = AacInternals.Binding(_component, typeof(SkinnedMeshRenderer), renderer.transform, $"blendShape.{blendShapeName}");
@@ -96,6 +106,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Change a blendShape of multiple skinned meshes, with an animation curve. The array can safely contain null values.
public AacFlClip BlendShape(SkinnedMeshRenderer[] rendererWithNulls, string blendShapeName, AnimationCurve animationCurve) public AacFlClip BlendShape(SkinnedMeshRenderer[] rendererWithNulls, string blendShapeName, AnimationCurve animationCurve)
{ {
var defensiveObjects = rendererWithNulls.Where(o => o != null); // Allow users to remove an item in the middle of the array var defensiveObjects = rendererWithNulls.Where(o => o != null); // Allow users to remove an item in the middle of the array
@@ -109,6 +120,8 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
// FIXME API: This is weird, this should be a Transform array, and also this needs a single-object overload.
/// Change the position of a GameObject in local space. This lasts one frame. This lasts one frame. The array can safely contain null values.
public AacFlClip Positioning(GameObject[] gameObjectsWithNulls, Vector3 localPosition) public AacFlClip Positioning(GameObject[] gameObjectsWithNulls, Vector3 localPosition)
{ {
var defensiveObjects = gameObjectsWithNulls.Where(o => o != null); // Allow users to remove an item in the middle of the array var defensiveObjects = gameObjectsWithNulls.Where(o => o != null); // Allow users to remove an item in the middle of the array
@@ -277,12 +290,15 @@ namespace AnimatorAsCode.V1
return new AacFlSettingCurve(Clip, new[] {binding}); return new AacFlSettingCurve(Clip, new[] {binding});
} }
/// Animates a color property of a component. The runtime type of the component will be used.
public AacFlSettingCurveColor AnimatesColor(Component anyComponent, string property) public AacFlSettingCurveColor AnimatesColor(Component anyComponent, string property)
{ {
var binding = Internal_BindingFromComponent(anyComponent, property); var binding = Internal_BindingFromComponent(anyComponent, property);
return new AacFlSettingCurveColor(Clip, new[] {binding}); return new AacFlSettingCurveColor(Clip, new[] {binding});
} }
// FIXME API: Safety is not provived on nulls. It should probably be, for convenience.
/// Animates a color property of several components. The runtime type of the component will be used.
public AacFlSettingCurveColor AnimatesColor(Component[] anyComponents, string property) public AacFlSettingCurveColor AnimatesColor(Component[] anyComponents, string property)
{ {
var that = this; var that = this;
@@ -293,18 +309,24 @@ namespace AnimatorAsCode.V1
return new AacFlSettingCurveColor(Clip, bindings); return new AacFlSettingCurveColor(Clip, bindings);
} }
// FIXME API: The multi-component (including nulls) version of this function is missing
/// Animates a HDR color property of a component (uses XYZW instead of RGBA). The runtime type of the component will be used. // FIXME: this needs multi-component, with safety
public AacFlSettingCurveColor AnimatesHDRColor(Component anyComponent, string property) public AacFlSettingCurveColor AnimatesHDRColor(Component anyComponent, string property)
{ {
var binding = Internal_BindingFromComponent(anyComponent, property); var binding = Internal_BindingFromComponent(anyComponent, property);
return new AacFlSettingCurveColor(Clip, new[] {binding}, true); return new AacFlSettingCurveColor(Clip, new[] {binding}, true);
} }
// FIXME API: The multi-component (including nulls) version of this function is missing
/// Animates an object reference of a component. The runtime type of the component will be used.
public AacFlSettingCurveObjectReference AnimatesObjectReference(Component anyComponent, string property) public AacFlSettingCurveObjectReference AnimatesObjectReference(Component anyComponent, string property)
{ {
var binding = Internal_BindingFromComponent(anyComponent, property); var binding = Internal_BindingFromComponent(anyComponent, property);
return new AacFlSettingCurveObjectReference(Clip, new[] {binding}); return new AacFlSettingCurveObjectReference(Clip, new[] {binding});
} }
/// Returns an EditorCurveBinding of a component, relative to the animator root. The runtime type of the component will be used.<br/>
/// This is meant to be used in conjunction with traditional animation APIs.
public EditorCurveBinding BindingFromComponent(Component anyComponent, string propertyName) public EditorCurveBinding BindingFromComponent(Component anyComponent, string propertyName)
{ {
return Internal_BindingFromComponent(anyComponent, propertyName); return Internal_BindingFromComponent(anyComponent, propertyName);
@@ -327,6 +349,7 @@ namespace AnimatorAsCode.V1
_bindings = bindings; _bindings = bindings;
} }
/// Define the curve to be exactly one frame by defining two constant keyframes, usually lasting 1/60th of a second, with the desired value.
public void WithOneFrame(float desiredValue) public void WithOneFrame(float desiredValue)
{ {
foreach (var binding in _bindings) foreach (var binding in _bindings)
@@ -335,6 +358,7 @@ namespace AnimatorAsCode.V1
} }
} }
/// Define the curve to last a specific amount of seconds by defining two constant keyframes, with the desired value.
public void WithFixedSeconds(float seconds, float desiredValue) public void WithFixedSeconds(float seconds, float desiredValue)
{ {
foreach (var binding in _bindings) foreach (var binding in _bindings)
@@ -343,16 +367,19 @@ namespace AnimatorAsCode.V1
} }
} }
/// Start defining the keyframes with a lambda expression, expressing the unit to be in seconds.
public void WithSecondsUnit(Action<AacFlSettingKeyframes> action) public void WithSecondsUnit(Action<AacFlSettingKeyframes> action)
{ {
InternalWithUnit(AacFlUnit.Seconds, action); InternalWithUnit(AacFlUnit.Seconds, action);
} }
/// Start defining the keyframes with a lambda expression, expressing the unit in frames.
public void WithFrameCountUnit(Action<AacFlSettingKeyframes> action) public void WithFrameCountUnit(Action<AacFlSettingKeyframes> action)
{ {
InternalWithUnit(AacFlUnit.Frames, action); InternalWithUnit(AacFlUnit.Frames, action);
} }
/// Start defining the keyframes with a lambda expression, expressing the unit.
public void WithUnit(AacFlUnit unit, Action<AacFlSettingKeyframes> action) public void WithUnit(AacFlUnit unit, Action<AacFlSettingKeyframes> action)
{ {
InternalWithUnit(unit, action); InternalWithUnit(unit, action);
@@ -370,6 +397,8 @@ namespace AnimatorAsCode.V1
} }
} }
// FIXME WEB: Missing from web docs
/// Define the curve as the parameter. The duration is encoded inside the curve itself.
public void WithAnimationCurve(AnimationCurve animationCurve) public void WithAnimationCurve(AnimationCurve animationCurve)
{ {
foreach (var binding in _bindings) foreach (var binding in _bindings)
@@ -390,6 +419,7 @@ namespace AnimatorAsCode.V1
_bindings = bindings; _bindings = bindings;
} }
/// Define the curve to be exactly one frame by defining two constant keyframes, usually lasting 1/60th of a second, with the desired object reference value.
public void WithOneFrame(Object desiredValue) public void WithOneFrame(Object desiredValue)
{ {
foreach (var binding in _bindings) foreach (var binding in _bindings)
@@ -402,6 +432,8 @@ namespace AnimatorAsCode.V1
} }
} }
// FIXME WEB: Missing from web docs
// FIXME NON-DOCUMENTED: Missing docs
public void WithKeyframes(AacFlUnit unit, Action<AacFlSettingObjectReferenceKeyframes> action) // FIXME: Should this be renamed? public void WithKeyframes(AacFlUnit unit, Action<AacFlSettingObjectReferenceKeyframes> action) // FIXME: Should this be renamed?
{ {
var mutatedObjectReferenceKeyframes = new List<ObjectReferenceKeyframe>(); var mutatedObjectReferenceKeyframes = new List<ObjectReferenceKeyframe>();
@@ -13,6 +13,7 @@ namespace AnimatorAsCode.V1
BlendTree = blendTree; BlendTree = blendTree;
} }
/// Exposes the underlying Unity BlendTree asset.
public BlendTree BlendTree { get; } public BlendTree BlendTree { get; }
} }
@@ -22,25 +23,25 @@ namespace AnimatorAsCode.V1
{ {
} }
// Define this BlendTree as being FreeformCartesian2D. /// Define this BlendTree as being FreeformCartesian2D.
public AacFlBlendTree2D FreeformCartesian2D(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY) public AacFlBlendTree2D FreeformCartesian2D(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY)
{ {
return New2DBlendTree(parameterX, parameterY, BlendTreeType.FreeformCartesian2D); return New2DBlendTree(parameterX, parameterY, BlendTreeType.FreeformCartesian2D);
} }
// Define this BlendTree as being FreeformDirectional2D. /// Define this BlendTree as being FreeformDirectional2D.
public AacFlBlendTree2D FreeformDirectional2D(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY) public AacFlBlendTree2D FreeformDirectional2D(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY)
{ {
return New2DBlendTree(parameterX, parameterY, BlendTreeType.FreeformDirectional2D); return New2DBlendTree(parameterX, parameterY, BlendTreeType.FreeformDirectional2D);
} }
// Define this BlendTree as being SimpleDirectional2D. /// Define this BlendTree as being SimpleDirectional2D.
public AacFlBlendTree2D SimpleDirectional2D(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY) public AacFlBlendTree2D SimpleDirectional2D(AacFlFloatParameter parameterX, AacFlFloatParameter parameterY)
{ {
return New2DBlendTree(parameterX, parameterY, BlendTreeType.SimpleDirectional2D); return New2DBlendTree(parameterX, parameterY, BlendTreeType.SimpleDirectional2D);
} }
// Define this BlendTree as being Simple1D. /// Define this BlendTree as being Simple1D.
public AacFlBlendTree1D Simple1D(AacFlFloatParameter parameter) public AacFlBlendTree1D Simple1D(AacFlFloatParameter parameter)
{ {
BlendTree.blendType = BlendTreeType.Simple1D; BlendTree.blendType = BlendTreeType.Simple1D;
@@ -50,7 +51,7 @@ namespace AnimatorAsCode.V1
return new AacFlBlendTree1D(BlendTree); return new AacFlBlendTree1D(BlendTree);
} }
// Define this BlendTree as being Direct. /// Define this BlendTree as being Direct.
public AacFlBlendTreeDirect Direct() public AacFlBlendTreeDirect Direct()
{ {
BlendTree.blendType = BlendTreeType.Direct; BlendTree.blendType = BlendTreeType.Direct;
@@ -74,43 +75,43 @@ namespace AnimatorAsCode.V1
{ {
} }
// Add a BlendTree in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a BlendTree in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, Vector2 pos) public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, Vector2 pos)
{ {
return WithAnimationInternal(blendTree.BlendTree, pos.x, pos.y, null); return WithAnimationInternal(blendTree.BlendTree, pos.x, pos.y, null);
} }
// Add a BlendTree in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a BlendTree in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, float x, float y) public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, float x, float y)
{ {
return WithAnimationInternal(blendTree.BlendTree, x, y, null); return WithAnimationInternal(blendTree.BlendTree, x, y, null);
} }
// Add a Clip in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a Clip in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(AacFlClip clip, Vector2 pos) public AacFlBlendTree2D WithAnimation(AacFlClip clip, Vector2 pos)
{ {
return WithAnimationInternal(clip.Clip, pos.x, pos.y, null); return WithAnimationInternal(clip.Clip, pos.x, pos.y, null);
} }
// Add a Clip in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a Clip in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(AacFlClip clip, float x, float y) public AacFlBlendTree2D WithAnimation(AacFlClip clip, float x, float y)
{ {
return WithAnimationInternal(clip.Clip, x, y, null); return WithAnimationInternal(clip.Clip, x, y, null);
} }
// Add a raw motion in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a raw motion in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(Motion motion, Vector2 pos) public AacFlBlendTree2D WithAnimation(Motion motion, Vector2 pos)
{ {
return WithAnimationInternal(motion, pos.x, pos.y, null); return WithAnimationInternal(motion, pos.x, pos.y, null);
} }
// Add a raw motion in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a raw motion in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(Motion motion, float x, float y) public AacFlBlendTree2D WithAnimation(Motion motion, float x, float y)
{ {
return WithAnimationInternal(motion, x, y, null); return WithAnimationInternal(motion, x, y, null);
} }
// Add a BlendTree in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a BlendTree in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, Vector2 pos, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, Vector2 pos, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -120,7 +121,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(blendTree.BlendTree, pos.x, pos.y, furtherDefiningChild); return WithAnimationInternal(blendTree.BlendTree, pos.x, pos.y, furtherDefiningChild);
} }
// Add a BlendTree in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a BlendTree in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, float x, float y, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree2D WithAnimation(AacFlBlendTree blendTree, float x, float y, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -130,7 +131,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(blendTree.BlendTree, x, y, furtherDefiningChild); return WithAnimationInternal(blendTree.BlendTree, x, y, furtherDefiningChild);
} }
// Add a Clip in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a Clip in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(AacFlClip clip, Vector2 pos, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree2D WithAnimation(AacFlClip clip, Vector2 pos, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -140,7 +141,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(clip.Clip, pos.x, pos.y, furtherDefiningChild); return WithAnimationInternal(clip.Clip, pos.x, pos.y, furtherDefiningChild);
} }
// Add a Clip in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a Clip in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(AacFlClip clip, float x, float y, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree2D WithAnimation(AacFlClip clip, float x, float y, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -150,7 +151,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(clip.Clip, x, y, furtherDefiningChild); return WithAnimationInternal(clip.Clip, x, y, furtherDefiningChild);
} }
// Add a raw motion in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a raw motion in the specified coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(Motion motion, Vector2 pos, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree2D WithAnimation(Motion motion, Vector2 pos, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -160,7 +161,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(motion, pos.x, pos.y, furtherDefiningChild); return WithAnimationInternal(motion, pos.x, pos.y, furtherDefiningChild);
} }
// Add a raw motion in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a raw motion in the specified `x` and `y` coordinates. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree2D WithAnimation(Motion motion, float x, float y, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree2D WithAnimation(Motion motion, float x, float y, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -200,25 +201,25 @@ namespace AnimatorAsCode.V1
{ {
} }
// Add a BlendTree in the specified threshold. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a BlendTree in the specified threshold. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree1D WithAnimation(AacFlBlendTree blendTree, float threshold) public AacFlBlendTree1D WithAnimation(AacFlBlendTree blendTree, float threshold)
{ {
return WithAnimationInternal(blendTree.BlendTree, threshold, null); return WithAnimationInternal(blendTree.BlendTree, threshold, null);
} }
// Add a Clip in the specified threshold. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a Clip in the specified threshold. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree1D WithAnimation(AacFlClip clip, float threshold) public AacFlBlendTree1D WithAnimation(AacFlClip clip, float threshold)
{ {
return WithAnimationInternal(clip.Clip, threshold, null); return WithAnimationInternal(clip.Clip, threshold, null);
} }
// Add a raw motion in the specified threshold. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a raw motion in the specified threshold. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree1D WithAnimation(Motion motion, float threshold) public AacFlBlendTree1D WithAnimation(Motion motion, float threshold)
{ {
return WithAnimationInternal(motion, threshold, null); return WithAnimationInternal(motion, threshold, null);
} }
// Add a BlendTree in the specified threshold, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a BlendTree in the specified threshold, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree1D WithAnimation(AacFlBlendTree blendTree, float threshold, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree1D WithAnimation(AacFlBlendTree blendTree, float threshold, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -228,7 +229,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(blendTree.BlendTree, threshold, furtherDefiningChild); return WithAnimationInternal(blendTree.BlendTree, threshold, furtherDefiningChild);
} }
// Add a Clip in the specified threshold, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a Clip in the specified threshold, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree1D WithAnimation(AacFlClip clip, float threshold, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree1D WithAnimation(AacFlClip clip, float threshold, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -238,7 +239,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(clip.Clip, threshold, furtherDefiningChild); return WithAnimationInternal(clip.Clip, threshold, furtherDefiningChild);
} }
// Add a raw motion in the specified threshold, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a raw motion in the specified threshold, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTree1D WithAnimation(Motion motion, float threshold, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTree1D WithAnimation(Motion motion, float threshold, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -281,25 +282,25 @@ namespace AnimatorAsCode.V1
{ {
} }
// Add a BlendTree driven by the specified parameter. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a BlendTree driven by the specified parameter. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTreeDirect WithAnimation(AacFlBlendTree blendTree, AacFlFloatParameter parameter) public AacFlBlendTreeDirect WithAnimation(AacFlBlendTree blendTree, AacFlFloatParameter parameter)
{ {
return WithAnimationInternal(blendTree.BlendTree, parameter, null); return WithAnimationInternal(blendTree.BlendTree, parameter, null);
} }
// Add a Clip driven by the specified parameter. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a Clip driven by the specified parameter. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTreeDirect WithAnimation(AacFlClip clip, AacFlFloatParameter parameter) public AacFlBlendTreeDirect WithAnimation(AacFlClip clip, AacFlFloatParameter parameter)
{ {
return WithAnimationInternal(clip.Clip, parameter, null); return WithAnimationInternal(clip.Clip, parameter, null);
} }
// Add a raw motion driven by the specified parameter. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a raw motion driven by the specified parameter. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTreeDirect WithAnimation(Motion motion, AacFlFloatParameter parameter) public AacFlBlendTreeDirect WithAnimation(Motion motion, AacFlFloatParameter parameter)
{ {
return WithAnimationInternal(motion, parameter, null); return WithAnimationInternal(motion, parameter, null);
} }
// Add a BlendTree driven by the specified parameter, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a BlendTree driven by the specified parameter, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTreeDirect WithAnimation(AacFlBlendTree blendTree, AacFlFloatParameter parameter, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTreeDirect WithAnimation(AacFlBlendTree blendTree, AacFlFloatParameter parameter, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -309,7 +310,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(blendTree.BlendTree, parameter, furtherDefiningChild); return WithAnimationInternal(blendTree.BlendTree, parameter, furtherDefiningChild);
} }
// Add a Clip driven by the specified parameter, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a Clip driven by the specified parameter, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTreeDirect WithAnimation(AacFlClip clip, AacFlFloatParameter parameter, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTreeDirect WithAnimation(AacFlClip clip, AacFlFloatParameter parameter, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -319,7 +320,7 @@ namespace AnimatorAsCode.V1
return WithAnimationInternal(clip.Clip, parameter, furtherDefiningChild); return WithAnimationInternal(clip.Clip, parameter, furtherDefiningChild);
} }
// Add a raw motion driven by the specified parameter, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false. /// Add a raw motion driven by the specified parameter, and further define that motion. By default, the timeScale is 1, cycle offset is 0, mirror is false.
public AacFlBlendTreeDirect WithAnimation(Motion motion, AacFlFloatParameter parameter, Action<AacFlBlendTreeChildMotion> furtherDefiningChild) public AacFlBlendTreeDirect WithAnimation(Motion motion, AacFlFloatParameter parameter, Action<AacFlBlendTreeChildMotion> furtherDefiningChild)
{ {
// Disallow null here: as nulls are allowed in the internal function, // Disallow null here: as nulls are allowed in the internal function,
@@ -41,6 +41,7 @@ namespace AnimatorAsCode.V1
public abstract class AacFlParameter public abstract class AacFlParameter
{ {
/// Expose the name of this parameter.
public string Name { get; } public string Name { get; }
protected AacFlParameter(string name) protected AacFlParameter(string name)
@@ -55,6 +56,9 @@ namespace AnimatorAsCode.V1
{ {
} }
/// This function is used for internal purposes:<br/>
/// Provide a float representation of the parameter.<br/>
/// This is used mainly to derive parameter driver values on the VRChat platform.
public abstract float ValueToFloat(TParam value); public abstract float ValueToFloat(TParam value);
} }
@@ -69,9 +73,17 @@ namespace AnimatorAsCode.V1
{ {
internal static AacFlFloatParameter Internally(string name) => new AacFlFloatParameter(name); internal static AacFlFloatParameter Internally(string name) => new AacFlFloatParameter(name);
protected AacFlFloatParameter(string name) : base(name) { } protected AacFlFloatParameter(string name) : base(name) { }
/// Float is greater than other.<br/>
/// When used on some platforms, you need to be careful as the remote value may not be the same as the local value.
public IAacFlCondition IsGreaterThan(float other) => Just(condition => condition.Add(Name, Greater, other)); public IAacFlCondition IsGreaterThan(float other) => Just(condition => condition.Add(Name, Greater, other));
/// Float is less than other.<br/>
/// When used on some platforms, you need to be careful as the remote value may not be the same as the local value.
public IAacFlCondition IsLessThan(float other) => Just(condition => condition.Add(Name, Less, other)); public IAacFlCondition IsLessThan(float other) => Just(condition => condition.Add(Name, Less, other));
/// This function is used for internal purposes:<br/>
/// Returns the same value as the parameter.
public override float ValueToFloat(float value) public override float ValueToFloat(float value)
{ {
return value; return value;
@@ -82,11 +94,21 @@ namespace AnimatorAsCode.V1
{ {
internal static AacFlIntParameter Internally(string name) => new AacFlIntParameter(name); internal static AacFlIntParameter Internally(string name) => new AacFlIntParameter(name);
protected AacFlIntParameter(string name) : base(name) { } protected AacFlIntParameter(string name) : base(name) { }
/// Int is strictly greater than `other`
public IAacFlCondition IsGreaterThan(int other) => Just(condition => condition.Add(Name, Greater, other)); public IAacFlCondition IsGreaterThan(int other) => Just(condition => condition.Add(Name, Greater, other));
/// Int is strictly less than `other`
public IAacFlCondition IsLessThan(int other) => Just(condition => condition.Add(Name, Less, other)); public IAacFlCondition IsLessThan(int other) => Just(condition => condition.Add(Name, Less, other));
/// Int is equal to `other`
public IAacFlCondition IsEqualTo(int other) => Just(condition => condition.Add(Name, AnimatorConditionMode.Equals, other)); public IAacFlCondition IsEqualTo(int other) => Just(condition => condition.Add(Name, AnimatorConditionMode.Equals, other));
/// Int is not equal to `other`
public IAacFlCondition IsNotEqualTo(int other) => Just(condition => condition.Add(Name, NotEqual, other)); public IAacFlCondition IsNotEqualTo(int other) => Just(condition => condition.Add(Name, NotEqual, other));
/// This function is used for internal purposes:<br/>
/// Returns the int value as a float.
public override float ValueToFloat(int value) public override float ValueToFloat(int value)
{ {
return value; return value;
@@ -100,7 +122,10 @@ namespace AnimatorAsCode.V1
{ {
} }
/// Int is equal to `(int)other`
public IAacFlCondition IsEqualTo(TEnum other) => IsEqualTo((int)(object)other); public IAacFlCondition IsEqualTo(TEnum other) => IsEqualTo((int)(object)other);
/// Int is not equal to `(int)other`
public IAacFlCondition IsNotEqualTo(TEnum other) => IsNotEqualTo((int)(object)other); public IAacFlCondition IsNotEqualTo(TEnum other) => IsNotEqualTo((int)(object)other);
} }
@@ -108,11 +133,21 @@ namespace AnimatorAsCode.V1
{ {
internal static AacFlBoolParameter Internally(string name) => new AacFlBoolParameter(name); internal static AacFlBoolParameter Internally(string name) => new AacFlBoolParameter(name);
protected AacFlBoolParameter(string name) : base(name) { } protected AacFlBoolParameter(string name) : base(name) { }
/// Bool is true
public IAacFlCondition IsTrue() => Just(condition => condition.Add(Name, If, 0)); public IAacFlCondition IsTrue() => Just(condition => condition.Add(Name, If, 0));
/// Bool is false
public IAacFlCondition IsFalse() => Just(condition => condition.Add(Name, IfNot, 0)); public IAacFlCondition IsFalse() => Just(condition => condition.Add(Name, IfNot, 0));
/// Bool is equal to `other`
public IAacFlCondition IsEqualTo(bool other) => Just(condition => condition.Add(Name, other ? If : IfNot, 0)); public IAacFlCondition IsEqualTo(bool other) => Just(condition => condition.Add(Name, other ? If : IfNot, 0));
/// Bool is not equal to `other`
public IAacFlCondition IsNotEqualTo(bool other) => Just(condition => condition.Add(Name, other ? IfNot : If, 0)); public IAacFlCondition IsNotEqualTo(bool other) => Just(condition => condition.Add(Name, other ? IfNot : If, 0));
/// This function is used for internal purposes:<br/>
/// Returns 1 when the value is true, 0 otherwise.
public override float ValueToFloat(bool value) public override float ValueToFloat(bool value)
{ {
return value ? 1f : 0f; return value ? 1f : 0f;
@@ -126,7 +161,11 @@ namespace AnimatorAsCode.V1
private AacFlFloatParameterGroup(params string[] names) { _names = names; } private AacFlFloatParameterGroup(params string[] names) { _names = names; }
public List<AacFlFloatParameter> ToList() => _names.Select(AacFlFloatParameter.Internally).ToList(); public List<AacFlFloatParameter> ToList() => _names.Select(AacFlFloatParameter.Internally).ToList();
/// All of the Floats are greater than `other`.<br/>
/// When used on some platforms, you need to be careful as the remote value may not be the same as the local value.
public IAacFlCondition AreGreaterThan(float other) => ForEach(_names, (name, condition) => condition.Add(name, Greater, other)); public IAacFlCondition AreGreaterThan(float other) => ForEach(_names, (name, condition) => condition.Add(name, Greater, other));
/// All of the Floats are less than `other`.<br/>
/// When used on some platforms, you need to be careful as the remote value may not be the same as the local value.
public IAacFlCondition AreLessThan(float other) => ForEach(_names, (name, condition) => condition.Add(name, Less, other)); public IAacFlCondition AreLessThan(float other) => ForEach(_names, (name, condition) => condition.Add(name, Less, other));
} }
@@ -137,9 +176,13 @@ namespace AnimatorAsCode.V1
private AacFlIntParameterGroup(params string[] names) { _names = names; } private AacFlIntParameterGroup(params string[] names) { _names = names; }
public List<AacFlIntParameter> ToList() => _names.Select(AacFlIntParameter.Internally).ToList(); public List<AacFlIntParameter> ToList() => _names.Select(AacFlIntParameter.Internally).ToList();
/// All of the Ints are strictly greater than `other`
public IAacFlCondition AreGreaterThan(float other) => ForEach(_names, (name, condition) => condition.Add(name, Greater, other)); public IAacFlCondition AreGreaterThan(float other) => ForEach(_names, (name, condition) => condition.Add(name, Greater, other));
/// All of the Ints are strictly less than `other`
public IAacFlCondition AreLessThan(float other) => ForEach(_names, (name, condition) => condition.Add(name, Less, other)); public IAacFlCondition AreLessThan(float other) => ForEach(_names, (name, condition) => condition.Add(name, Less, other));
/// All of the Ints are equal to `other`
public IAacFlCondition AreEqualTo(float other) => ForEach(_names, (name, condition) => condition.Add(name, AnimatorConditionMode.Equals, other)); public IAacFlCondition AreEqualTo(float other) => ForEach(_names, (name, condition) => condition.Add(name, AnimatorConditionMode.Equals, other));
/// All of the Ints are not equal to `other`
public IAacFlCondition AreNotEqualTo(float other) => ForEach(_names, (name, condition) => condition.Add(name, NotEqual, other)); public IAacFlCondition AreNotEqualTo(float other) => ForEach(_names, (name, condition) => condition.Add(name, NotEqual, other));
} }
@@ -150,27 +193,30 @@ namespace AnimatorAsCode.V1
private AacFlBoolParameterGroup(params string[] names) { _names = names; } private AacFlBoolParameterGroup(params string[] names) { _names = names; }
public List<AacFlBoolParameter> ToList() => _names.Select(AacFlBoolParameter.Internally).ToList(); public List<AacFlBoolParameter> ToList() => _names.Select(AacFlBoolParameter.Internally).ToList();
/// All of the Bools are true
public IAacFlCondition AreTrue() => ForEach(_names, (name, condition) => condition.Add(name, If, 0)); public IAacFlCondition AreTrue() => ForEach(_names, (name, condition) => condition.Add(name, If, 0));
/// All of the Bools are false
public IAacFlCondition AreFalse() => ForEach(_names, (name, condition) => condition.Add(name, IfNot, 0)); public IAacFlCondition AreFalse() => ForEach(_names, (name, condition) => condition.Add(name, IfNot, 0));
/// All of the Bools are equal to `other`
public IAacFlCondition AreEqualTo(bool other) => ForEach(_names, (name, condition) => condition.Add(name, other ? If : IfNot, 0)); public IAacFlCondition AreEqualTo(bool other) => ForEach(_names, (name, condition) => condition.Add(name, other ? If : IfNot, 0));
/// is true when all of the following conditions are met: /// All the Bools except `exceptThisMustBeTrue` are false, and the Bool of `exceptThisMustBeTrue` must be true.
/// <ul>
/// <li>all of the parameters in the group must be false except for the parameter defined in exceptThisMustBeTrue if it is present in the group.</li>
/// <li>the parameter defined in exceptThisMustBeTrue must be true.</li>
/// </ul>
public IAacFlCondition AreFalseExcept(AacFlBoolParameter exceptThisMustBeTrue) public IAacFlCondition AreFalseExcept(AacFlBoolParameter exceptThisMustBeTrue)
{ {
var group = new AacFlBoolParameterGroup(exceptThisMustBeTrue.Name); var group = new AacFlBoolParameterGroup(exceptThisMustBeTrue.Name);
return AreFalseExcept(group); return AreFalseExcept(group);
} }
/// All the Bools except those in `exceptTheseMustBeTrue` are false, and all of the Bools in `exceptTheseMustBeTrue` must be true.
public IAacFlCondition AreFalseExcept(params AacFlBoolParameter[] exceptTheseMustBeTrue) public IAacFlCondition AreFalseExcept(params AacFlBoolParameter[] exceptTheseMustBeTrue)
{ {
var group = new AacFlBoolParameterGroup(exceptTheseMustBeTrue.Select(parameter => parameter.Name).ToArray()); var group = new AacFlBoolParameterGroup(exceptTheseMustBeTrue.Select(parameter => parameter.Name).ToArray());
return AreFalseExcept(group); return AreFalseExcept(group);
} }
/// All the Bools except those in `exceptTheseMustBeTrue` are false, and all of the Bools in `exceptTheseMustBeTrue` must be true.
public IAacFlCondition AreFalseExcept(AacFlBoolParameterGroup exceptTheseMustBeTrue) => Just(condition => public IAacFlCondition AreFalseExcept(AacFlBoolParameterGroup exceptTheseMustBeTrue) => Just(condition =>
{ {
foreach (var name in _names.Where(name => !exceptTheseMustBeTrue._names.Contains(name))) foreach (var name in _names.Where(name => !exceptTheseMustBeTrue._names.Contains(name)))
@@ -183,18 +229,21 @@ namespace AnimatorAsCode.V1
} }
}); });
/// All the Bools except `exceptThisMustBeTrue` are true, and the Bool of `exceptThisMustBeTrue` must be false.
public IAacFlCondition AreTrueExcept(AacFlBoolParameter exceptThisMustBeFalse) public IAacFlCondition AreTrueExcept(AacFlBoolParameter exceptThisMustBeFalse)
{ {
var group = new AacFlBoolParameterGroup(exceptThisMustBeFalse.Name); var group = new AacFlBoolParameterGroup(exceptThisMustBeFalse.Name);
return AreTrueExcept(group); return AreTrueExcept(group);
} }
/// All the Bools except those in `exceptTheseMustBeTrue` are true, and all of the Bools in `exceptTheseMustBeTrue` must be false.
public IAacFlCondition AreTrueExcept(params AacFlBoolParameter[] exceptTheseMustBeFalse) public IAacFlCondition AreTrueExcept(params AacFlBoolParameter[] exceptTheseMustBeFalse)
{ {
var group = new AacFlBoolParameterGroup(exceptTheseMustBeFalse.Select(parameter => parameter.Name).ToArray()); var group = new AacFlBoolParameterGroup(exceptTheseMustBeFalse.Select(parameter => parameter.Name).ToArray());
return AreTrueExcept(group); return AreTrueExcept(group);
} }
/// All the Bools except those in `exceptTheseMustBeTrue` are true, and all of the Bools in `exceptTheseMustBeTrue` must be false.
public IAacFlCondition AreTrueExcept(AacFlBoolParameterGroup exceptTheseMustBeFalse) => Just(condition => public IAacFlCondition AreTrueExcept(AacFlBoolParameterGroup exceptTheseMustBeFalse) => Just(condition =>
{ {
foreach (var name in _names.Where(name => !exceptTheseMustBeFalse._names.Contains(name))) foreach (var name in _names.Where(name => !exceptTheseMustBeFalse._names.Contains(name)))
@@ -207,11 +256,13 @@ namespace AnimatorAsCode.V1
} }
}); });
/// Generates multiple transitions, verifying whether any Bool is true. This can only be used inside `.When(...)`
public IAacFlOrCondition IsAnyTrue() public IAacFlOrCondition IsAnyTrue()
{ {
return IsAnyEqualTo(true); return IsAnyEqualTo(true);
} }
/// Generates multiple transitions, verifying whether any Bool is false. This can only be used inside `.When(...)`
public IAacFlOrCondition IsAnyFalse() public IAacFlOrCondition IsAnyFalse()
{ {
return IsAnyEqualTo(false); return IsAnyEqualTo(false);
@@ -110,7 +110,9 @@ namespace AnimatorAsCode.V1
public class AacFlStateMachine : AacAnimatorNode<AacFlStateMachine> public class AacFlStateMachine : AacAnimatorNode<AacFlStateMachine>
{ {
/// Exposes the underlying Unity AnimatorStateMachine object of this state machine.
public readonly AnimatorStateMachine Machine; public readonly AnimatorStateMachine Machine;
private readonly AnimationClip _emptyClip; private readonly AnimationClip _emptyClip;
private readonly AacBackingAnimator _backingAnimator; private readonly AacBackingAnimator _backingAnimator;
private readonly IAacDefaultsProvider _defaultsProvider; private readonly IAacDefaultsProvider _defaultsProvider;
@@ -137,17 +139,23 @@ namespace AnimatorAsCode.V1
_childNodes = new List<AacAnimatorNode>(); _childNodes = new List<AacAnimatorNode>();
} }
/// <b>FOR USE ONLY BY EXTENSION FUNCTIONS:</b><br/>
/// Exposes the internal backing animator.
public AacBackingAnimator InternalBackingAnimator() public AacBackingAnimator InternalBackingAnimator()
{ {
return _backingAnimator; return _backingAnimator;
} }
/// Create a new state machine, initially positioned below the last generated state of this layer.<br/>
/// 🔺 If the name is already used, a number will be appended at the end.
public AacFlStateMachine NewSubStateMachine(string name) public AacFlStateMachine NewSubStateMachine(string name)
{ {
var lastState = LastNodePosition(); var lastState = LastNodePosition();
return NewSubStateMachine(name, 0, 0).Shift(lastState, 0, 1); return NewSubStateMachine(name, 0, 0).Shift(lastState, 0, 1);
} }
/// Create a new state machine at a specific position `x` and `y`, in grid units. The grid size is defined in the DefaultsProvider of the AacConfiguration of AAC. `x` positive goes right, `y` positive goes down.<br/>
/// 🔺 If the name is already used, a number will be appended at the end.
public AacFlStateMachine NewSubStateMachine(string name, int x, int y) public AacFlStateMachine NewSubStateMachine(string name, int x, int y)
{ {
var stateMachine = AacInternals.NoUndo(Machine, () => Machine.AddStateMachine(EnsureNameIsDeduplicated(name), GridPosition(x, y))); var stateMachine = AacInternals.NoUndo(Machine, () => Machine.AddStateMachine(EnsureNameIsDeduplicated(name), GridPosition(x, y)));
@@ -181,12 +189,16 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Create a new state, initially positioned below the last generated state of this layer.<br/>
/// 🔺 If the name is already used, a number will be appended at the end.
public AacFlState NewState(string name) public AacFlState NewState(string name)
{ {
var lastState = LastNodePosition(); var lastState = LastNodePosition();
return NewState(name, 0, 0).Shift(lastState, 0, 1); return NewState(name, 0, 0).Shift(lastState, 0, 1);
} }
/// Create a new state at a specific position `x` and `y`, in grid units. The grid size is defined in the DefaultsProvider of the AacConfiguration of AAC. `x` positive goes right, `y` positive goes down.<br/>
/// 🔺 If the name is already used, a number will be appended at the end.
public AacFlState NewState(string name, int x, int y) public AacFlState NewState(string name, int x, int y)
{ {
var state = AacInternals.NoUndo(Machine, () => Machine.AddState(EnsureNameIsDeduplicated(name), GridPosition(x, y))); var state = AacInternals.NoUndo(Machine, () => Machine.AddState(EnsureNameIsDeduplicated(name), GridPosition(x, y)));
@@ -210,21 +222,25 @@ namespace AnimatorAsCode.V1
return stateName; return stateName;
} }
/// Create a transition from Any to the `destination` state.
public AacFlTransition AnyTransitionsTo(AacFlState destination) public AacFlTransition AnyTransitionsTo(AacFlState destination)
{ {
return AnyTransition(destination, Machine); return AnyTransition(destination, Machine);
} }
/// Create a transition from Any to the `destination` state machine.
public AacFlTransition AnyTransitionsTo(AacFlStateMachine destination) public AacFlTransition AnyTransitionsTo(AacFlStateMachine destination)
{ {
return AnyTransition(destination, Machine); return AnyTransition(destination, Machine);
} }
/// Create a transition from the Entry to the `destination` state.
public AacFlEntryTransition EntryTransitionsTo(AacFlState destination) public AacFlEntryTransition EntryTransitionsTo(AacFlState destination)
{ {
return EntryTransition(destination, Machine); return EntryTransition(destination, Machine);
} }
/// Create a transition from the Entry to the `destination` state machine.
public AacFlEntryTransition EntryTransitionsTo(AacFlStateMachine destination) public AacFlEntryTransition EntryTransitionsTo(AacFlStateMachine destination)
{ {
return EntryTransition(destination, Machine); return EntryTransition(destination, Machine);
@@ -367,26 +383,33 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Create a new transition from this state to the `destination` state.
public AacFlTransition TransitionsTo(AacFlState destination) public AacFlTransition TransitionsTo(AacFlState destination)
{ {
return new AacFlTransition(ConfigureTransition(AacInternals.NoUndo(State, () => State.AddTransition(destination.State))), _machine, State, destination.State); return new AacFlTransition(ConfigureTransition(AacInternals.NoUndo(State, () => State.AddTransition(destination.State))), _machine, State, destination.State);
} }
/// Create a new transition from this state to the `destination` state machine.
public AacFlTransition TransitionsTo(AacFlStateMachine destination) public AacFlTransition TransitionsTo(AacFlStateMachine destination)
{ {
return new AacFlTransition(ConfigureTransition(AacInternals.NoUndo(State, () => State.AddTransition(destination.Machine))), _machine, State, destination.Machine); return new AacFlTransition(ConfigureTransition(AacInternals.NoUndo(State, () => State.AddTransition(destination.Machine))), _machine, State, destination.Machine);
} }
/// Create a new transition from Any to this state.
public AacFlTransition TransitionsFromAny() public AacFlTransition TransitionsFromAny()
{ {
return new AacFlTransition(ConfigureTransition(AacInternals.NoUndo(State, () => _machine.AddAnyStateTransition(State))), _machine, null, State); return new AacFlTransition(ConfigureTransition(AacInternals.NoUndo(State, () => _machine.AddAnyStateTransition(State))), _machine, null, State);
} }
/// Create a new transition from Entry to this state. Note that the first created state is the default state, so generally this function does not need to be invoked onto the first created state.<br/>
/// Calling this function will not define this state to be the default state.
public AacFlEntryTransition TransitionsFromEntry() public AacFlEntryTransition TransitionsFromEntry()
{ {
return new AacFlEntryTransition(AacInternals.NoUndo(State, () => _machine.AddEntryTransition(State)), _machine, null, State); return new AacFlEntryTransition(AacInternals.NoUndo(State, () => _machine.AddEntryTransition(State)), _machine, null, State);
} }
/// Create a transition with no exit time to the `destination` state.<br/>
/// Calling this function does not return the transition.
public AacFlState AutomaticallyMovesTo(AacFlState destination) public AacFlState AutomaticallyMovesTo(AacFlState destination)
{ {
var transition = ConfigureTransition(AacInternals.NoUndo(State, () => State.AddTransition(destination.State))); var transition = ConfigureTransition(AacInternals.NoUndo(State, () => State.AddTransition(destination.State)));
@@ -394,6 +417,8 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Create a transition with no exit time to the `destination` state machine.<br/>
/// Calling this function does not return the transition.
public AacFlState AutomaticallyMovesTo(AacFlStateMachine destination) public AacFlState AutomaticallyMovesTo(AacFlStateMachine destination)
{ {
var transition = ConfigureTransition(AacInternals.NoUndo(State, () => State.AddTransition(destination.Machine))); var transition = ConfigureTransition(AacInternals.NoUndo(State, () => State.AddTransition(destination.Machine)));
@@ -401,6 +426,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Create a transition from this state to the exit.
public AacFlTransition Exits() public AacFlTransition Exits()
{ {
return new AacFlTransition(ConfigureTransition(AacInternals.NoUndo(State, () => State.AddExitTransition())), _machine, State, null); return new AacFlTransition(ConfigureTransition(AacInternals.NoUndo(State, () => State.AddExitTransition())), _machine, State, null);
@@ -412,12 +438,16 @@ namespace AnimatorAsCode.V1
return transition; return transition;
} }
/// Set Write Defaults. If you need to do this to many states, consider changing the AacConfiguration DefaultsProvider when creating the AnimatorAsCode instance.
public AacFlState WithWriteDefaultsSetTo(bool shouldWriteDefaults) public AacFlState WithWriteDefaultsSetTo(bool shouldWriteDefaults)
{ {
State.writeDefaultValues = shouldWriteDefaults; State.writeDefaultValues = shouldWriteDefaults;
return this; return this;
} }
// FIXME API: Shouldn't there be a WithMotionTimeSetTo?
// FIXME API inconsistency: Shouldn't this also be called WithMotionTime?
/// Set the Motion Time to a parameter. This was formerly known as Normalized Time.
public AacFlState MotionTime(AacFlFloatParameter floatParam) public AacFlState MotionTime(AacFlFloatParameter floatParam)
{ {
State.timeParameterActive = true; State.timeParameterActive = true;
@@ -426,6 +456,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Set the Cycle Offset to a parameter.
public AacFlState WithCycleOffset(AacFlFloatParameter floatParam) public AacFlState WithCycleOffset(AacFlFloatParameter floatParam)
{ {
State.cycleOffsetParameterActive = false; State.cycleOffsetParameterActive = false;
@@ -434,6 +465,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Set the Cycle Offset to a specific value.
public AacFlState WithCycleOffsetSetTo(float cycleOffset) public AacFlState WithCycleOffsetSetTo(float cycleOffset)
{ {
State.cycleOffsetParameterActive = false; State.cycleOffsetParameterActive = false;
@@ -442,6 +474,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Set the Speed to a parameter.
public AacFlState WithSpeed(AacFlFloatParameter parameter) public AacFlState WithSpeed(AacFlFloatParameter parameter)
{ {
State.speedParameterActive = true; State.speedParameterActive = true;
@@ -450,6 +483,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Set the Speed to a specific value.
public AacFlState WithSpeedSetTo(float speed) public AacFlState WithSpeedSetTo(float speed)
{ {
State.speedParameterActive = false; State.speedParameterActive = false;
@@ -503,48 +537,56 @@ namespace AnimatorAsCode.V1
_transition = transition; _transition = transition;
} }
/// Set interruption source to be Source.
public AacFlTransition WithSourceInterruption() public AacFlTransition WithSourceInterruption()
{ {
_transition.interruptionSource = TransitionInterruptionSource.Source; _transition.interruptionSource = TransitionInterruptionSource.Source;
return this; return this;
} }
/// Set interruption source set to that value.
public AacFlTransition WithInterruption(TransitionInterruptionSource interruptionSource) public AacFlTransition WithInterruption(TransitionInterruptionSource interruptionSource)
{ {
_transition.interruptionSource = interruptionSource; _transition.interruptionSource = interruptionSource;
return this; return this;
} }
/// Set a fixed transition duration in seconds.
public AacFlTransition WithTransitionDurationSeconds(float transitionDuration) public AacFlTransition WithTransitionDurationSeconds(float transitionDuration)
{ {
_transition.duration = transitionDuration; _transition.duration = transitionDuration;
return this; return this;
} }
/// Enable ordered interruption.
public AacFlTransition WithOrderedInterruption() public AacFlTransition WithOrderedInterruption()
{ {
_transition.orderedInterruption = true; _transition.orderedInterruption = true;
return this; return this;
} }
/// Disable ordered interruption.
public AacFlTransition WithNoOrderedInterruption() public AacFlTransition WithNoOrderedInterruption()
{ {
_transition.orderedInterruption = false; _transition.orderedInterruption = false;
return this; return this;
} }
/// Enable transition to self.
public AacFlTransition WithTransitionToSelf() public AacFlTransition WithTransitionToSelf()
{ {
_transition.canTransitionToSelf = true; _transition.canTransitionToSelf = true;
return this; return this;
} }
/// Disable transition to self.
public AacFlTransition WithNoTransitionToSelf() public AacFlTransition WithNoTransitionToSelf()
{ {
_transition.canTransitionToSelf = false; _transition.canTransitionToSelf = false;
return this; return this;
} }
/// Set an exit time at 1, where the animation finishes.
public AacFlTransition AfterAnimationFinishes() public AacFlTransition AfterAnimationFinishes()
{ {
_transition.hasExitTime = true; _transition.hasExitTime = true;
@@ -553,6 +595,7 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
/// Set an exit time at 0, so that it may transition almost immediately.
public AacFlTransition Automatically() public AacFlTransition Automatically()
{ {
_transition.hasExitTime = true; _transition.hasExitTime = true;
@@ -561,6 +604,8 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
// FIXME API: Percent is misnomer
/// Set the exit time at a specific normalized amount.
public AacFlTransition AfterAnimationIsAtLeastAtPercent(float exitTimeNormalized) public AacFlTransition AfterAnimationIsAtLeastAtPercent(float exitTimeNormalized)
{ {
_transition.hasExitTime = true; _transition.hasExitTime = true;
@@ -569,6 +614,8 @@ namespace AnimatorAsCode.V1
return this; return this;
} }
// FIXME API: Percent is misnomer
/// Set a non-fixed transition duration in a normalized amount.
public AacFlTransition WithTransitionDurationPercent(float transitionDurationNormalized) public AacFlTransition WithTransitionDurationPercent(float transitionDurationNormalized)
{ {
_transition.hasFixedDuration = false; _transition.hasFixedDuration = false;
@@ -648,39 +695,28 @@ namespace AnimatorAsCode.V1
return AsContinuationWithOr(); return AsContinuationWithOr();
} }
/// <summary>
/// Applies a series of conditions to this transition, but this series of conditions cannot include an Or operator. /// Applies a series of conditions to this transition, but this series of conditions cannot include an Or operator.
/// </summary>
/// <param name="actionsWithoutOr"></param>
/// <returns></returns>
public AacFlTransitionContinuation When(Action<AacFlTransitionContinuationWithoutOr> actionsWithoutOr) public AacFlTransitionContinuation When(Action<AacFlTransitionContinuationWithoutOr> actionsWithoutOr)
{ {
actionsWithoutOr(new AacFlTransitionContinuationWithoutOr(Transition)); actionsWithoutOr(new AacFlTransitionContinuationWithoutOr(Transition));
return AsContinuationWithOr(); return AsContinuationWithOr();
} }
/// <summary>
/// Applies a series of conditions, and this series may contain Or operators. However, the result can not be followed by an And operator. It can only be an Or operator. /// Applies a series of conditions, and this series may contain Or operators. However, the result can not be followed by an And operator. It can only be an Or operator.
/// </summary>
/// <param name="actionsWithOr"></param>
/// <returns></returns>
public AacFlTransitionContinuationOnlyOr When(Action<AacFlNewTransitionContinuation> actionsWithOr) public AacFlTransitionContinuationOnlyOr When(Action<AacFlNewTransitionContinuation> actionsWithOr)
{ {
actionsWithOr(this); actionsWithOr(this);
return AsContinuationOnlyOr(); return AsContinuationOnlyOr();
} }
/// <summary>
/// Applies a series of conditions, and this series may contain Or operators. All And operators that follow will apply to all the conditions generated by this series, until the next Or operator. /// Applies a series of conditions, and this series may contain Or operators. All And operators that follow will apply to all the conditions generated by this series, until the next Or operator.
/// </summary>
/// <param name="actionsWithOr"></param>
/// <returns></returns>
public AacFlMultiTransitionContinuation When(IAacFlOrCondition actionsWithOr) public AacFlMultiTransitionContinuation When(IAacFlOrCondition actionsWithOr)
{ {
var pendingContinuations = actionsWithOr.ApplyTo(this); var pendingContinuations = actionsWithOr.ApplyTo(this);
return new AacFlMultiTransitionContinuation(Transition, _machine, _sourceNullableIfAny, _destinationNullableIfExits, pendingContinuations); return new AacFlMultiTransitionContinuation(Transition, _machine, _sourceNullableIfAny, _destinationNullableIfExits, pendingContinuations);
} }
/// Provides a handle to start defining conditions using the And operator, for use in loops. The Or operator may be invoked at any point.
public AacFlTransitionContinuation WhenConditions() public AacFlTransitionContinuation WhenConditions()
{ {
return AsContinuationWithOr(); return AsContinuationWithOr();
@@ -12,6 +12,8 @@ namespace AnimatorAsCode.V1
internal static class AacInternals internal static class AacInternals
{ {
internal const string AutoGeneratedPrefix = "zAutogenerated/"; internal const string AutoGeneratedPrefix = "zAutogenerated/";
// The legacy prefix is preserved, because we need to still be able to clean up
// assets generated using that legacy prefix from previous versions.
internal const string AutoGeneratedLegacyPrefix = "zAutogenerated__"; internal const string AutoGeneratedLegacyPrefix = "zAutogenerated__";
internal static AnimatorController NewAnimatorController(AacConfiguration component, string suffix) internal static AnimatorController NewAnimatorController(AacConfiguration component, string suffix)