Parameter Setters
TL;DR: All write paths converge on AvatarAnimatorManager.SetParameter, which respects the read-only flag (core parameters can’t be written from outside the engine), the curve-controlled flag, and bumps AASParameterChangedSinceLastSync = true when a synced parameter is modified. PlayerSetup.ChangeAnimatorParam is the central dispatcher used by OSC, the AAS menu UI, and most scripting paths.
Mechanisms
Section titled “Mechanisms”| Mechanism | Source file | Effect |
|---|---|---|
OSC /avatar/parameters/<name> | ABI_RC.Systems.OSC.Modules/OSCAvatarModule.cs (HandleIncoming) | Writes int / float / bool / null. Null is treated as 1.0. Floats also dual-write to face tracking — see OSC Face Tracking. |
| AAS menu UI | ABI_RC.Core.InteractionSystem/CVR_MenuManager.cs (SendAdvancedAvatarUpdate) | Sliders, colour pickers, dropdowns in the Big Menu’s Avatar tab. Pushes values into AdvAvatarUpdateQueue for the player loop to drain. |
| Profiles | ABI_RC.Core.Util.AnimatorManager/AvatarAnimatorManager.cs (ApplyAdvancedSettingsFileProfile) | Loads a list of CVRAdvancedSettingsFileProfileValue and writes each. Also notifies the menu via SendAdvancedAvatarUpdate(name, value, markChange: false). |
CVRParameterStream | ABI.CCK.Components/CVRParameterStreamEntry.cs | Pipes a data source into an animator/variable-buffer/custom-float/avatar-animator parameter. |
CVRAnimatorDriver | ABI.CCK.Components/CVRAnimatorDriver.cs | World-authored component that writes a list of animator parameters when an AnimatorDriverTask fires. |
CVRSpawnable (syncValues) | ABI.CCK.Components/CVRSpawnable.cs | Spawnables sync their own syncValues to remote clients. This is a separate pipeline from avatar AAS — name/value pairs propagate per-spawnable, not via the avatar’s 3200-bit budget. |
NAK.Contacts.ContactAnimator | NAK.Contacts/ContactAnimator.cs | A ContactReceiver companion that writes info.targetValue into a named animator parameter on every enter / update / exit. Routes through Animator.SetFloat/SetInteger/SetBool based on parameter type. |
Koneko.Sensors.Sensor | Koneko.Sensors/Sensor.cs | Writes parameters when its volume detects something. Drives Distance, BoxDistance, SignedDistance.x/y/z, Rotation.x/y/z, and named per-target int/float/bool values. |
| Lua scripts | ABI.Scripting.CVRSTL.Common.Modules/CVR_CCKLuaModule.cs | Lua can read/write animator parameters via the bound API surface (subject to the access manager). |
| WASM scripts | CVR.CCK.Wasm/Scripting/Links/WasmBinder/UnityEngine/AnimatorLinks.cs | Sandboxed scripts can call Animator.SetBool/SetFloat/SetInteger/SetTrigger and the matching Get* methods on any animator they have access to. |
PlayerSetup.ChangeAnimatorParam | ABI_RC.Core.Player/PlayerSetup.cs (line 1259) | Central dispatcher used by OSC, the AAS UI, scripting, and modders. Tracks a ParameterChangeSource (Default, MainMenu, OSC, QuickMenu). |
The central dispatcher
Section titled “The central dispatcher”public void ChangeAnimatorParam(string parameterName, float value, ParameterChangeSource source = ParameterChangeSource.Default){ base.AnimatorManager.SetParameter(parameterName, value); if (source == ParameterChangeSource.Default || source == ParameterChangeSource.MainMenu || source == ParameterChangeSource.OSC) { CVR_MenuManager.Instance.SendAdvancedAvatarUpdate(parameterName, value); } if (source == ParameterChangeSource.QuickMenu || source == ParameterChangeSource.OSC) { ViewManager.Instance.OnAdvancedAvatarUpdate(); }}ParameterChangeSource controls which secondary listener is notified — the AAS dropdown menu, the Quick Menu, or both. The actual write goes through AvatarAnimatorManager.SetParameter, which means core parameters are silently dropped by this entry point.
Read-only protection
Section titled “Read-only protection”AvatarAnimatorManager.SetParameter(name, …) (inherited from CVRAnimatorManager) checks:
if (Parameters.TryGetValue(name, out var p) && p.isValid && !p.IsReadOnly){ ParameterChanged = true; SetParameter_Internal(p, value);}AvatarParam.IsReadOnly returns true when:
- the parameter is curve-controlled (
isControlledByCurve) - the parameter is in
AvatarDefinitions.CoreParameters
That covers the 22 core names. To write MovementX, Grounded, etc., the engine uses the typed properties on AvatarAnimatorManager (MovementX = 1f;) — those call SetParameter_Internal directly and bypass the read-only check.
Swimming and AFK are [Obsolete] and not in CoreParameters, so they go through SetParameter like any other custom parameter — that’s why the engine can write to them and so can a mod, but they’re never sent on the wire.
Sync side effects
Section titled “Sync side effects”When SetParameter_Internal writes through SetFloat/Int/Bool_Animator (the AvatarAnimatorManager overrides):
int hash = param.nameHash;if (_aasOutboundIndicesFloat.ContainsKey(hash) && idx < _aasOutboundCacheFloat.Count){ _aasOutboundCacheFloat[idx] = value; AASParameterChangedSinceLastSync = true;}So writes to AAS-tracked parameters bump the cache and the dirty flag, and the next sync tick will broadcast them. Local-only parameters (including triggers and #-prefixed names) skip this step.
Triggers are special: when isTrigger is true, the AAS bool cache update is skipped entirely. The trigger’s effect is purely local and never serialized.
OSC dispatch path
Section titled “OSC dispatch path”OSCAvatarModule.RegisterQueues registers four delegates on the OSC payload queues. Each one looks the parameter up by nameHash in AvatarAnimatorManager.ParametersHash and routes through ChangeAnimatorParam:
_avatarFloatParamQueue = OSCJobSystem.RegisterQueue(8192, payload =>{ if (AvatarAnimatorManager.ParametersHash.TryGetValue(payload.NameHash, out var p)) { PlayerSetup.Instance.ChangeAnimatorParam(p.name, payload.FloatValue, PlayerSetup.ParameterChangeSource.OSC); OnIncomingAvatarFloatOSCParameter?.Invoke(p.name, payload.FloatValue); }});Bool and int values follow the same shape; null values dispatch as 1.0 (so OSC null becomes a “trigger pulse” of value 1). The OnIncomingAvatar*OSCParameter events are public hooks for mods that need to observe OSC writes.