All-in-One Solution for Indie Game Development · Empowering Indie Developers' Dreams
Documentation · Quick Start · QQ Group · Language: **English** · 简体中文 · 繁體中文 · 日本語 · 한국어
- Sound Groups — Organize sounds into named groups (BGM, SFX, Voice, etc.) with independent volume, mute, and agent count settings
- Priority-based Playback — Async playback via UniTask with automatic low-priority eviction when all agents are busy
- Full Lifecycle Control — Play, stop, pause, resume with optional fade-in/fade-out durations
- Spatial Audio — Bind sounds to game entities or place them at specific world positions
- AudioMixer Integration — Route sound groups to specific AudioMixer groups for fine-grained mixing
- Event-driven Notifications — Success, failure, and update events dispatched through the GameFrameX Event system
- Reference Pooling — All event args and play parameters are pooled to minimize GC allocation
-
Add to
manifest.jsondependencies:{"com.gameframex.unity.sound": "https://github.com/GameFrameX/com.gameframex.unity.sound.git"} -
Unity Package Manager →
Add package from git URL: https://github.com/GameFrameX/com.gameframex.unity.sound.git -
Download and place in your project's
Packagesdirectory.
var sound = GameEntry.GetComponent<SoundComponent>();
// Play a sound in the "BGM" group
int serialId = await sound.PlaySound("Assets/Audio/bgm.mp3", "BGM");
// Stop with fade-out
sound.StopSound(serialId, fadeOutSeconds: 1f);
// Pause / Resume
sound.PauseSound(serialId);
sound.ResumeSound(serialId, fadeInSeconds: 0.5f);
// Set group volume
sound.SetVolume("BGM", 0.5f);For complex play requests, use SoundPlayOptions instead of matching a specific overload:
int serialId = await sound.PlaySound("Assets/Audio/explosion.mp3", "SFX",
new SoundPlayOptions
{
Loop = false,
Volume = 0.8f,
Priority = 5,
BindingEntity = enemyEntity,
FadeInSeconds = 0.2f,
Pitch = 1.2f,
SpatialBlend = 1.0f
});// Bind to an entity — AudioSource follows the entity's transform
int serialId = await sound.PlaySound("Assets/Audio/footstep.mp3", "SFX",
bindingEntity: playerEntity);
// Play at a world position
int serialId = await sound.PlaySound("Assets/Audio/explosion.mp3", "SFX",
worldPosition: explosionPos);// Subscribe via EventComponent
var eventComponent = GameEntry.GetComponent<EventComponent>();
eventComponent.Subscribe(PlaySoundSuccessEventArgs.EventId, OnPlaySuccess);
eventComponent.Subscribe(PlaySoundFailureEventArgs.EventId, OnPlayFailure);
void OnPlaySuccess(object sender, GameEventArgs e)
{
var args = (PlaySoundSuccessEventArgs)e;
Debug.Log($"Sound playing: {args.SoundAssetName}, duration: {args.Duration}s");
}
void OnPlayFailure(object sender, GameEventArgs e)
{
var args = (PlaySoundFailureEventArgs)e;
Debug.LogWarning($"Sound failed: {args.SoundAssetName}, error: {args.ErrorMessage}");
}SoundComponent (MonoBehaviour)
└── SoundManager (engine-agnostic logic)
└── SoundGroup (named group: BGM, SFX, ...)
└── SoundAgent (single voice slot)
└── SoundAgentHelper (AudioSource wrapper)
| Concept | Description |
|---|---|
| SoundGroup | A named collection of agents. Each group has its own volume, mute state, and configurable agent count. |
| SoundAgent | Represents one concurrent voice. The number of agents per group determines how many sounds can play simultaneously. |
| SoundPlayContext | Carries binding entity, world position, and user data for a play request. |
| PlaySoundParams | Pooled parameter object for audio properties (volume, pitch, fade, spatial blend, etc.). |
| Package | Description |
|---|---|
com.gameframex.unity |
Core framework (module system, reference pool, utilities) |
com.gameframex.unity.asset |
Asset loading (YooAsset integration) |
com.gameframex.unity.entity |
Entity system for spatial audio binding |
com.gameframex.unity.event |
Event system for playback notifications |
- QQ Group: Join
See Releases for changelog.
This project is licensed under the MIT License - see the LICENSE file for details.
