SharedVRCStuff/AAC/AACShared/Layers/ParameterPreset.cs
Lillith Rose 1d7052a258 Bring in AAC!
project ive been working on for a while, just felt confident enough to move it here
2025-12-09 21:40:28 -05:00

114 lines
4.6 KiB
C#

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<ParameterPresetDefinition>();
}
public override bool IsApplicable(AACAssets assets)
{
return getDefinitions(assets).Length > 0;
}
private void RunGroup(AACAssets assets, List<ParameterPresetDefinition> 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<string, AacFlParameter<int>> intParams = new();
Dictionary<string, AacFlParameter<float>> floatParams = new();
Dictionary<string, AacFlParameter<bool>> 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<string, List<ParameterPresetDefinition>> groupedPresets = new();
foreach (var preset in presets)
{
if (!groupedPresets.ContainsKey(preset.Group))
{
groupedPresets[preset.Group] = new List<ParameterPresetDefinition>();
}
groupedPresets[preset.Group].Add(preset);
}
foreach (var group in groupedPresets)
{
RunGroup(assets, group.Value);
}
}
}
}