add AacFlParameter<TParam> and AacFlNumericParameter<TParam>

in order to simplify the maintenance of extension methods
This commit is contained in:
galister
2022-12-16 22:43:52 +01:00
parent b9c7211867
commit 8b41ec953e
3 changed files with 100 additions and 61 deletions
+34 -3
View File
@@ -49,15 +49,36 @@ namespace AnimatorAsCode.V0
} }
} }
public class AacFlFloatParameter : AacFlParameter public abstract class AacFlParameter<TParam> : AacFlParameter
{
protected AacFlParameter(string name) : base(name)
{
}
protected internal abstract float ValueToFloat(TParam value);
}
public abstract class AacFlNumericParameter<TParam> : AacFlParameter<TParam>
{
protected AacFlNumericParameter(string name) : base(name)
{
}
}
public class AacFlFloatParameter : AacFlNumericParameter<float>
{ {
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) { }
public IAacFlCondition IsGreaterThan(float other) => Just(condition => condition.Add(Name, Greater, other)); public IAacFlCondition IsGreaterThan(float other) => Just(condition => condition.Add(Name, Greater, other));
public IAacFlCondition IsLessThan(float other) => Just(condition => condition.Add(Name, Less, other)); public IAacFlCondition IsLessThan(float other) => Just(condition => condition.Add(Name, Less, other));
protected internal override float ValueToFloat(float value)
{
return value;
}
} }
public class AacFlIntParameter : AacFlParameter public class AacFlIntParameter : AacFlNumericParameter<int>
{ {
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) { }
@@ -65,6 +86,11 @@ namespace AnimatorAsCode.V0
public IAacFlCondition IsLessThan(int other) => Just(condition => condition.Add(Name, Less, other)); public IAacFlCondition IsLessThan(int other) => Just(condition => condition.Add(Name, Less, 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));
public IAacFlCondition IsNotEqualTo(int other) => Just(condition => condition.Add(Name, NotEqual, other)); public IAacFlCondition IsNotEqualTo(int other) => Just(condition => condition.Add(Name, NotEqual, other));
protected internal override float ValueToFloat(int value)
{
return value;
}
} }
public class AacFlEnumIntParameter<TEnum> : AacFlIntParameter where TEnum : Enum public class AacFlEnumIntParameter<TEnum> : AacFlIntParameter where TEnum : Enum
@@ -78,7 +104,7 @@ namespace AnimatorAsCode.V0
public IAacFlCondition IsNotEqualTo(TEnum other) => IsNotEqualTo((int)(object)other); public IAacFlCondition IsNotEqualTo(TEnum other) => IsNotEqualTo((int)(object)other);
} }
public class AacFlBoolParameter : AacFlParameter public class AacFlBoolParameter : AacFlParameter<bool>
{ {
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) { }
@@ -86,6 +112,11 @@ namespace AnimatorAsCode.V0
public IAacFlCondition IsFalse() => Just(condition => condition.Add(Name, IfNot, 0)); public IAacFlCondition IsFalse() => Just(condition => condition.Add(Name, IfNot, 0));
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));
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));
protected internal override float ValueToFloat(bool value)
{
return value ? 1f : 0f;
}
} }
public class AacFlFloatParameterGroup public class AacFlFloatParameterGroup
@@ -6,73 +6,54 @@ namespace AnimatorAsCode.V0.Extensions.VRChat
{ {
public static class VRChatExtensions public static class VRChatExtensions
{ {
public static TNode Drives<TNode>(this TNode node,AacFlIntParameter parameter, int value) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Set <i>parameter</i> to a given <i>value</i>. For unsynced parameters, also see <i>DrivingLocally</i>.
/// </summary>
public static TNode Drives<TNode, TParam>(this TNode node, AacFlParameter<TParam> parameter, TParam value) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
{ {
type = VRC_AvatarParameterDriver.ChangeType.Set, type = VRC_AvatarParameterDriver.ChangeType.Set,
name = parameter.Name, value = value name = parameter.Name, value = parameter.ValueToFloat(value)
}); });
return node; return node;
} }
public static TNode Drives<TNode>(this TNode node,AacFlFloatParameter parameter, float value) where TNode : AacAnimatorNode<TNode> /// <summary>
{ /// Set <i>parameter</i> by increasing its current value by <i>additiveValue</i>.
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); /// </summary>
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter public static TNode DrivingIncreases<TNode, TParam>(this TNode node, AacFlParameter<TParam> parameter, TParam additiveValue) where TNode : AacAnimatorNode<TNode>
{
type = VRC_AvatarParameterDriver.ChangeType.Set,
name = parameter.Name, value = value
});
return node;
}
public static TNode DrivingIncreases<TNode>(this TNode node,AacFlFloatParameter parameter, float additiveValue) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
{ {
type = VRC_AvatarParameterDriver.ChangeType.Add, type = VRC_AvatarParameterDriver.ChangeType.Add,
name = parameter.Name, value = additiveValue name = parameter.Name, value = parameter.ValueToFloat(additiveValue)
}); });
return node; return node;
} }
public static TNode DrivingDecreases<TNode>(this TNode node,AacFlFloatParameter parameter, float positiveValueToDecreaseBy) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Set <i>parameter</i> by decreasing its current value by <i>positiveValueToDecreaseBy</i>.
/// </summary>
public static TNode DrivingDecreases<TNode, TParam>(this TNode node, AacFlParameter<TParam> parameter, TParam positiveValueToDecreaseBy) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
{ {
type = VRC_AvatarParameterDriver.ChangeType.Add, type = VRC_AvatarParameterDriver.ChangeType.Add,
name = parameter.Name, value = -positiveValueToDecreaseBy name = parameter.Name,
}); value = parameter.ValueToFloat(positiveValueToDecreaseBy) * -1
return node;
}
public static TNode DrivingIncreases<TNode>(this TNode node,AacFlIntParameter parameter, int additiveValue) where TNode : AacAnimatorNode<TNode>
{
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
{
type = VRC_AvatarParameterDriver.ChangeType.Add,
name = parameter.Name, value = additiveValue
});
return node;
}
public static TNode DrivingDecreases<TNode>(this TNode node,AacFlIntParameter parameter, int positiveValueToDecreaseBy) where TNode : AacAnimatorNode<TNode>
{
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
{
type = VRC_AvatarParameterDriver.ChangeType.Add,
name = parameter.Name, value = -positiveValueToDecreaseBy
}); });
return node; return node;
} }
public static TNode DrivingRemaps<TNode>(this TNode node, AacFlParameter sourceParameter, float sourceMin, float sourceMax, AacFlParameter destParameter, float destMin, float destMax) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Copies <i>sourceParameter</i> to <i>destParameter</i> with the given custom ranges.
/// https://docs.vrchat.com/docs/state-behaviors#copy
/// </summary>
public static TNode DrivingRemaps<TNode, TSource, TDest>(this TNode node, AacFlParameter<TSource> sourceParameter, TSource sourceMin, TSource sourceMax, AacFlParameter<TDest> destParameter, TDest destMin, TDest destMax) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.EnsureParameter(new VRC_AvatarParameterDriver.Parameter driver.EnsureParameter(new VRC_AvatarParameterDriver.Parameter
@@ -81,15 +62,19 @@ namespace AnimatorAsCode.V0.Extensions.VRChat
type = VRC_AvatarParameterDriver.ChangeType.Copy, type = VRC_AvatarParameterDriver.ChangeType.Copy,
source = sourceParameter.Name, source = sourceParameter.Name,
convertRange = true, convertRange = true,
sourceMin = sourceMin, sourceMin = sourceParameter.ValueToFloat(sourceMin),
sourceMax = sourceMax, sourceMax = sourceParameter.ValueToFloat(sourceMax),
destMin = destMin, destMin = destParameter.ValueToFloat(destMin),
destMax = destMax destMax = destParameter.ValueToFloat(destMax)
}); });
return node; return node;
} }
public static TNode DrivingCopies<TNode>(this TNode node, AacFlParameter sourceParameter, AacFlParameter destParameter) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Copies <i>sourceParameter</i> to <i>destParameter</i> with no custom ranges.
/// https://docs.vrchat.com/docs/state-behaviors#copy
/// </summary>
public static TNode DrivingCopies<TNode, TSource, TDest>(this TNode node, AacFlParameter<TSource> sourceParameter, AacFlParameter<TDest> destParameter) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.EnsureParameter(new VRC_AvatarParameterDriver.Parameter driver.EnsureParameter(new VRC_AvatarParameterDriver.Parameter
@@ -101,19 +86,29 @@ namespace AnimatorAsCode.V0.Extensions.VRChat
return node; return node;
} }
public static TNode DrivingRandomizesLocally<TNode>(this TNode node,AacFlFloatParameter parameter, float min, float max) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Sets <i>parameter</i> to a random value between <i>min</i> and <i>max</i>.
/// This is only ran for the person wearing the avatar, and usually needs to be backed by a synced variable.
/// https://docs.vrchat.com/docs/state-behaviors#random
/// </summary>
public static TNode DrivingRandomizesLocally<TNode, TParam>(this TNode node, AacFlNumericParameter<TParam> parameter, TParam min, TParam max) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
{ {
type = VRC_AvatarParameterDriver.ChangeType.Random, type = VRC_AvatarParameterDriver.ChangeType.Random,
name = parameter.Name, valueMin = min, valueMax = max name = parameter.Name, valueMin = parameter.ValueToFloat(min), valueMax = parameter.ValueToFloat(max)
}); });
driver.localOnly = true; driver.localOnly = true;
return node; return node;
} }
public static TNode DrivingRandomizesLocally<TNode>(this TNode node,AacFlBoolParameter parameter, float chance) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Sets <i>parameter</i> to either true or false, with the given <i>chance</i>.
/// This is only ran for the person wearing the avatar, and usually needs to be backed by a synced variable.
/// https://docs.vrchat.com/docs/state-behaviors#random
/// </summary>
public static TNode DrivingRandomizesLocally<TNode>(this TNode node, AacFlBoolParameter parameter, float chance) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
@@ -124,25 +119,35 @@ namespace AnimatorAsCode.V0.Extensions.VRChat
driver.localOnly = true; driver.localOnly = true;
return node; return node;
} }
public static TNode DrivingRandomizesLocally<TNode>(this TNode node,AacFlIntParameter parameter, int min, int max) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Sets <i>parameter</i> to a random value between <i>min</i> and <i>max</i>.
/// For use with unsynced parameters. <b>Warning: The resulting value will be different for everyone seeing your avatar.</b>
/// https://docs.vrchat.com/docs/state-behaviors#random
/// </summary>
public static TNode DrivingRandomizesUnsynced<TNode, TParam>(this TNode node, AacFlNumericParameter<TParam> parameter, TParam min, TParam max) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
{ {
type = VRC_AvatarParameterDriver.ChangeType.Random, type = VRC_AvatarParameterDriver.ChangeType.Random,
name = parameter.Name, valueMin = min, valueMax = max name = parameter.Name, valueMin = parameter.ValueToFloat(min), valueMax = parameter.ValueToFloat(max)
}); });
driver.localOnly = true;
return node; return node;
} }
public static TNode Drives<TNode>(this TNode node,AacFlBoolParameter parameter, bool value) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Sets <i>parameter</i> to either true or false, with the given <i>chance</i>.
/// For use with unsynced parameters. <b>Warning: The resulting value will be different for everyone seeing your avatar.</b>
/// https://docs.vrchat.com/docs/state-behaviors#random
/// </summary>
public static TNode DrivingRandomizesUnsynced<TNode>(this TNode node, AacFlBoolParameter parameter, float chance) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter
{ {
name = parameter.Name, value = value ? 1 : 0 type = VRC_AvatarParameterDriver.ChangeType.Random,
name = parameter.Name, chance = chance
}); });
return node; return node;
} }
@@ -159,11 +164,14 @@ namespace AnimatorAsCode.V0.Extensions.VRChat
} }
return node; return node;
} }
public static TNode DrivingLocally<TNode>(this TNode node, bool wantLocal = true) where TNode : AacAnimatorNode<TNode> /// <summary>
/// Only set this parameter for the person wearing the avatar (recommended for synced parameters).
/// </summary>
public static TNode DrivingLocally<TNode>(this TNode node) where TNode : AacAnimatorNode<TNode>
{ {
var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>(); var driver = node.EnsureBehaviour<VRCAvatarParameterDriver>();
driver.localOnly = wantLocal; driver.localOnly = true;
return node; return node;
} }
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 15c8f3e3d106998769a5066411470ac1 guid: bf8bc1a5fededc2d9a9ced46f1eb94f9
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2