using System; using VRC.SDK3.Avatars.Components; using VRC.SDKBase; namespace AnimatorAsCode.V0.Extensions.VRChat { public static class VrcStateExtensions { public static TNode Drives(this TNode node,AacFlIntParameter parameter, int value) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Set, name = parameter.Name, value = value }); return node; } public static TNode Drives(this TNode node,AacFlFloatParameter parameter, float value) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Set, name = parameter.Name, value = value }); return node; } public static TNode DrivingIncreases(this TNode node,AacFlFloatParameter parameter, float additiveValue) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Add, name = parameter.Name, value = additiveValue }); return node; } public static TNode DrivingDecreases(this TNode node,AacFlFloatParameter parameter, float positiveValueToDecreaseBy) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Add, name = parameter.Name, value = -positiveValueToDecreaseBy }); return node; } public static TNode DrivingIncreases(this TNode node,AacFlIntParameter parameter, int additiveValue) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Add, name = parameter.Name, value = additiveValue }); return node; } public static TNode DrivingDecreases(this TNode node,AacFlIntParameter parameter, int positiveValueToDecreaseBy) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Add, name = parameter.Name, value = -positiveValueToDecreaseBy }); return node; } public static TNode DrivingRandomizesLocally(this TNode node,AacFlFloatParameter parameter, float min, float max) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Random, name = parameter.Name, valueMin = min, valueMax = max }); driver.localOnly = true; return node; } public static TNode DrivingRandomizesLocally(this TNode node,AacFlBoolParameter parameter, float chance) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Random, name = parameter.Name, chance = chance }); driver.localOnly = true; return node; } public static TNode DrivingRandomizesLocally(this TNode node,AacFlIntParameter parameter, int min, int max) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { type = VRC_AvatarParameterDriver.ChangeType.Random, name = parameter.Name, valueMin = min, valueMax = max }); driver.localOnly = true; return node; } public static TNode Drives(this TNode node,AacFlBoolParameter parameter, bool value) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { name = parameter.Name, value = value ? 1 : 0 }); return node; } public static TNode Drives(this TNode node,AacFlBoolParameterGroup parameters, bool value) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); foreach (var parameter in parameters.ToList()) { driver.parameters.Add(new VRC_AvatarParameterDriver.Parameter { name = parameter.Name, value = value ? 1 : 0 }); } return node; } public static TNode DrivingLocally(this TNode node) where TNode : AacAnimatorNode { var driver = node.EnsureBehaviour(); driver.localOnly = true; return node; } public static TNode PrintsToLogUsingTrackingBehaviour(this TNode node, string value) where TNode : AacAnimatorNode { var tracking = node.EnsureBehaviour(); tracking.debugString = value; return node; } public static TNode TrackingTracks(this TNode node, TrackingElement element) where TNode : AacAnimatorNode { var tracking = node.EnsureBehaviour(); SettingElementTo(tracking, element, VRC_AnimatorTrackingControl.TrackingType.Tracking); return node; } public static TNode TrackingAnimates(this TNode node, TrackingElement element) where TNode : AacAnimatorNode { var tracking = node.EnsureBehaviour(); SettingElementTo(tracking, element, VRC_AnimatorTrackingControl.TrackingType.Animation); return node; } public static TNode TrackingSets(this TNode node, TrackingElement element, VRC_AnimatorTrackingControl.TrackingType trackingType) where TNode : AacAnimatorNode { var tracking = node.EnsureBehaviour(); SettingElementTo(tracking, element, trackingType); return node; } private static void SettingElementTo(VRCAnimatorTrackingControl tracking, TrackingElement element, VRC_AnimatorTrackingControl.TrackingType target) { switch (element) { case TrackingElement.Head: tracking.trackingHead = target; break; case TrackingElement.LeftHand: tracking.trackingLeftHand = target; break; case TrackingElement.RightHand: tracking.trackingRightHand = target; break; case TrackingElement.Hip: tracking.trackingHip = target; break; case TrackingElement.LeftFoot: tracking.trackingLeftFoot = target; break; case TrackingElement.RightFoot: tracking.trackingRightFoot = target; break; case TrackingElement.LeftFingers: tracking.trackingLeftFingers = target; break; case TrackingElement.RightFingers: tracking.trackingRightFingers = target; break; case TrackingElement.Eyes: tracking.trackingEyes = target; break; case TrackingElement.Mouth: tracking.trackingMouth = target; break; default: throw new ArgumentOutOfRangeException(nameof(element), element, null); } } public static TNode LocomotionEnabled(this TNode node) where TNode : AacAnimatorNode { var locomotionControl = node.EnsureBehaviour(); locomotionControl.disableLocomotion = false; return node; } public static TNode LocomotionDisabled(this TNode node) where TNode : AacAnimatorNode { var locomotionControl = node.EnsureBehaviour(); locomotionControl.disableLocomotion = true; return node; } public static TNode PlayableEnables(this TNode node, VRC_PlayableLayerControl.BlendableLayer blendable, float blendDurationSeconds = 0f) where TNode : AacAnimatorNode { var playable = node.EnsureBehaviour(); PlayableSets(playable, blendable, blendDurationSeconds, 1.0f); return node; } public static TNode PlayableDisables(this TNode node, VRC_PlayableLayerControl.BlendableLayer blendable, float blendDurationSeconds = 0f) where TNode : AacAnimatorNode { var playable = node.EnsureBehaviour(); PlayableSets(playable, blendable, blendDurationSeconds, 0.0f); return node; } public static void PlayableSets(VRCPlayableLayerControl playable, VRC_PlayableLayerControl.BlendableLayer blendable, float blendDurationSeconds, float weight) { playable.layer = blendable; playable.goalWeight = weight; playable.blendDuration = blendDurationSeconds; } public static TNode PoseSpaceEntered(this TNode node, float delaySeconds = 0f) where TNode : AacAnimatorNode { var temporaryPoseSpace = node.EnsureBehaviour(); temporaryPoseSpace.enterPoseSpace = true; temporaryPoseSpace.fixedDelay = true; temporaryPoseSpace.delayTime = delaySeconds; return node; } public static TNode PoseSpaceExited(this TNode node, float delaySeconds = 0f) where TNode : AacAnimatorNode { var temporaryPoseSpace = node.EnsureBehaviour(); temporaryPoseSpace.enterPoseSpace = false; temporaryPoseSpace.fixedDelay = true; temporaryPoseSpace.delayTime = delaySeconds; return node; } public static TNode PoseSpaceEnteredPercent(this TNode node, float delayNormalized) where TNode : AacAnimatorNode { var temporaryPoseSpace = node.EnsureBehaviour(); temporaryPoseSpace.enterPoseSpace = true; temporaryPoseSpace.fixedDelay = false; temporaryPoseSpace.delayTime = delayNormalized; return node; } public static TNode PoseSpaceExitedPercent(this TNode node, float delayNormalized) where TNode : AacAnimatorNode { var temporaryPoseSpace = node.EnsureBehaviour(); temporaryPoseSpace.enterPoseSpace = false; temporaryPoseSpace.fixedDelay = false; temporaryPoseSpace.delayTime = delayNormalized; return node; } } }