Guidance / API reference
Parameters
Explained in USER_GUIDE Manual §3.4. A sound reads a parameter’s value from its play (handle), else its emitter, else the global scope, else the parameter’s default.
AudioParameter
Namespace: AudioSystem
Inheritance: ScriptableObject
Menu: Create > Audio System > Parameter
| Field | Description |
|---|---|
valueFrom |
Where the value comes from: Game (default: set by code, in three scopes), or a built-in Pepper works out per sound: Distance (m to the listening point), ApproachSpeed (m/s closing, + coming closer, eased over 50 ms), Angle (° on the horizontal plane: 0 ahead, + right, ±180 behind). A built-in ignores game writes (one warning per asset), clamps to the range, has no smoothing, and reads its default where there is no sound to measure. |
parameterName |
The name it answers to in the string API and in Blends that name a parameter. Empty = the asset’s name. |
unitLabel |
Display only: RPM, m/s, 0-1. |
minValue, maxValue |
The range. Values are clamped when read, kept as written. One warning per asset for a write outside it. |
defaultValue |
Read when no scope has a value. |
slew |
Smoothing: how fast what sounds hear follows a written value (ParameterSlew). Applies to writes through the asset, in every scope separately. The string API is never smoothed. |
bypassSlewWhile |
Optional on/off parameter: while it reads 0.5 or more in the same scope, the smoothing is skipped. |
public string ParameterName { get; } // parameterName, or the asset's name when empty
public string UnitLabel { get; }
public float Min { get; } // swapped min/max are read the right way round
public float Max { get; }
public float Default { get; } // clamped to the range
public ParameterSlew Slew { get; }
public AudioParameter BypassSlewWhile { get; }
public ParameterSource ValueFrom { get; } // Game, Distance, ApproachSpeed, Angle
public bool IsBuiltIn { get; } // ValueFrom isn't Game
public float Clamp(float value)
AudioAttenuation
Namespace: AudioSystem
Inheritance: ScriptableObject
Menu: Create > Audio System > Attenuation
How a 3D sound changes with distance from the listening point, shared between containers (USER_GUIDE §4.1, “Attenuation assets”). Set in a container’s 3D Settings, where it replaces Min Distance, Max Distance and Rolloff; children take it with Uses Parent Positioning.
| Field | Description |
|---|---|
maxDistance (m) |
Where the curves end. Past it a voice is made virtual (with LOD on), and real again inside 95% of it. The curves’ last values hold beyond it. |
volumeDb |
Volume in dB against metres. Default: 0 dB to 2 m, −6 dB per doubling, −60 dB at 100 m, straight lines between keys. |
lowPass, lowPassHz |
Optional low-pass cutoff in Hz against metres (octaves between keys). |
highPass, highPassHz |
Optional high-pass cutoff in Hz against metres. |
spread, spreadCurve |
Optional spread 0 (a point) to 1 (fully wide) against metres. |
public float MaxDistance { get; }
public AnimationCurve VolumeDb { get; }
public bool UsesLowPass { get; } public AnimationCurve LowPassHz { get; }
public bool UsesHighPass { get; } public AnimationCurve HighPassHz { get; }
public bool UsesSpread { get; } public AnimationCurve Spread { get; }
public bool HasFilters { get; } // low- or high-pass on: its voices are updated every frame
public float VolumeDbAt(float metres)
public float GainAt(float metres) // linear 0..1
public float LowPassAt(float metres) // open (22000) when off
public float HighPassAt(float metres) // open (10) when off
public float SpreadAt(float metres) // 0 when off
How it plays (Unity spatial mode, the default). A 3D voice with an asset plays with rolloffMode = Custom, maxDistance = the asset’s, and the volume and spread curves converted to Unity’s custom curves (AudioSource.SetCustomCurve, over distance ÷ Max Distance; spread as angle ÷ 360, so 1 = 180°), set only when the voice’s asset changes. Unity applies them while mixing, from its AudioListener; keep it on the listening point (DriveUnityListener). Pepper sets the low- and high-pass from each voice’s own distance to the listening point every frame (eased about 20 ms), combined with Parameter Curves (lowest low-pass, highest high-pass). The voice’s importance uses GainAt(distance). The pool puts the source back to Logarithmic and spread 0.
ParameterSlew
Namespace: AudioSystem (serializable struct)
public SlewMode mode; // None, Rate, Ease
public float upSeconds; // Ease: seconds to close 95% of a rise (0 = at once)
public float downSeconds; // Ease: seconds to close 95% of a fall
public float upRate; // Rate: units per second rising (0 = at once)
public float downRate; // Rate: units per second falling
public static ParameterSlew None { get; }
public static ParameterSlew Ease(float upSeconds, float downSeconds)
public static ParameterSlew Rate(float upRate, float downRate)
public bool IsSmoothing { get; }
public float Step(float current, float target, float dt) // one step, for tools and tests
Ease moves current += (target - current) * (1 - 0.05^(dt / T)), so the gap closes by 95% every T seconds however the time is split into frames. Rate moves at most rate * dt per step and stops on the target. Smoothing runs in the manager’s per-frame step on unscaled time. The first value a scope gets is heard at once; Snap skips the smoothing.
AudioEmitter
Namespace: AudioSystem
Inheritance: MonoBehaviour (sealed; one per GameObject)
Menu: Add Component > Audio System > Audio Emitter
An object that makes sounds and holds parameter values for them (one car). Sounds posted on it read its values before the global ones.
public AudioHandle Post(AudioEvent audioEvent) // same as audioEvent.Post(this)
public AudioHandle Post(AudioEvent audioEvent, string point) // at a named point; same as audioEvent.Post(this, point)
public AudioHandle Post(AudioEvent audioEvent, int point) // by number (FindPoint); -1 = the origin
public AudioHandle Post(AudioEvent audioEvent, PostValues values) // values for that sound only
public AudioHandle Post(AudioEvent audioEvent, string point, PostValues values)
public AudioHandle Post(AudioEvent audioEvent, Vector3 localOffset, PostValues values = default) // anywhere on it (an impact)
public AudioHandle Post(AudioEvent audioEvent, double startDsp, double startOffsetSeconds,
PostValues values = default) // a moment of the sound at a DSP time (a pass-by)
// Level and pitch against the other emitters (inspector: Volume Offset, Pitch Offset), on every sound on it, now and later
public float VolumeOffsetDb { get; set; } // dB, 0 = as authored; can't lift a sound past full volume
public float PitchOffsetCents { get; set; } // cents, 0 = as recorded
// Random numbers (AudioManager.RandomNumbers = Pepper): this emitter's own sequence
public int RandomSeed { get; } // 0 = a different sequence every run
public void SetRandomSeed(int seed) // start again from seed: the same seed replays the same picks
// Named points: offsets in this object's own space (a car's "Exhaust", "Intake", "FrontAxle")
public IReadOnlyList<EmitterPoint> Points { get; } // EmitterPoint { string name; Vector3 offset; }
public int FindPoint(string point) // its number, or -1 (the first, if two share a name)
public int SetPoint(string point, Vector3 offset) // add, or move an existing one; later posts only
public Vector3 GetPointOffset(int point)
public Vector3 GetPointPosition(int point) // world space, now
// Velocity, shared by every sound on it (read by Approach Speed and Pepper's Doppler)
public Vector3 Velocity { get; } // measured in Pepper's per-frame step, unless given
public void SetVelocity(Vector3 metresPerSecond) // give it yourself (a rigidbody's); stops measuring
public void ClearVelocity() // measure again
public void Teleport() // it jumped (a reset, a respawn): the jump isn't speed
// Switched off or destroyed (inspector: On Disable, Stop Fade Seconds)
public EmitterDisableMode WhenDisabled { get; set; } // Keep (default, as before), Stop, Pause; read at each post
public float StopFadeSeconds { get; set; } // seconds, default 0.1
public void SetParameter(AudioParameter parameter, float value)
public void ClearParameter(AudioParameter parameter)
public void RampParameter(AudioParameter parameter, float target, float seconds)
public void SnapParameter(AudioParameter parameter)
public void SnapAllParameters()
public void SetSlewOverride(AudioParameter parameter, ParameterSlew slew)
public void ClearSlewOverride(AudioParameter parameter)
public bool TryGetParameter(AudioParameter parameter, out float value) // set here, as written
public float GetEffectiveParameter(AudioParameter parameter) // heard now: here, else global, else default; clamped
// Switches (one car's surface); a driven group ignores them, with a warning
public void SetSwitch(AudioSwitchGroup group, string value)
public void ClearSwitch(AudioSwitchGroup group)
public bool TryGetSwitch(AudioSwitchGroup group, out string value) // set here
public string GetEffectiveSwitch(AudioSwitchGroup group) // here, else global, else the Default Value
// For tools: the values on this emitter
public int ParameterCount { get; }
public string GetParameterNameAt(int index)
public float GetParameterValueAt(int index) // as heard now (after smoothing)
public float GetParameterTargetAt(int index) // as written
public bool IsParameterMovingAt(int index) // ramping, smoothing or easing away
public int SwitchCount { get; }
public string GetSwitchGroupAt(int index)
public string GetSwitchValueAt(int index)
// For tools: every Audio Emitter enabled now (the Live View, a game's debug overlay). Don't change it.
public static IReadOnlyList<AudioEmitter> AllEnabled { get; }
SetParameter: the emitter’s sounds follow the value through the parameter’s smoothing; the first value set here is heard at once.ClearParameter: the sounds go back to the global value, easing over if the parameter is smoothed.RampParametermoves the written value in a straight line from the one written before (or what the sounds hear, if none), on unscaled time; smoothing applies on top. A new ramp, a Set, a Snap or a Clear replaces it.SnapParameter/SnapAllParameters: the sounds hear the written value now (a ramp jumps to its end). For a reset or a teleport. Values set on the sounds’ handles have their ownSnapAllParameters.SetSlewOverride: smooth this emitter’s value with other settings than the parameter’s (a per-car attack). Affects this emitter’s value only.
Values work without an AudioManager (an emitter can be set up before one exists); ramps and smoothing need one to advance.
Named points. A sound posted at a point is attached to the emitter at the point’s offset (in its own space, so its scale applies), its later voices too (a Sequence’s next clip), so it moves and turns with the object; a 2D container ignores the place. It reads the emitter’s parameter values like any sound on it. An unknown name warns once per name and plays at the origin. SetPoint changes later posts; sounds already playing stay where they were attached. AudioEvent.Post(AudioEmitter, string point, double scheduledDspTime = 0.0) and Post(AudioEmitter, int point, double scheduledDspTime) (the DSP time has no default there: Post(emitter, 1) is the older overload with a DSP time) and AudioManager.Post(audioEvent, emitter, point) do the same. In the inspector, the points are listed and can be dragged in the Scene view while the object is selected.
Posting at an offset (3.1.0-dev.7). Post(evt, localOffset, values) is a named point anywhere: an impact at the contact point, with this emitter’s values, Max Instances Per Emitter, Cooldown Per Emitter and random numbers (AudioEvent.PostAtOffset). A playing sound moves with AudioHandle.SetLocalOffset (a scrape following the contact). Post(evt, startDsp, startOffsetSeconds, values) is AudioEvent’s timed post.
Level and pitch (3.1.0-dev.7). VolumeOffsetDb and PitchOffsetCents reach every sound on the emitter, playing or posted later, through their own gain and pitch slots (GainStack.EmitterGain, PitchStack.Emitter), and compose with a sound’s own offset. Set them in the inspector or from code, also in Play mode. An AudioSource’s volume stops at 1, so a raise can’t lift a sound already at full level.
Teleport (3.1.0-dev.7). After a jump that isn’t motion (a reset to the track, a respawn, a remote car placed), Teleport(): Pepper’s next step takes the new position and measures nothing from the jump, so Approach Speed and Doppler don’t spike. The last velocity stays until a new one is measured; a velocity given with SetVelocity is kept. It doesn’t touch parameter values: call SnapAllParameters too if they jump.
Switched off or destroyed. WhenDisabled (EmitterDisableMode):
Keep(default): as before 3.1. 3D sounds are attached to the object: switched off, Unity stops them with it (a loop is never reclaimed); destroyed, they are cut with a warning and Pepper rebuilds their voices.Stop: switched off or destroyed, every sound posted on it fades out overStopFadeSecondswhere it is, with whatever it was still going to start (Delay actions, a Sequence’s next clip), and goes back to the pool.Pause: switched off, its sounds fade out over about 25 ms and hold their place, keeping no real voice; switched on, they carry on from there, in phase. Destroyed, they stop with the fade.
With Stop or Pause, its sounds aren’t attached: they follow the object (position and rotation, at their point), moved by Pepper every frame after every LateUpdate and before Unity mixes, so a fade can outlive the object. While it is off, posts on it return a finished handle and play nothing. The setting is read at each post; sounds already playing keep the way they were attached.
Example:
AudioEmitter car = GetComponent<AudioEmitter>();
AudioHandle engine = car.Post(engineEvent);
car.SetParameter(rpm, 4200f); // only this car's engine
car.WhenDisabled = EmitterDisableMode.Stop; // removed from car select: its sounds fade out, not cut
public enum EmitterDisableMode { Keep, Stop, Pause }
AudioSwitchGroup
Namespace: AudioSystem
Inheritance: ScriptableObject
Menu: Create > Audio System > Switch Group
A switch that Switch Containers read (a surface, a weather), with its values. A sound reads its handle’s value, else its emitter’s, else the global one, else Default (USER_GUIDE §4.5).
| Field | Description |
|---|---|
groupName |
The name it answers to in the string API (AudioManager.SetSwitch, state and event actions) and in Switches that name a group. Empty = the asset’s name. |
values |
The values it can take. Switch inspectors offer them; a value set that isn’t here warns once. Empty = any. |
defaultValue |
Read when nothing is set. Empty = none (the Switch plays its Default Container). |
drivenBy |
Optional Parameter asset that picks the value through ranges, read in each sound’s scopes. Values set directly are then ignored, with one warning. |
ranges |
SwitchRange { string value; float from; }: each value from its start up to the next one’s; the first also covers below. Kept sorted. |
hysteresis |
How far past a boundary (in the parameter’s unit) the parameter must go to change the value. Each playing sound remembers its own range. |
public string GroupName { get; }
public IReadOnlyList<string> Values { get; }
public string Default { get; }
public AudioParameter DrivenBy { get; }
public IReadOnlyList<SwitchRange> Ranges { get; }
public float Hysteresis { get; }
public bool IsDriven { get; } // DrivenBy set and at least one range
public bool HasValue(string value) // in Values, or Values is empty
public string ValueFor(float parameterValue) // the ranges, without hysteresis From the Pepper.SFX 3.1 guides (API_REFERENCE.md). Something wrong or unclear? Tell me.