using System.Collections.Generic; using AnimatorAsCode.V1; using AnimatorAsCode.V1.VRC; using gay.lilyy.aaccore; using gay.lilyy.aacshared.runtimecomponents; using UnityEditor; using UnityEngine; using VRC.SDK3.Avatars.ScriptableObjects; namespace gay.lilyy.aacshared.layers { [InitializeOnLoad] public class ParameterPreset : LayerGroup { private static readonly ParameterPreset _instance = new(); static ParameterPreset() { } public override string DisplayName => "Parameter Preset"; public override string SystemName => "parameter_preset"; public override bool shouldWarnIfNotApplicable => false; private static ParameterPresetDefinition[] getDefinitions(AACAssets assets) { return assets.ctx.AvatarRootObject.GetComponents(); } public override bool IsApplicable(AACAssets assets) { return getDefinitions(assets).Length > 0; } private void RunGroup(AACAssets assets, List presets) { if (presets.Count == 0) return; // If there are none in the avatar, skip this entirely. var layer = assets.fx.NewLayer("Presets " + presets[0].Group); var presetParam = layer.IntParameter("Preset " + presets[0].Group); Dictionary> intParams = new(); Dictionary> floatParams = new(); Dictionary> boolParams = new(); var idle = layer.NewState("Idle").WithAnimation(assets.emptyClip); layer.WithDefaultState(idle); var presetIndex = 0; foreach (var preset in presets) { presetIndex++; var state = layer.NewState("Preset " + preset.Name) .WithAnimation(assets.emptyClip); foreach (var param in preset.Parameters) { if (!param.shouldChange) continue; switch (param.valueType) { case VRCExpressionParameters.ValueType.Int: { if (!intParams.ContainsKey(param.name)) { intParams[param.name] = layer.IntParameter(param.name); } var layerParam = intParams[param.name]; state.Drives(layerParam, (int)param.setTo); break; } case VRCExpressionParameters.ValueType.Float: { if (!floatParams.ContainsKey(param.name)) { floatParams[param.name] = layer.FloatParameter(param.name); } var layerParam = floatParams[param.name]; state.Drives(layerParam, param.setTo); break; } case VRCExpressionParameters.ValueType.Bool: { if (!boolParams.ContainsKey(param.name)) { boolParams[param.name] = layer.BoolParameter(param.name); } var layerParam = boolParams[param.name]; state.Drives(layerParam, param.setTo > 0.5f); break; } } } idle.TransitionsTo(state).When(presetParam.IsEqualTo(presetIndex)); state.TransitionsTo(idle).When(presetParam.IsEqualTo(0)); } } public override void Run(AACAssets assets) { var presets = getDefinitions(assets); Dictionary> groupedPresets = new(); foreach (var preset in presets) { if (!groupedPresets.ContainsKey(preset.Group)) { groupedPresets[preset.Group] = new List(); } groupedPresets[preset.Group].Add(preset); } foreach (var group in groupedPresets) { RunGroup(assets, group.Value); } } } }