31 changed files with 486 additions and 964 deletions
@ -1,336 +0,0 @@ |
|||
using Core.Localization; |
|||
using Core.Settings; |
|||
using Core.Tools.Saves; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace Core.Audio |
|||
{ |
|||
public static class AudioController |
|||
{ |
|||
private static List<AudioPlayer> _audioPlayers = new List<AudioPlayer>(); |
|||
|
|||
private static Dictionary<string, AudioClip> _nonLocalizedSoundsDictionary = new Dictionary<string, AudioClip>(); |
|||
private static Dictionary<SystemLanguage, Dictionary<string, AudioClip>> _localizedSoundDictionary = new Dictionary<SystemLanguage, Dictionary<string, AudioClip>>(); |
|||
|
|||
private static GameObject _parent = null; |
|||
|
|||
internal static void Init() |
|||
{ |
|||
_parent = new GameObject("[AudioController]"); |
|||
|
|||
GameObject.DontDestroyOnLoad(_parent); |
|||
|
|||
AudioClip[] nonLocalizedSounds = Resources.LoadAll<AudioClip>("Audio/NonLocalizedSounds"); |
|||
|
|||
for (int i = 0; i < nonLocalizedSounds.Length; i++) |
|||
_nonLocalizedSoundsDictionary.Add(nonLocalizedSounds[i].name, nonLocalizedSounds[i]); |
|||
|
|||
for (int l = 0; l < CoreSettings.data.availableLanguages.Count; l++) |
|||
{ |
|||
SystemLanguage language = CoreSettings.data.availableLanguages[l]; |
|||
|
|||
Dictionary<string, AudioClip> voicesDictionary = new Dictionary<string, AudioClip>(); |
|||
|
|||
AudioClip[] voices = Resources.LoadAll<AudioClip>("CoreAudio/LocalizedSounds/" + language.ToString()); |
|||
|
|||
for (int i = 0; i < voices.Length; i++) |
|||
voicesDictionary.Add(voices[i].name, voices[i]); |
|||
|
|||
_localizedSoundDictionary.Add(language, voicesDictionary); |
|||
} |
|||
} |
|||
|
|||
public static AudioPlayer CreatePlayer(string clipName) => |
|||
CreatePlayer(FindAudioClip(clipName)); |
|||
|
|||
#region AudioPlayer manager
|
|||
|
|||
public static AudioPlayer CreatePlayer(AudioClip clip) |
|||
{ |
|||
if (clip == null) |
|||
return null; |
|||
|
|||
AudioPlayer player = _audioPlayers.Where(p => p.AudioClip == null).FirstOrDefault(); |
|||
|
|||
if (player == null) |
|||
{ |
|||
GameObject newPlayer = new GameObject("AudioPlayer"); |
|||
newPlayer.transform.SetParent(_parent.transform); |
|||
|
|||
newPlayer.AddComponent<AudioSource>(); |
|||
player = newPlayer.AddComponent<AudioPlayer>(); |
|||
|
|||
player.OnNeedDestroy += DestroyPlayer; |
|||
|
|||
_audioPlayers.Add(player); |
|||
} |
|||
|
|||
player.Init(clip); |
|||
|
|||
return player; |
|||
} |
|||
|
|||
private static void DestroyPlayer(AudioPlayer player) |
|||
{ |
|||
_audioPlayers.Remove(player); |
|||
|
|||
GameObject gameObject = player.gameObject; |
|||
|
|||
GameObject.Destroy(player); |
|||
|
|||
player = gameObject.AddComponent<AudioPlayer>(); |
|||
|
|||
player.OnNeedDestroy += DestroyPlayer; |
|||
|
|||
_audioPlayers.Add(player); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Volume
|
|||
|
|||
public static void SetVolume(AudioGroup group, float volume) |
|||
{ |
|||
SaveManager.SetFloat(group.ToString() + "_volume", volume); |
|||
|
|||
for (int i = 0; i < _audioPlayers.Count; i++) |
|||
{ |
|||
if (_audioPlayers[i].AudioClip != null && _audioPlayers[i].AudioGroup == group) |
|||
_audioPlayers[i].UpdateVolume(); |
|||
} |
|||
} |
|||
|
|||
public static float GetVolume(AudioGroup group) => |
|||
SaveManager.GetFloat(group.ToString() + "_volume", 1f); |
|||
|
|||
#endregion
|
|||
|
|||
#region Find player with parametres
|
|||
|
|||
public static AudioPlayer FindPlayer(string clipName) |
|||
{ |
|||
AudioClip clip = FindAudioClip(clipName); |
|||
|
|||
if (clip == null) |
|||
return null; |
|||
|
|||
return FindPlayer(clip, -1, -1); |
|||
} |
|||
|
|||
public static AudioPlayer FindPlayer(string clipName, AudioGroup group) |
|||
{ |
|||
AudioClip clip = FindAudioClip(clipName); |
|||
|
|||
if (clip == null) |
|||
return null; |
|||
|
|||
return FindPlayer(clip, (int)group, -1); |
|||
} |
|||
|
|||
public static AudioPlayer FindPlayer(string clipName, SourceType type) |
|||
{ |
|||
AudioClip clip = FindAudioClip(clipName); |
|||
|
|||
if (clip == null) |
|||
return null; |
|||
|
|||
return FindPlayer(clip, -1, (int)type); |
|||
} |
|||
|
|||
public static AudioPlayer FindPlayer(string clipName, AudioGroup group, SourceType type) |
|||
{ |
|||
AudioClip clip = FindAudioClip(clipName); |
|||
|
|||
if (clip == null) |
|||
return null; |
|||
|
|||
return FindPlayer(clip, (int)group, (int)type); |
|||
} |
|||
|
|||
public static AudioPlayer FindPlayer(AudioClip clip) => |
|||
FindPlayer(clip, -1, -1); |
|||
public static AudioPlayer FindPlayer(AudioClip clip, AudioGroup group) => |
|||
FindPlayer(clip, (int)group, -1); |
|||
|
|||
public static AudioPlayer FindPlayer(AudioClip clip, SourceType type) => |
|||
FindPlayer(clip, -1, (int)type); |
|||
|
|||
public static AudioPlayer FindPlayer(AudioClip clip, AudioGroup group, SourceType type) => |
|||
FindPlayer(clip, (int)group, (int)type); |
|||
|
|||
public static AudioPlayer FindPlayer(AudioGroup group) => |
|||
FindPlayer(null, (int)group, -1); |
|||
|
|||
public static AudioPlayer FindPlayer(SourceType type) => |
|||
FindPlayer(null, -1, (int)type); |
|||
|
|||
public static AudioPlayer FindPlayer(AudioGroup group, SourceType type) => |
|||
FindPlayer(null, (int)group, (int)type); |
|||
|
|||
private static AudioPlayer FindPlayer(AudioClip clip, int group = -1, int type = -1) |
|||
{ |
|||
AudioPlayer[] players = FindPlayers(clip, group, type); |
|||
|
|||
if (players != null && players.Length > 0) |
|||
return players[0]; |
|||
else |
|||
return null; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Find players with parametres
|
|||
|
|||
public static AudioPlayer[] FindPlayers(string clipName) |
|||
{ |
|||
AudioClip clip = FindAudioClip(clipName); |
|||
|
|||
if (clip == null) |
|||
return null; |
|||
|
|||
return FindPlayers(clip, -1, -1); |
|||
} |
|||
|
|||
public static AudioPlayer[] FindPlayers(string clipName, AudioGroup group) |
|||
{ |
|||
AudioClip clip = FindAudioClip(clipName); |
|||
|
|||
if (clip == null) |
|||
return null; |
|||
|
|||
return FindPlayers(clip, (int)group, -1); |
|||
} |
|||
|
|||
public static AudioPlayer[] FindPlayers(string clipName, SourceType type) |
|||
{ |
|||
AudioClip clip = FindAudioClip(clipName); |
|||
|
|||
if (clip == null) |
|||
return null; |
|||
|
|||
return FindPlayers(clip, -1, (int)type); |
|||
} |
|||
|
|||
public static AudioPlayer[] FindPlayers(string clipName, AudioGroup group, SourceType type) |
|||
{ |
|||
AudioClip clip = FindAudioClip(clipName); |
|||
|
|||
if (clip == null) |
|||
return null; |
|||
|
|||
return FindPlayers(clip, (int)group, (int)type); |
|||
} |
|||
|
|||
public static AudioPlayer[] FindPlayers(AudioClip clip) => |
|||
FindPlayers(clip, -1, -1); |
|||
public static AudioPlayer[] FindPlayers(AudioClip clip, AudioGroup group) => |
|||
FindPlayers(clip, (int)group, -1); |
|||
|
|||
public static AudioPlayer[] FindPlayers(AudioClip clip, SourceType type) => |
|||
FindPlayers(clip, -1, (int)type); |
|||
|
|||
public static AudioPlayer[] FindPlayers(AudioClip clip, AudioGroup group, SourceType type) => |
|||
FindPlayers(clip, (int)group, (int)type); |
|||
|
|||
public static AudioPlayer[] FindPlayers(AudioGroup group) => |
|||
FindPlayers(null, (int)group, -1); |
|||
|
|||
public static AudioPlayer[] FindPlayers(SourceType type) => |
|||
FindPlayers(null, -1, (int)type); |
|||
|
|||
public static AudioPlayer[] FindPlayers(AudioGroup group, SourceType type) => |
|||
FindPlayers(null, (int)group, (int)type); |
|||
|
|||
private static AudioPlayer[] FindPlayers(AudioClip clip, int group = -1, int type = -1) |
|||
{ |
|||
AudioPlayer[] audioPlayers = new AudioPlayer[0]; |
|||
|
|||
if (clip != null && group != -1 && type != -1) |
|||
{ |
|||
AudioGroup audioGroup = (AudioGroup)group; |
|||
SourceType sourceType = (SourceType)type; |
|||
|
|||
audioPlayers = _audioPlayers.Where(p => p.AudioClip == clip && p.AudioGroup == audioGroup && p.SourceType == sourceType).ToArray(); |
|||
|
|||
return audioPlayers; |
|||
} |
|||
|
|||
if (clip != null && group != -1 && type == -1) |
|||
{ |
|||
AudioGroup audioGroup = (AudioGroup)group; |
|||
|
|||
audioPlayers = _audioPlayers.Where(p => p.AudioClip == clip && p.AudioGroup == audioGroup).ToArray(); |
|||
|
|||
return audioPlayers; |
|||
} |
|||
|
|||
|
|||
if (clip != null && group == -1 && type != -1) |
|||
{ |
|||
SourceType sourceType = (SourceType)type; |
|||
|
|||
audioPlayers = _audioPlayers.Where(p => p.AudioClip == clip && p.SourceType == sourceType).ToArray(); |
|||
|
|||
return audioPlayers; |
|||
} |
|||
|
|||
if (clip != null && group == -1 && type == -1) |
|||
{ |
|||
SourceType sourceType = (SourceType)type; |
|||
|
|||
audioPlayers = _audioPlayers.Where(p => p.AudioClip == clip).ToArray(); |
|||
|
|||
return audioPlayers; |
|||
} |
|||
|
|||
if (clip == null && group != -1 && type != -1) |
|||
{ |
|||
AudioGroup audioGroup = (AudioGroup)group; |
|||
SourceType sourceType = (SourceType)type; |
|||
|
|||
audioPlayers = _audioPlayers.Where(p => p.AudioGroup == audioGroup && p.SourceType == sourceType).ToArray(); |
|||
|
|||
return audioPlayers; |
|||
} |
|||
|
|||
if (clip == null && group != -1 && type == -1) |
|||
{ |
|||
AudioGroup audioGroup = (AudioGroup)group; |
|||
|
|||
audioPlayers = _audioPlayers.Where(p => p.AudioGroup == audioGroup).ToArray(); |
|||
|
|||
return audioPlayers; |
|||
} |
|||
|
|||
if (clip == null && group == -1 && type != -1) |
|||
{ |
|||
SourceType sourceType = (SourceType)type; |
|||
|
|||
audioPlayers = _audioPlayers.Where(p => p.SourceType == sourceType).ToArray(); |
|||
|
|||
return audioPlayers; |
|||
} |
|||
|
|||
return audioPlayers; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
public static AudioClip FindAudioClip(string clipName) |
|||
{ |
|||
SystemLanguage language = LocalizationManager.CurrentLanguage; |
|||
|
|||
AudioClip clip = _localizedSoundDictionary[language].Where(d => d.Key == clipName).FirstOrDefault().Value; |
|||
|
|||
if (clip == null) |
|||
clip = _nonLocalizedSoundsDictionary.Where(d => d.Key == clipName).FirstOrDefault().Value; |
|||
|
|||
if (clip == null) |
|||
Debug.LogError($"AudioController: clip \"{clipName}\" not found"); |
|||
|
|||
return clip; |
|||
} |
|||
} |
|||
} |
|||
@ -1,190 +1,77 @@ |
|||
using Core.Settings; |
|||
using System; |
|||
using System.Collections; |
|||
using UnityEngine; |
|||
using UnityEngine; |
|||
using UnityEngine.UI; |
|||
|
|||
namespace Core.Audio |
|||
{ |
|||
public enum SourceType |
|||
{ |
|||
Type2D = 0, |
|||
Type3D = 1, |
|||
} |
|||
|
|||
public enum AudioGroup |
|||
{ |
|||
Music = 0, |
|||
Sound = 1, |
|||
Voice = 2, |
|||
} |
|||
|
|||
[RequireComponent(typeof(AudioSource))] |
|||
public sealed class AudioPlayer : MonoBehaviour |
|||
public class AudioPlayer : MonoBehaviour |
|||
{ |
|||
internal event Action<AudioPlayer> OnNeedDestroy = null; |
|||
|
|||
private event Action _onComplete = null; |
|||
private AudioSource _audioSource = null; |
|||
private SourceType _sourceType = SourceType.Type2D; |
|||
private AudioGroup _group = AudioGroup.Sound; |
|||
private float _customVolume = 1f; |
|||
private bool _isLoop = false; |
|||
private Transform _target = null; |
|||
|
|||
private Coroutine _playCoroutine = null; |
|||
|
|||
public AudioClip AudioClip => (_audioSource != null) ? _audioSource.clip : null; |
|||
public SourceType SourceType => _sourceType; |
|||
public AudioGroup AudioGroup => _group; |
|||
public float CustomVolume => _customVolume; |
|||
public bool IsPlaying => _audioSource != null && _audioSource.clip != null && _audioSource.isPlaying; |
|||
public bool IsLoop => _isLoop; |
|||
public Transform Target => _target; |
|||
|
|||
internal void Init(AudioClip clip) |
|||
{ |
|||
_audioSource = GetComponent<AudioSource>(); |
|||
[SerializeField] private AudioClip[] _clips = new AudioClip[0]; |
|||
|
|||
_onComplete = null; |
|||
[Space] |
|||
|
|||
_audioSource.playOnAwake = false; |
|||
_audioSource.Stop(); |
|||
|
|||
SetGroup(AudioGroup.Sound); |
|||
SetLoop(false); |
|||
SetCustomVolume(1f); |
|||
SetSource(SourceType.Type2D); |
|||
SetTarget(null); |
|||
SetMinDistance(0f); |
|||
SetMaxDistance(0f); |
|||
|
|||
UpdateVolume(); |
|||
|
|||
_audioSource.clip = clip; |
|||
} |
|||
|
|||
internal void UpdateVolume() => |
|||
_audioSource.volume = _customVolume * AudioController.GetVolume(_group) * CoreSettings.data.volume[(int)_group]; |
|||
|
|||
public void Stop() |
|||
{ |
|||
_audioSource.Stop(); |
|||
_audioSource.clip = null; |
|||
[SerializeField] private float _delayForPlay = 0f; |
|||
|
|||
if (_playCoroutine != null) |
|||
StopCoroutine(_playCoroutine); |
|||
|
|||
OnNeedDestroy?.Invoke(this); |
|||
} |
|||
|
|||
private void Update() |
|||
{ |
|||
if (_sourceType == SourceType.Type3D && _target != null) |
|||
transform.position = _target.position; |
|||
else |
|||
transform.localPosition = Vector3.zero; |
|||
} |
|||
|
|||
public AudioPlayer SetSource(SourceType type) |
|||
{ |
|||
_sourceType = type; |
|||
|
|||
if (_sourceType == SourceType.Type2D) |
|||
{ |
|||
_audioSource.spatialBlend = 0f; |
|||
_audioSource.rolloffMode = AudioRolloffMode.Linear; |
|||
} |
|||
else |
|||
{ |
|||
_audioSource.spatialBlend = 1f; |
|||
_audioSource.rolloffMode = AudioRolloffMode.Custom; |
|||
_audioSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, AnimationCurve.Linear(0f, 1f, 1f, 0f)); |
|||
} |
|||
[Header("Flags")] |
|||
|
|||
return this; |
|||
} |
|||
[SerializeField] private bool _playOnEnable = false; |
|||
[SerializeField] private bool _playOnClick = false; |
|||
[SerializeField] private bool _playWithParticle = false; |
|||
|
|||
public AudioPlayer SetTarget(Transform target) |
|||
{ |
|||
_target = target; |
|||
return this; |
|||
} |
|||
private AudioSource _source = null; |
|||
private ParticleSystem _particle = null; |
|||
private Button _button = null; |
|||
|
|||
public AudioPlayer SetMinDistance(float minDistance) |
|||
{ |
|||
_audioSource.minDistance = minDistance; |
|||
return this; |
|||
} |
|||
|
|||
public AudioPlayer SetMaxDistance(float maxDistance) |
|||
{ |
|||
_audioSource.maxDistance = maxDistance; |
|||
return this; |
|||
} |
|||
private bool _lastParticleState = false; |
|||
|
|||
public AudioPlayer SetCustomVolume(float volume) |
|||
private void Awake() |
|||
{ |
|||
_customVolume = volume; |
|||
_source = GetComponent<AudioSource>(); |
|||
_particle = GetComponent<ParticleSystem>(); |
|||
_button = GetComponent<Button>(); |
|||
|
|||
UpdateVolume(); |
|||
_source.playOnAwake = false; |
|||
_source.Stop(); |
|||
|
|||
return this; |
|||
if (_button != null && _playOnClick) |
|||
_button.onClick.AddListener(Play); |
|||
} |
|||
|
|||
public AudioPlayer SetGroup(AudioGroup group) |
|||
{ |
|||
_group = group; |
|||
|
|||
UpdateVolume(); |
|||
private void OnDestroy() => |
|||
_source.Stop(); |
|||
|
|||
return this; |
|||
} |
|||
|
|||
public AudioPlayer SetLoop(bool loop) |
|||
private void OnEnable() |
|||
{ |
|||
_isLoop = loop; |
|||
|
|||
_audioSource.loop = _isLoop; |
|||
|
|||
return this; |
|||
if (_playOnEnable) |
|||
Play(); |
|||
} |
|||
|
|||
public AudioPlayer OnComplete(Action onComplete) |
|||
private void Update() |
|||
{ |
|||
_onComplete += onComplete; |
|||
|
|||
return this; |
|||
if (_playWithParticle) |
|||
{ |
|||
if (_lastParticleState != _particle.isPlaying) |
|||
{ |
|||
if (_particle.isPlaying) |
|||
Play(); |
|||
else |
|||
Stop(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public AudioPlayer Play() => |
|||
Play(0f); |
|||
|
|||
public AudioPlayer Play(float delay) |
|||
private void PlayClipWithDelay() |
|||
{ |
|||
_playCoroutine = StartCoroutine(PlayCoroutine(delay)); |
|||
AudioClip clipToPlay = _clips[Random.Range(0, _clips.Length)]; |
|||
|
|||
return this; |
|||
_source.clip = clipToPlay; |
|||
_source.Play(); |
|||
} |
|||
|
|||
private IEnumerator PlayCoroutine(float delay) |
|||
{ |
|||
if (_audioSource.isPlaying) |
|||
yield break; |
|||
|
|||
if (delay > 0f) |
|||
yield return new WaitForSeconds(delay); |
|||
|
|||
_audioSource.Play(); |
|||
|
|||
if (_isLoop) |
|||
yield break; |
|||
public void Play() => |
|||
Invoke("PlayClipWithDelay", _delayForPlay); |
|||
|
|||
while (_audioSource.isPlaying) |
|||
yield return null; |
|||
|
|||
_onComplete?.Invoke(); |
|||
|
|||
Stop(); |
|||
} |
|||
public void Stop() => |
|||
_source.Stop(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,131 +0,0 @@ |
|||
using System.Collections; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
using UnityEngine.UI; |
|||
|
|||
namespace Core.Audio |
|||
{ |
|||
public sealed class PlayAudioFile : MonoBehaviour |
|||
{ |
|||
|
|||
public enum PlayType |
|||
{ |
|||
OnActivate = 0, |
|||
OnClickButton = 1, |
|||
OnClickCollider = 2, |
|||
OnPlayParticle = 3, |
|||
} |
|||
|
|||
[SerializeField] private SourceType _sourceType = SourceType.Type2D; |
|||
[SerializeField] private AudioGroup _audioFileType = AudioGroup.Music; |
|||
[SerializeField] private PlayType _playType = PlayType.OnActivate; |
|||
[SerializeField] private float _startDelay = 0f; |
|||
[SerializeField] private float _customVolume = 1f; |
|||
[SerializeField] private bool _loop = false; |
|||
[SerializeField] private float _minDistance = 0f; |
|||
[SerializeField] private float _maxDistance = 100f; |
|||
[SerializeField] private string[] _audioFileNames = new string[0]; |
|||
|
|||
private ParticleSystem _particleSystem = null; |
|||
private Button _button = null; |
|||
|
|||
private bool _isPlaying = false; |
|||
|
|||
private AudioPlayer _currentPlayer = null; |
|||
|
|||
private void Awake() |
|||
{ |
|||
switch (_playType) |
|||
{ |
|||
case PlayType.OnClickButton: |
|||
|
|||
_button = GetComponent<Button>(); |
|||
_button.onClick.AddListener(() => |
|||
{ |
|||
Play(); |
|||
}); |
|||
|
|||
break; |
|||
} |
|||
} |
|||
|
|||
private void OnEnable() |
|||
{ |
|||
_particleSystem = GetComponent<ParticleSystem>(); |
|||
|
|||
if (_particleSystem == null) |
|||
_particleSystem = GetComponentInChildren<ParticleSystem>(); |
|||
|
|||
switch (_playType) |
|||
{ |
|||
case PlayType.OnActivate: |
|||
Play(); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
private void OnDisable() |
|||
{ |
|||
if (_loop && _currentPlayer != null) |
|||
_currentPlayer.Stop(); |
|||
} |
|||
|
|||
private IEnumerator Start() |
|||
{ |
|||
while (true) |
|||
{ |
|||
switch (_playType) |
|||
{ |
|||
case PlayType.OnPlayParticle: |
|||
|
|||
while (!_particleSystem.isPlaying) |
|||
yield return null; |
|||
|
|||
Play(); |
|||
|
|||
while (_particleSystem.isPlaying || _isPlaying) |
|||
yield return null; |
|||
|
|||
break; |
|||
} |
|||
|
|||
yield return null; |
|||
} |
|||
} |
|||
|
|||
private void OnMouseDown() |
|||
{ |
|||
if (_isPlaying || _playType != PlayType.OnClickCollider) |
|||
return; |
|||
|
|||
Play(); |
|||
} |
|||
|
|||
private void Play() |
|||
{ |
|||
_isPlaying = true; |
|||
|
|||
if (_audioFileType == AudioGroup.Music) |
|||
{ |
|||
AudioPlayer[] player = AudioController.FindPlayers(AudioGroup.Music); |
|||
|
|||
for(int i = 0; i < player.Length; i++) |
|||
player[i].Stop(); |
|||
} |
|||
|
|||
if (_sourceType == SourceType.Type2D) |
|||
_maxDistance = 0; |
|||
|
|||
AudioController.CreatePlayer(_audioFileNames[Random.Range(0, _audioFileNames.Length)]) |
|||
.SetSource(_sourceType) |
|||
.SetGroup(_audioFileType) |
|||
.SetCustomVolume(_customVolume) |
|||
.SetLoop(_loop) |
|||
.SetTarget(transform) |
|||
.SetMinDistance(_minDistance) |
|||
.SetMaxDistance(_maxDistance) |
|||
.OnComplete(() => _isPlaying = false) |
|||
.Play(_startDelay); |
|||
} |
|||
} |
|||
} |
|||
@ -1,54 +1,86 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
using UnityEngine; |
|||
|
|||
namespace Core.Tools.Pool.Particles |
|||
{ |
|||
[Serializable] |
|||
public sealed class Particle |
|||
public sealed class Particle : MonoBehaviour |
|||
{ |
|||
[SerializeField] private string _id = "particle"; |
|||
[SerializeField] private ParticleSystem _prefab = null; |
|||
[SerializeField] private int _startCount = 1; |
|||
private ParticleSystem _system = null; |
|||
public bool IsPlaying => _system.isPlaying; |
|||
public float Time => _system.time; |
|||
|
|||
private ParticleSystem[] _pool = new ParticleSystem[0]; |
|||
private Transform _target = null; |
|||
|
|||
private Transform _summonParent = null; |
|||
private Vector3 _offsetPosition = Vector3.zero; |
|||
private Quaternion _offsetRotation = Quaternion.identity; |
|||
private Vector3 _offsetScale = Vector3.zero; |
|||
|
|||
public string ID => _id; |
|||
internal void Init(ParticleSystem system) => |
|||
_system = system; |
|||
|
|||
public void Init(Transform summonParent) |
|||
internal void UpdatePosition() |
|||
{ |
|||
_summonParent = summonParent; |
|||
|
|||
_pool = new ParticleSystem[_startCount]; |
|||
if (_target != null) |
|||
UpdatePositionForce(); |
|||
} |
|||
|
|||
for (int i = 0; i < _startCount; i++) |
|||
_pool[i] = GameObject.Instantiate(_prefab, _summonParent); |
|||
internal void UpdatePositionForce() |
|||
{ |
|||
if (_target == null) |
|||
{ |
|||
transform.position = _offsetPosition; |
|||
transform.rotation = _offsetRotation; |
|||
transform.localScale = _offsetScale; |
|||
} |
|||
else |
|||
{ |
|||
transform.position = _target.TransformPoint(_offsetPosition); |
|||
transform.rotation = _target.rotation * _offsetRotation; |
|||
transform.localScale = new Vector3(_target.lossyScale.x * _offsetScale.x, _target.lossyScale.y * _offsetScale.y, _target.lossyScale.z * _offsetScale.z); |
|||
} |
|||
} |
|||
|
|||
public ParticleSystem GetParticleFromPool() |
|||
internal Particle Reset() |
|||
{ |
|||
ParticleSystem particle = _pool.Where(p => p != null && !p.isPlaying).FirstOrDefault(); |
|||
_target = null; |
|||
|
|||
/*ParticleSystem[] newArray = new ParticleSystem[_pool.Length + 1]; |
|||
_offsetScale = Vector3.one; |
|||
_offsetPosition = Vector3.zero; |
|||
_offsetRotation = Quaternion.identity; |
|||
|
|||
for (int i = 0; i < _pool.Length; i++) |
|||
newArray[i] = _pool[i]; |
|||
return this; |
|||
} |
|||
|
|||
internal Particle SetTarget(Transform target) |
|||
{ |
|||
_target = target; |
|||
return this; |
|||
} |
|||
|
|||
if (particle == null) |
|||
{ |
|||
particle = GameObject.Instantiate(_prefab, _summonParent); |
|||
newArray[_pool.Length] = particle; |
|||
} |
|||
internal Particle SetScale(Vector3 scale) |
|||
{ |
|||
_offsetScale = scale; |
|||
return this; |
|||
} |
|||
|
|||
internal Particle SetPosition(Vector3 position) |
|||
{ |
|||
_offsetPosition = position; |
|||
return this; |
|||
} |
|||
|
|||
_pool = newArray;*/ |
|||
internal Particle SetRotation(Quaternion rotation) |
|||
{ |
|||
_offsetRotation = rotation; |
|||
return this; |
|||
} |
|||
|
|||
internal Particle Play() |
|||
{ |
|||
UpdatePositionForce(); |
|||
|
|||
if (particle == null) |
|||
particle = _pool.Aggregate((curMax, p) => (curMax == null || p.time > curMax.time ? p : curMax)); |
|||
_system.Play(); |
|||
|
|||
return particle; |
|||
return this; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,53 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
using static UnityEngine.ParticleSystem; |
|||
|
|||
namespace Core.Tools.Pool.Particles |
|||
{ |
|||
[Serializable] |
|||
internal sealed class ParticleData |
|||
{ |
|||
[SerializeField] private string _id = "particle"; |
|||
[SerializeField] private ParticleSystem _prefab = null; |
|||
[SerializeField] private int _startCount = 1; |
|||
|
|||
private List<Particle> _pool = new List<Particle>(); |
|||
|
|||
private Transform _summonParent = null; |
|||
|
|||
public string ID => _id; |
|||
|
|||
internal void Init(Transform summonParent) |
|||
{ |
|||
_summonParent = summonParent; |
|||
|
|||
for (int i = 0; i < _startCount; i++) |
|||
AddNewParticle(); |
|||
} |
|||
|
|||
internal Particle GetParticleFromPool() |
|||
{ |
|||
Particle particle = _pool.Where(p => p != null && !p.IsPlaying).FirstOrDefault(); |
|||
|
|||
if (particle == null) |
|||
particle = AddNewParticle(); |
|||
|
|||
return particle; |
|||
} |
|||
|
|||
private Particle AddNewParticle() |
|||
{ |
|||
ParticleSystem system = GameObject.Instantiate(_prefab, _summonParent); |
|||
|
|||
Particle particle = system.gameObject.AddComponent<Particle>(); |
|||
|
|||
particle.Init(system); |
|||
|
|||
_pool.Add(particle); |
|||
|
|||
return particle; |
|||
} |
|||
} |
|||
} |
|||
@ -1,4 +1,4 @@ |
|||
// <autogenerated />
|
|||
using System; |
|||
using System.Reflection; |
|||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] |
|||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] |
|||
|
|||
Binary file not shown.
Binary file not shown.
@ -1 +1 @@ |
|||
e79d925b831775a6b5acbedb7a2f92dcde277ce4 |
|||
773a4196594e792408d2cdc64f8007606332b05f |
|||
|
|||
Binary file not shown.
@ -1,4 +1,4 @@ |
|||
// <autogenerated />
|
|||
using System; |
|||
using System.Reflection; |
|||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] |
|||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] |
|||
|
|||
Binary file not shown.
Binary file not shown.
@ -1 +1 @@ |
|||
f2d2b287343c0aea3b8f18dbfa4e1e191225142e |
|||
e90e1d7ea4c74eec1bdec271d766ed0a740f70bc |
|||
|
|||
Binary file not shown.
Loading…
Reference in new issue