Audio система в процессе
This commit is contained in:
1 parent
b13cf8cfc0
commit
557c4c3dee
10 files changed
+236
-30
No files matched your search
@@ -0,0 +1,23 @@
|
|||||||
|
namespace Code.Audio
|
||||||
|
{
|
||||||
|
public enum SFXSounds
|
||||||
|
{
|
||||||
|
Crowbar,
|
||||||
|
Shot357
|
||||||
|
}
|
||||||
|
public enum UISounds
|
||||||
|
{
|
||||||
|
Crowbar
|
||||||
|
}
|
||||||
|
public enum EnemiesSounds
|
||||||
|
{
|
||||||
|
Bastard,
|
||||||
|
Bravo
|
||||||
|
}
|
||||||
|
public enum DispatcherSounds
|
||||||
|
{
|
||||||
|
Absolutely,
|
||||||
|
AbsolutelyNot,
|
||||||
|
AhFreeman
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 907b506ceac843ebb509a8e5298af540
|
||||||
|
timeCreated: 1762888870
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Code.Configs;
|
using Code.Configs;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
using UnityEngine.AddressableAssets;
|
using UnityEngine.AddressableAssets;
|
||||||
using UnityEngine.Audio;
|
using UnityEngine.Audio;
|
||||||
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace Code.Audio
|
namespace Code.Audio
|
||||||
@@ -10,14 +13,30 @@ namespace Code.Audio
|
|||||||
public class AudioFactory : IAudioFactory
|
public class AudioFactory : IAudioFactory
|
||||||
{
|
{
|
||||||
private AssetReference _audioMixerPrefab;
|
private AssetReference _audioMixerPrefab;
|
||||||
|
private AssetReference _audioSourcePrefab;
|
||||||
|
|
||||||
private AssetReference[] _peacefulSoundtrack;
|
private AssetReference[] _peacefulSoundtrack;
|
||||||
private AssetReference[] _actionSoundtrack;
|
private AssetReference[] _actionSoundtrack;
|
||||||
|
private AssetReference[] _menuSoundtrack;
|
||||||
private AssetReference[] _SFX;
|
private AssetReference[] _SFX;
|
||||||
private AssetReference[] _enemies;
|
private AssetReference[] _enemies;
|
||||||
private AssetReference[] _dispatcher;
|
private AssetReference[] _dispatcher;
|
||||||
private AssetReference[] _character;
|
private AssetReference[] _character;
|
||||||
|
|
||||||
|
private AsyncOperationHandle<IList<AudioClip>> _menuMusicHandle;
|
||||||
|
private AsyncOperationHandle<IList<AudioClip>> _actionMusicHandle;
|
||||||
|
private AsyncOperationHandle<IList<AudioClip>> _peacefulMusicHandle;
|
||||||
|
private AsyncOperationHandle<IList<AudioClip>> _SFXHandle;
|
||||||
|
private AsyncOperationHandle<IList<AudioClip>> _enemiesHandle;
|
||||||
|
private AsyncOperationHandle<IList<AudioClip>> _dispatcherHandle;
|
||||||
|
|
||||||
|
public List<AudioClip> PeacefulMusic { get; private set; }
|
||||||
|
public List<AudioClip> ActionMusic { get; private set; }
|
||||||
|
public List<AudioClip> MenuMusic { get; private set; }
|
||||||
|
public List<AudioClip> SFXAudios { get; private set; }
|
||||||
|
public List<AudioClip> EnemiesAudios { get; private set; }
|
||||||
|
public List<AudioClip> DispatcherAudios { get; private set; }
|
||||||
|
|
||||||
public AudioFactory(AudioMixerConfig audioMixerConfig,
|
public AudioFactory(AudioMixerConfig audioMixerConfig,
|
||||||
SoundtrackListConfig soundtrackListConfig,
|
SoundtrackListConfig soundtrackListConfig,
|
||||||
SFXListConfig sfxListConfig,
|
SFXListConfig sfxListConfig,
|
||||||
@@ -26,15 +45,18 @@ namespace Code.Audio
|
|||||||
CharacterSoundListConfig characterSoundListConfig)
|
CharacterSoundListConfig characterSoundListConfig)
|
||||||
{
|
{
|
||||||
_audioMixerPrefab = audioMixerConfig.audioMixerPrefab;
|
_audioMixerPrefab = audioMixerConfig.audioMixerPrefab;
|
||||||
|
_audioSourcePrefab = audioMixerConfig.audioSourcePrefab;
|
||||||
|
|
||||||
_peacefulSoundtrack = soundtrackListConfig.peacefulSoundtrack;
|
_peacefulSoundtrack = soundtrackListConfig.peacefulSoundtrack;
|
||||||
_actionSoundtrack = soundtrackListConfig.actionSoundtrack;
|
_actionSoundtrack = soundtrackListConfig.actionSoundtrack;
|
||||||
|
_actionSoundtrack = soundtrackListConfig.menuSoundtrack;
|
||||||
_SFX = sfxListConfig.SFX;
|
_SFX = sfxListConfig.SFX;
|
||||||
_enemies = enemiesSoundListConfig.enemies;
|
_enemies = enemiesSoundListConfig.enemies;
|
||||||
_dispatcher = dispatcherSoundListConfig.dispatcher;
|
_dispatcher = dispatcherSoundListConfig.dispatcher;
|
||||||
_character = characterSoundListConfig.character;
|
_character = characterSoundListConfig.character;
|
||||||
}
|
}
|
||||||
public async UniTask<AudioMixer> CreateCanvas()
|
|
||||||
|
public async UniTask<AudioMixer> CreateMixer()
|
||||||
{
|
{
|
||||||
AudioMixer audioMixer = (await Addressables.InstantiateAsync(_audioMixerPrefab).ToUniTask()).GetComponent<AudioMixer>();
|
AudioMixer audioMixer = (await Addressables.InstantiateAsync(_audioMixerPrefab).ToUniTask()).GetComponent<AudioMixer>();
|
||||||
|
|
||||||
@@ -43,10 +65,108 @@ namespace Code.Audio
|
|||||||
return audioMixer;
|
return audioMixer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReleaseMixer()
|
public async UniTaskVoid LoadAudioSourcePrefab(Action<AudioSource> callback) => callback?.Invoke(await Addressables.LoadAssetAsync<AudioSource>(_audioSourcePrefab));
|
||||||
{
|
|
||||||
|
|
||||||
|
public async UniTaskVoid WarmGameplayMusic(Action callback)
|
||||||
|
{
|
||||||
|
_actionMusicHandle = Addressables.LoadAssetsAsync<AudioClip>(_actionSoundtrack, OnActionTrackLoaded);
|
||||||
|
_peacefulMusicHandle = Addressables.LoadAssetsAsync<AudioClip>(_peacefulSoundtrack, OnPeacefulTrackLoaded);
|
||||||
|
|
||||||
|
await UniTask.WhenAll(_actionMusicHandle.ToUniTask(), _peacefulMusicHandle.ToUniTask());
|
||||||
|
|
||||||
|
callback?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ReleaseGameplayMusic()
|
||||||
|
{
|
||||||
|
ActionMusic.Clear();
|
||||||
|
_actionMusicHandle.Release();
|
||||||
|
|
||||||
|
PeacefulMusic.Clear();
|
||||||
|
_peacefulMusicHandle.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async UniTaskVoid WarmMenuMusic(Action callback)
|
||||||
|
{
|
||||||
|
_menuMusicHandle = Addressables.LoadAssetsAsync<AudioClip>(_menuSoundtrack, OnMenuTrackLoaded);
|
||||||
|
|
||||||
|
await _menuMusicHandle.ToUniTask();
|
||||||
|
|
||||||
|
callback?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReleaseMenuMusic()
|
||||||
|
{
|
||||||
|
MenuMusic.Clear();
|
||||||
|
_menuMusicHandle.Release();
|
||||||
|
}
|
||||||
|
public async UniTaskVoid WarmSFX(Action callback)
|
||||||
|
{
|
||||||
|
_SFXHandle = Addressables.LoadAssetsAsync<AudioClip>(_SFX, OnSFXLoaded);
|
||||||
|
|
||||||
|
await _SFXHandle.ToUniTask();
|
||||||
|
|
||||||
|
callback?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReleaseSFX()
|
||||||
|
{
|
||||||
|
SFXAudios.Clear();
|
||||||
|
_SFXHandle.Release();
|
||||||
|
}
|
||||||
|
public async UniTaskVoid WarmEnemies(Action callback)
|
||||||
|
{
|
||||||
|
_enemiesHandle = Addressables.LoadAssetsAsync<AudioClip>(_enemies, OnEnemiesLoaded);
|
||||||
|
|
||||||
|
await _enemiesHandle.ToUniTask();
|
||||||
|
|
||||||
|
callback?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReleaseEnemies()
|
||||||
|
{
|
||||||
|
EnemiesAudios.Clear();
|
||||||
|
_enemiesHandle.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async UniTaskVoid WarmDispatcher(Action callback)
|
||||||
|
{
|
||||||
|
_dispatcherHandle = Addressables.LoadAssetsAsync<AudioClip>(_dispatcher, OnDispatcherLoaded);
|
||||||
|
|
||||||
|
await _dispatcherHandle.ToUniTask();
|
||||||
|
|
||||||
|
callback?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReleaseDispatcher()
|
||||||
|
{
|
||||||
|
DispatcherAudios.Clear();
|
||||||
|
_dispatcherHandle.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnActionTrackLoaded(AudioClip audioClip)
|
||||||
|
{
|
||||||
|
ActionMusic.Add(audioClip);
|
||||||
|
}
|
||||||
|
private void OnPeacefulTrackLoaded(AudioClip audioClip)
|
||||||
|
{
|
||||||
|
PeacefulMusic.Add(audioClip);
|
||||||
|
}
|
||||||
|
private void OnMenuTrackLoaded(AudioClip audioClip)
|
||||||
|
{
|
||||||
|
MenuMusic.Add(audioClip);
|
||||||
|
}
|
||||||
|
private void OnSFXLoaded(AudioClip audioClip)
|
||||||
|
{
|
||||||
|
SFXAudios.Add(audioClip);
|
||||||
|
}
|
||||||
|
private void OnEnemiesLoaded(AudioClip audioClip)
|
||||||
|
{
|
||||||
|
EnemiesAudios.Add(audioClip);
|
||||||
|
}
|
||||||
|
private void OnDispatcherLoaded(AudioClip audioClip)
|
||||||
|
{
|
||||||
|
DispatcherAudios.Add(audioClip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Code.Configs;
|
using Code.Configs;
|
||||||
using Code.Constants;
|
using Code.Constants;
|
||||||
using Unity.VisualScripting;
|
using Unity.VisualScripting;
|
||||||
|
using UnityEngine;
|
||||||
using UnityEngine.AddressableAssets;
|
using UnityEngine.AddressableAssets;
|
||||||
using UnityEngine.Audio;
|
using UnityEngine.Audio;
|
||||||
|
using Random = UnityEngine.Random;
|
||||||
|
|
||||||
namespace Code.Audio
|
namespace Code.Audio
|
||||||
{
|
{
|
||||||
public class AudioService : IAudioService, IDisposable
|
public class AudioService : IAudioService
|
||||||
{
|
{
|
||||||
private IAudioFactory _audioFactory;
|
private IAudioFactory _audioFactory;
|
||||||
|
|
||||||
private AudioMixer _mixer;
|
private AudioMixer _mixer;
|
||||||
|
private AudioSource _actionMusicSource;
|
||||||
|
private AudioSource _peacefulMusicSource;
|
||||||
|
|
||||||
private AudioMixerGroup _masterGroup,
|
private AudioMixerGroup _masterGroup,
|
||||||
_musicGroup,
|
_musicGroup,
|
||||||
@@ -23,6 +28,10 @@ namespace Code.Audio
|
|||||||
_courierGroup,
|
_courierGroup,
|
||||||
_enemiesGroup;
|
_enemiesGroup;
|
||||||
|
|
||||||
|
private readonly AudioSourcePool _audioSourcePool = new();
|
||||||
|
|
||||||
|
private Dictionary<AudioSnapshotState, AudioMixerSnapshot> _snapshots = new();
|
||||||
|
|
||||||
public AudioService(AudioFactory audioFactory)
|
public AudioService(AudioFactory audioFactory)
|
||||||
{
|
{
|
||||||
_audioFactory = audioFactory;
|
_audioFactory = audioFactory;
|
||||||
@@ -30,7 +39,7 @@ namespace Code.Audio
|
|||||||
|
|
||||||
public async void Initialize(Action callback)
|
public async void Initialize(Action callback)
|
||||||
{
|
{
|
||||||
_mixer = await _audioFactory.CreateCanvas();
|
_mixer = await _audioFactory.CreateMixer();
|
||||||
|
|
||||||
MixerCreated();
|
MixerCreated();
|
||||||
|
|
||||||
@@ -48,10 +57,53 @@ namespace Code.Audio
|
|||||||
_dispatcherGroup = _mixer.FindMatchingGroups(AudioGroups.DispatcherMusicGroup)[0];
|
_dispatcherGroup = _mixer.FindMatchingGroups(AudioGroups.DispatcherMusicGroup)[0];
|
||||||
_courierGroup = _mixer.FindMatchingGroups(AudioGroups.CourierMusicGroup)[0];
|
_courierGroup = _mixer.FindMatchingGroups(AudioGroups.CourierMusicGroup)[0];
|
||||||
_enemiesGroup = _mixer.FindMatchingGroups(AudioGroups.EnemiesMusicGroup)[0];
|
_enemiesGroup = _mixer.FindMatchingGroups(AudioGroups.EnemiesMusicGroup)[0];
|
||||||
|
|
||||||
|
_snapshots[AudioSnapshotState.Peaceful] = _mixer.FindSnapshot(AudioGroups.PeacefulSnapshot);
|
||||||
|
_snapshots[AudioSnapshotState.Action] = _mixer.FindSnapshot(AudioGroups.ActionSnapshot);
|
||||||
|
|
||||||
|
_audioFactory.LoadAudioSourcePrefab(_audioSourcePool.Initialize);
|
||||||
|
|
||||||
|
InitializeMusicSources();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
private void InitializeMusicSources()
|
||||||
{
|
{
|
||||||
|
_actionMusicSource = _audioSourcePool.GetSource();
|
||||||
|
_actionMusicSource.outputAudioMixerGroup = _actionMusicGroup;
|
||||||
|
_actionMusicSource.spatialBlend = 0f;
|
||||||
|
|
||||||
|
_peacefulMusicSource = _audioSourcePool.GetSource();
|
||||||
|
_peacefulMusicSource.outputAudioMixerGroup = _peacefulMusicGroup;
|
||||||
|
_peacefulMusicSource.spatialBlend = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PlayRandomGameplayMusic()
|
||||||
|
{
|
||||||
|
_peacefulMusicSource.resource = _audioFactory.PeacefulMusic[Random.Range(0, _audioFactory.PeacefulMusic.Count)];
|
||||||
|
_actionMusicSource.resource =
|
||||||
|
_audioFactory.ActionMusic[Random.Range(0, _audioFactory.ActionMusic.Count)];
|
||||||
|
|
||||||
|
_peacefulMusicSource.Play();
|
||||||
|
_actionMusicSource.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TransitToSnapshot(AudioSnapshotState state)
|
||||||
|
{
|
||||||
|
_snapshots[state].TransitionTo(1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||||
|
public void PlaySFX(SFXSounds sfxId, Vector3 position)
|
||||||
|
{
|
||||||
|
_audioSourcePool.PlayOneShot(_audioFactory.SFXAudios[(int)sfxId], position, _SFXGroup);
|
||||||
|
}
|
||||||
|
public void PlayEnemy(EnemiesSounds enemySoundId, Vector3 position)
|
||||||
|
{
|
||||||
|
_audioSourcePool.PlayOneShot(_audioFactory.EnemiesAudios[(int)enemySoundId], position, _enemiesGroup);
|
||||||
|
}
|
||||||
|
public void PlayDispatcher(DispatcherSounds dispatcherSoundId)
|
||||||
|
{
|
||||||
|
_audioSourcePool.PlayShizo(_audioFactory.DispatcherAudios[(int)dispatcherSoundId], _dispatcherGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ namespace Code.Audio
|
|||||||
_snapshots[AudioSnapshotState.Peaceful] = mixer.FindSnapshot(AudioGroups.PeacefulSnapshot);
|
_snapshots[AudioSnapshotState.Peaceful] = mixer.FindSnapshot(AudioGroups.PeacefulSnapshot);
|
||||||
_snapshots[AudioSnapshotState.Action] = mixer.FindSnapshot(AudioGroups.ActionSnapshot);
|
_snapshots[AudioSnapshotState.Action] = mixer.FindSnapshot(AudioGroups.ActionSnapshot);
|
||||||
|
|
||||||
_audioSourcePool.Initialize(10,prefab);
|
// _audioSourcePool.Initialize(10,prefab);
|
||||||
|
|
||||||
InitializeMusicSources();
|
InitializeMusicSources();
|
||||||
}
|
}
|
||||||
@@ -114,26 +114,6 @@ namespace Code.Audio
|
|||||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SFXSounds
|
|
||||||
{
|
|
||||||
Crowbar,
|
|
||||||
Shot357
|
|
||||||
}
|
|
||||||
public enum UISounds
|
|
||||||
{
|
|
||||||
Crowbar
|
|
||||||
}
|
|
||||||
public enum EnemiesSounds
|
|
||||||
{
|
|
||||||
Bastard,
|
|
||||||
Bravo
|
|
||||||
}
|
|
||||||
public enum DispatcherSounds
|
|
||||||
{
|
|
||||||
Absolutely,
|
|
||||||
AbsolutelyNot,
|
|
||||||
AhFreeman
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ namespace Code.Audio
|
|||||||
private IObjectPool<AudioSource> _pool;
|
private IObjectPool<AudioSource> _pool;
|
||||||
private AudioSource _sourcePrefab;
|
private AudioSource _sourcePrefab;
|
||||||
|
|
||||||
public void Initialize(int count, AudioSource sourcePrefab)
|
public void Initialize(AudioSource sourcePrefab)
|
||||||
{
|
{
|
||||||
_sourcePrefab = sourcePrefab;
|
_sourcePrefab = sourcePrefab;
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ namespace Code.Audio
|
|||||||
// actionOnRelease: OnRelease,
|
// actionOnRelease: OnRelease,
|
||||||
actionOnDestroy: OnDestroyItem,
|
actionOnDestroy: OnDestroyItem,
|
||||||
collectionCheck: true, // helps catch double-release mistakes
|
collectionCheck: true, // helps catch double-release mistakes
|
||||||
defaultCapacity: count,
|
defaultCapacity: 10,
|
||||||
maxSize: 20
|
maxSize: 20
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
using UnityEngine.Audio;
|
using UnityEngine.Audio;
|
||||||
|
|
||||||
namespace Code.Audio
|
namespace Code.Audio
|
||||||
{
|
{
|
||||||
public interface IAudioFactory
|
public interface IAudioFactory
|
||||||
{
|
{
|
||||||
UniTask<AudioMixer> CreateCanvas();
|
List<AudioClip> PeacefulMusic { get; }
|
||||||
|
List<AudioClip> ActionMusic { get; }
|
||||||
|
List<AudioClip> MenuMusic { get; }
|
||||||
|
List<AudioClip> SFXAudios { get; }
|
||||||
|
List<AudioClip> EnemiesAudios { get; }
|
||||||
|
List<AudioClip> DispatcherAudios { get; }
|
||||||
|
UniTask<AudioMixer> CreateMixer();
|
||||||
|
UniTaskVoid LoadAudioSourcePrefab(Action<AudioSource> callback);
|
||||||
|
UniTaskVoid WarmGameplayMusic(Action callback);
|
||||||
|
void ReleaseGameplayMusic();
|
||||||
|
UniTaskVoid WarmMenuMusic(Action callback);
|
||||||
|
void ReleaseMenuMusic();
|
||||||
|
UniTaskVoid WarmSFX(Action callback);
|
||||||
|
void ReleaseSFX();
|
||||||
|
UniTaskVoid WarmEnemies(Action callback);
|
||||||
|
void ReleaseEnemies();
|
||||||
|
UniTaskVoid WarmDispatcher(Action callback);
|
||||||
|
void ReleaseDispatcher();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Code.Audio
|
namespace Code.Audio
|
||||||
{
|
{
|
||||||
public interface IAudioService
|
public interface IAudioService
|
||||||
{
|
{
|
||||||
void Initialize(Action callback);
|
void Initialize(Action callback);
|
||||||
|
void PlayRandomGameplayMusic();
|
||||||
|
void TransitToSnapshot(AudioSnapshotState state);
|
||||||
|
void PlaySFX(SFXSounds sfxId, Vector3 position);
|
||||||
|
void PlayEnemy(EnemiesSounds enemySoundId, Vector3 position);
|
||||||
|
void PlayDispatcher(DispatcherSounds dispatcherSoundId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,6 @@ namespace Code.Configs
|
|||||||
public class AudioMixerConfig : ScriptableObject
|
public class AudioMixerConfig : ScriptableObject
|
||||||
{
|
{
|
||||||
public AssetReference audioMixerPrefab;
|
public AssetReference audioMixerPrefab;
|
||||||
|
public AssetReference audioSourcePrefab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,5 +8,6 @@ namespace Code.Configs
|
|||||||
{
|
{
|
||||||
public AssetReference[] peacefulSoundtrack;
|
public AssetReference[] peacefulSoundtrack;
|
||||||
public AssetReference[] actionSoundtrack;
|
public AssetReference[] actionSoundtrack;
|
||||||
|
public AssetReference[] menuSoundtrack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user