1. Mixer
在Mixer中分类管理每个音频,按player、UI、enemy等来分类,可以管控不同的音频音量大小。
2. 音频播放
(也可以用AudioSource,但音频太多时不建议) 这里使用AudioClip,只用把音频文件挂上去即可。 代码:
[ Header ( "Sounds" ) ] [ Tooltip ( "Sound played when recieving damages" ) ]
public AudioClip DamageTick;
挂上效果: 播放代码:
if ( DamageTick && ! m_WasDamagedThisFrame)
AudioUtility. CreateSFX ( DamageTick, transform. position, AudioUtility. AudioGroups. DamageTick, 0f ) ;
3. AudioUtility.cs和AudioManager.cs
using UnityEngine;
using UnityEngine. Audio;
namespace Unity. FPS. Game
{
public class AudioUtility
{
static AudioManager s_AudioManager;
public enum AudioGroups
{
DamageTick,
Impact,
EnemyDetection,
Pickup,
WeaponShoot,
WeaponOverheat,
WeaponChargeBuildup,
WeaponChargeLoop,
HUDVictory,
HUDObjective,
EnemyAttack
}
public static void CreateSFX ( AudioClip clip, Vector3 position, AudioGroups audioGroup, float spatialBlend,
float rolloffDistanceMin = 1f )
{
GameObject impactSfxInstance = new GameObject ( ) ;
impactSfxInstance. transform. position = position;
AudioSource source = impactSfxInstance. AddComponent < AudioSource > ( ) ;
source. clip = clip;
source. spatialBlend = spatialBlend;
source. minDistance = rolloffDistanceMin;
source. Play ( ) ;
source. outputAudioMixerGroup = GetAudioGroup ( audioGroup) ;
TimedSelfDestruct timedSelfDestruct = impactSfxInstance. AddComponent < TimedSelfDestruct > ( ) ;
timedSelfDestruct. LifeTime = clip. length;
}
public static AudioMixerGroup GetAudioGroup ( AudioGroups group )
{
if ( s_AudioManager == null )
s_AudioManager = GameObject. FindObjectOfType < AudioManager > ( ) ;
var groups = s_AudioManager. FindMatchingGroups ( group . ToString ( ) ) ;
if ( groups. Length > 0 )
return groups[ 0 ] ;
Debug. LogWarning ( "Didn't find audio group for " + group . ToString ( ) ) ;
return null ;
}
public static void SetMasterVolume ( float value )
{
if ( s_AudioManager == null )
s_AudioManager = GameObject. FindObjectOfType < AudioManager > ( ) ;
if ( value <= 0 )
value = 0.001f ;
float valueInDb = Mathf. Log10 ( value ) * 20 ;
s_AudioManager. SetFloat ( "MasterVolume" , valueInDb) ;
}
public static float GetMasterVolume ( )
{
if ( s_AudioManager == null )
s_AudioManager = GameObject. FindObjectOfType < AudioManager > ( ) ;
s_AudioManager. GetFloat ( "MasterVolume" , out var valueInDb) ;
return Mathf. Pow ( 10f , valueInDb / 20.0f ) ;
}
}
}
using UnityEngine;
using UnityEngine. Audio;
namespace Unity. FPS. Game
{
public class AudioManager : MonoBehaviour
{
public AudioMixer[ ] AudioMixers;
public AudioMixerGroup[ ] FindMatchingGroups ( string subPath)
{
for ( int i = 0 ; i < AudioMixers. Length; i++ )
{
AudioMixerGroup[ ] results = AudioMixers[ i] . FindMatchingGroups ( subPath) ;
if ( results != null && results. Length != 0 )
{
return results;
}
}
return null ;
}
public void SetFloat ( string name, float value )
{
for ( int i = 0 ; i < AudioMixers. Length; i++ )
{
if ( AudioMixers[ i] != null )
{
AudioMixers[ i] . SetFloat ( name, value ) ;
}
}
}
public void GetFloat ( string name, out float value )
{
value = 0f ;
for ( int i = 0 ; i < AudioMixers. Length; i++ )
{
if ( AudioMixers[ i] != null )
{
AudioMixers[ i] . GetFloat ( name, out value ) ;
break ;
}
}
}
}
}
4. AudioUtility中的延时销毁函数
using UnityEngine;
namespace Unity. FPS. Game
{
public class TimedSelfDestruct : MonoBehaviour
{
public float LifeTime = 1f ;
float m_SpawnTime;
void Awake ( )
{
m_SpawnTime = Time. time;
}
void Update ( )
{
if ( Time. time > m_SpawnTime + LifeTime)
{
Destroy ( gameObject) ;
}
}
}
}