Pepper.SFX

Features

Spatial audio and listeners

Shared distance curves, listening points with split-screen panning, Pepper's own Doppler and named sound points on an object.

A car’s engine should fade, dull and narrow as it drives away, come from its exhaust rather than its centre, and still sound right when two players share one screen. Pepper.SFX gives you shared distance assets, listening points you register yourself, and its own panning and Doppler for what one AudioListener can’t do.

How it works

  • Attenuation assets. Curves over metres, shared between sounds: Volume in dB, and optional Low Pass, High Pass and Spread. Set in a container’s 3D Settings, one replaces its Min Distance, Max Distance and Rolloff. Past Max Distance a sound goes virtual (silent, keeping its place). handle.SetAttenuation gives one sound a different asset.
  • Listening points. AddListeningPoint(cameraTransform) tells Pepper where you listen from, so it never searches the scene. Voice importance, occlusion, Doppler and the Distance, Approach Speed and Angle values all read the points. DriveUnityListener keeps Unity’s AudioListener on the primary one.
  • Split screen: Spatial Mode = Pepper. Pepper then pans and attenuates 3D sounds itself, from every point. A sound’s level is the loudest of its attenuation at each point times that point’s Weight (0–1); its pan blends the points, narrowed by each one’s Pan Width (0 = mono). At one point of Weight 1 and Pan Width 1 it sounds the same as Unity’s 3D. SetPrimaryListeningPoint picks the primary point, and changes glide over about 100 ms.
  • Pepper’s Doppler. Set a container’s Doppler to Pepper and pitch follows the closing speed on the listening point, scaled by Doppler Exaggeration (×1 to ×3) and capped by Doppler Max Cents. Virtual voices come back in step with it. AudioEmitter.Teleport() and AudioListeningPoint.ClearVelocity() stop a respawn or camera cut reading as speed.
  • Named points and offsets. An Audio Emitter lists named Points (Exhaust, Intake, RearAxle). car.Post(exhaustEvent, "Exhaust") attaches the sound there. car.Post(impactEvent, localOffset) plays anywhere on the object with the emitter’s values, and handle.SetLocalOffset moves a playing sound, such as a scrape following the contact.

Example

using AudioSystem;
using UnityEngine;

public class SplitScreenCar : MonoBehaviour
{
    [SerializeField] private Transform player1Camera;
    [SerializeField] private Transform player2Camera;
    [SerializeField] private AudioEmitter car;
    [SerializeField] private AudioEvent exhaustEvent;
    [SerializeField] private AudioEvent impactEvent;

    private void Start()
    {
        var manager = AudioManager.Instance;
        manager.SpatialMode = AudioSpatialMode.Pepper;   // before the sounds start

        AudioListeningPoint p1 = manager.AddListeningPoint(player1Camera);
        AudioListeningPoint p2 = manager.AddListeningPoint(player2Camera);
        p1.PanWidth = 0f;   // top and bottom halves: no left and right
        p2.PanWidth = 0f;

        car.Post(exhaustEvent, "Exhaust");   // attached at the car's Exhaust point
    }

    private void OnCollisionEnter(Collision hit)
    {
        Vector3 local = car.transform.InverseTransformPoint(hit.GetContact(0).point);
        car.Post(impactEvent, local);        // at the contact, with the car's values
    }
}

Both cameras become listening points, so a car near either player sounds near. The exhaust rides on the car’s Exhaust point, and each impact plays where the car was hit.

Setting it up

  1. Create > Audio System > Attenuation, shape its curves and set Max Distance.
  2. In a container’s 3D Settings, assign the asset and set Doppler to Pepper if wanted.
  3. Add Component > Audio System > Audio Emitter on the moving object. Add Points and drag them in the Scene view.
  4. For split screen, set the Audio Manager’s Spatial Mode to Pepper.
  5. Register listening points from code at start. In Play mode the Audio Manager inspector lists them.

Good to know

  • Spatial Mode = Pepper has no spatializer plugins (HRTF) and ignores the project’s Doppler Factor. It balances a stereo clip rather than placing it, so give 3D sounds mono clips.
  • Unity’s own AudioSources, such as the ambient system’s, still hear from the AudioListener: keep it on the primary point with DriveUnityListener.
  • Changing Spatial Mode affects sounds started after the change.
  • With no listening point registered, Pepper searches for an AudioListener and warns once.
  • With Spatial Mode = Unity, Attenuation curves are handed to Unity when a sound starts, so Play-mode edits reach a playing sound only when it is posted again.

Learn more