From 075ce2d80d059d8473f84f44856092ec1df0ba6d Mon Sep 17 00:00:00 2001 From: Seraph Date: Sat, 3 Dec 2022 12:15:55 +0200 Subject: [PATCH] =?UTF-8?q?-=20=D0=9F=D0=B5=D1=80=D0=B5=D1=80=D0=BE=D0=B1?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=B7=D0=B2=D1=83=D0=BA=20-?= =?UTF-8?q?=20=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20=D0=BF=D0=BE=D0=BA?= =?UTF-8?q?=D1=83=D0=BF=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets_DLL/Core/Ads/AdsManager.cs | 98 ++++- .../Core/Ads/Bridges/DemoAds/DemoBannerAds.cs | 9 +- Assets_DLL/Core/Ads/RewardedButton.cs | 7 +- Assets_DLL/Core/Audio/AudioController.cs | 343 ++++++++++++++---- Assets_DLL/Core/Audio/AudioController2D.cs | 202 ----------- Assets_DLL/Core/Audio/AudioController3D.cs | 154 -------- Assets_DLL/Core/Audio/AudioPlayer.cs | 190 ++++++++++ Assets_DLL/Core/Audio/PlayAudioFile.cs | 124 +++---- Assets_DLL/Core/Core.csproj | 128 +++---- Assets_DLL/Core/Core.csproj.bak | 224 ++++++++++++ Assets_DLL/Core/IAP/PurchaseButton.cs | 10 +- Assets_DLL/Core/IAP/PurchaseManager.cs | 13 +- Assets_DLL/Core/IAP/PurchaseManagerBase.cs | 145 +++++--- Assets_DLL/Core/Settings/CoreSettingsData.cs | 4 +- .../Core/Tools/Pool/Particles/Particle.cs | 18 +- .../Tools/Pool/Particles/ParticlesPool.cs | 3 + Assets_DLL/Core/Tools/Saves/SaveManager.cs | 50 +-- .../Core/Tools/Saves/Utils/Encrypter.cs | 53 --- .../Core/obj/Core.csproj.nuget.dgspec.json | 2 +- Assets_DLL/Core/obj/Core.csproj.nuget.g.props | 5 +- .../Core/obj/Core.csproj.nuget.g.targets | 3 - .../Debug/netstandard2.0/Core.assets.cache | Bin 197 -> 197 bytes .../Core.csproj.AssemblyReference.cache | Bin 11 -> 181478 bytes .../Core.csproj.CoreCompileInputs.cache | 2 +- .../Core/obj/Debug/netstandard2.0/Core.dll | Bin 58368 -> 57856 bytes Assets_DLL/Core/obj/project.assets.json | 2 +- Assets_DLL/Core/obj/project.nuget.cache | 2 +- Assets_DLL/CoreEditor/CoreEditor.csproj | 130 +++---- Assets_DLL/CoreEditor/CoreEditor.csproj.bak | 227 ++++++++++++ .../CoreEditor/Settings/CoreSettingsWindow.cs | 24 +- .../CoreEditor/Tools/SaveManagerEditor.cs | 4 - .../obj/CoreEditor.csproj.nuget.dgspec.json | 4 +- .../obj/CoreEditor.csproj.nuget.g.props | 5 +- .../obj/CoreEditor.csproj.nuget.g.targets | 3 - .../netstandard2.0/CoreEditor.assets.cache | Bin 197 -> 197 bytes .../CoreEditor.csproj.AssemblyReference.cache | Bin 1172 -> 135073 bytes .../CoreEditor.csproj.CoreCompileInputs.cache | 2 +- .../obj/Debug/netstandard2.0/CoreEditor.dll | Bin 26624 -> 27136 bytes Assets_DLL/CoreEditor/obj/project.assets.json | 2 +- Assets_DLL/CoreEditor/obj/project.nuget.cache | 2 +- 40 files changed, 1338 insertions(+), 856 deletions(-) delete mode 100644 Assets_DLL/Core/Audio/AudioController2D.cs delete mode 100644 Assets_DLL/Core/Audio/AudioController3D.cs create mode 100644 Assets_DLL/Core/Audio/AudioPlayer.cs create mode 100644 Assets_DLL/Core/Core.csproj.bak delete mode 100644 Assets_DLL/Core/Tools/Saves/Utils/Encrypter.cs create mode 100644 Assets_DLL/CoreEditor/CoreEditor.csproj.bak diff --git a/Assets_DLL/Core/Ads/AdsManager.cs b/Assets_DLL/Core/Ads/AdsManager.cs index d70ca9c..8e6b077 100644 --- a/Assets_DLL/Core/Ads/AdsManager.cs +++ b/Assets_DLL/Core/Ads/AdsManager.cs @@ -64,10 +64,10 @@ namespace Core.Ads PurchaseManager.OnPurchaseSuccess += (productId) => { - if (CoreSettings.data.IsProductConsumable(productId)) + if (CoreSettings.data.IsProductConsumable(productId.definition.id)) return; - if (CoreSettings.data.IsOnAdsProduct(productId)) + if (CoreSettings.data.IsOnAdsProduct(productId.definition.id)) HideBanner(); }; } @@ -101,23 +101,35 @@ namespace Core.Ads return false; if (_interstitial == null) - throw new NullReferenceException("Ads bridge object does not implement IInterstitialBridge"); + { + Debug.LogError("Ads bridge object does not implement IInterstitialBridge"); + return false; + } if (CoreSettings.data.needInterstitial) return _interstitial.IsReady(); else - throw new InvalidOperationException("Interstitial ads is disabled"); + { + Debug.LogError("Interstitial ads is disabled"); + return false; + } } public static bool IsInterstitialVisible() { if (_interstitial == null) - throw new NullReferenceException("Ads bridge object does not implement IInterstitialBridge"); + { + Debug.LogError("Ads bridge object does not implement IInterstitialBridge"); + return false; + } if (CoreSettings.data.needInterstitial) return _interstitial.IsVisible(); else - throw new InvalidOperationException("Interstitial ads is disabled"); + { + Debug.LogError("Interstitial ads is disabled"); + return false; + } } public static void ShowInterstitial() @@ -128,12 +140,23 @@ namespace Core.Ads return; if (_interstitial == null) - throw new NullReferenceException("Ads bridge object does not implement IInterstitialBridge"); + { + Debug.LogError("Ads bridge object does not implement IInterstitialBridge"); + return; + } if (CoreSettings.data.needInterstitial) - _interstitial.Show(); + { + if (_interstitial.IsReady()) + _interstitial.Show(); + else + Debug.LogError("Interstitial ads is not ready"); + } else - throw new InvalidOperationException("Interstitial ads is disabled"); + { + Debug.LogError("Interstitial ads is disabled"); + return; + } } public static bool IsRewardedReady() @@ -142,12 +165,18 @@ namespace Core.Ads return false; if (_rewarded == null) - throw new NullReferenceException("Ads bridge object does not implement IRewardedBridge"); + { + Debug.LogError("Ads bridge object does not implement IRewardedBridge"); + return false; + } if (CoreSettings.data.needRewarded) return _rewarded.IsReady(); else - throw new InvalidOperationException("Rewarded ads is disabled"); + { + Debug.LogError("Rewarded ads is disabled"); + return false; + } } public static void ShowRewarded(Action onSucces, Action onFailed) @@ -158,23 +187,40 @@ namespace Core.Ads return; if (_rewarded == null) - throw new NullReferenceException("Ads bridge object does not implement IRewardedBridge"); + { + Debug.LogError("Ads bridge object does not implement IRewardedBridge"); + return; + } if (CoreSettings.data.needRewarded) - _rewarded.Show(onSucces, onFailed); + { + if (_rewarded.IsReady()) + _rewarded.Show(onSucces, onFailed); + else + Debug.LogError("Rewarded ads is not ready"); + } else - throw new InvalidOperationException("Rewarded ads is disabled"); + { + Debug.LogError("Rewarded ads is disabled"); + return; + } } public static bool IsBannerVisible() { if (_banner == null) - throw new NullReferenceException("Ads bridge object does not implement IBannerBridge"); + { + Debug.LogError("Ads bridge object does not implement IBannerBridge"); + return false; + } if (CoreSettings.data.needBanner) _banner.IsVisible(); else - throw new InvalidOperationException("Banner ads is disabled"); + { + Debug.LogError("Banner ads is disabled"); + return false; + } return false; } @@ -187,12 +233,18 @@ namespace Core.Ads return; if (_banner == null) - throw new NullReferenceException("Ads bridge object does not implement IBannerBridge"); + { + Debug.LogError("Ads bridge object does not implement IBannerBridge"); + return; + } if (CoreSettings.data.needBanner) _banner.Show(position); else - throw new InvalidOperationException("Banner ads is disabled"); + { + Debug.LogError("Banner ads is disabled"); + return; + } } public static void HideBanner() @@ -200,12 +252,18 @@ namespace Core.Ads Debug.Log("Called hide banner"); if (_banner == null) - throw new NullReferenceException("Ads bridge object does not implement IBannerBridge"); + { + Debug.LogError("Ads bridge object does not implement IBannerBridge"); + return; + } if (CoreSettings.data.needBanner) _banner.Hide(); else - throw new InvalidOperationException("Banner ads is disabled"); + { + Debug.LogError("Banner ads is disabled"); + return; + } } } } diff --git a/Assets_DLL/Core/Ads/Bridges/DemoAds/DemoBannerAds.cs b/Assets_DLL/Core/Ads/Bridges/DemoAds/DemoBannerAds.cs index f403e2d..2cc96c2 100644 --- a/Assets_DLL/Core/Ads/Bridges/DemoAds/DemoBannerAds.cs +++ b/Assets_DLL/Core/Ads/Bridges/DemoAds/DemoBannerAds.cs @@ -42,11 +42,12 @@ namespace Core.Ads.Bridges.DemoAds private Vector2 CalculateBannerSize() { - float bannerSizePixels = Screen.height <= 400 ? 32 : Screen.height < 720 ? 50 : 90; - var percent = (100f / Screen.height) * bannerSizePixels; - var bannerSize = Screen.height * (percent / 100f); + int screenWidth = Screen.width; + int screenHeight = Screen.height; - return new Vector2(bannerSize * 6.4f, bannerSize); + float scale = Mathf.Max(screenWidth, screenHeight) / 640; + + return new Vector2(320.0f * scale, 50.0f * scale); } private Vector2 CalculateBannerPosition(Vector2 bannerSize) { diff --git a/Assets_DLL/Core/Ads/RewardedButton.cs b/Assets_DLL/Core/Ads/RewardedButton.cs index bb725e4..db0fbe4 100644 --- a/Assets_DLL/Core/Ads/RewardedButton.cs +++ b/Assets_DLL/Core/Ads/RewardedButton.cs @@ -3,6 +3,7 @@ using Core.IAP; using Core.Settings; using UnityEngine; using UnityEngine.Events; +using UnityEngine.Purchasing; using UnityEngine.UI; namespace Core.Ads @@ -47,12 +48,12 @@ namespace Core.Ads PurchaseManager.OnPurchaseSuccess -= CheckAdsEnablingAfterPurchasing; } - private void CheckAdsEnablingAfterPurchasing(string productId) + private void CheckAdsEnablingAfterPurchasing(Product productId) { - if (CoreSettings.data.IsProductConsumable(productId)) + if (CoreSettings.data.IsProductConsumable(productId.definition.id)) return; - if (CoreSettings.data.IsOnAdsProduct(productId)) + if (CoreSettings.data.IsOnAdsProduct(productId.definition.id)) gameObject.SetActive(false); } } diff --git a/Assets_DLL/Core/Audio/AudioController.cs b/Assets_DLL/Core/Audio/AudioController.cs index ef7cbc4..55c9962 100644 --- a/Assets_DLL/Core/Audio/AudioController.cs +++ b/Assets_DLL/Core/Audio/AudioController.cs @@ -1,38 +1,31 @@ using Core.Localization; +using Core.Settings; +using Core.Tools.Saves; using System.Collections.Generic; using System.Linq; using UnityEngine; -using Core.Settings; -using Core.Tools.Saves; namespace Core.Audio { - public class AudioController : MonoBehaviour + public static class AudioController { - private static AudioController _controller = null; + private static List _audioPlayers = new List(); - private static AudioController2D _audio2D = null; - private static AudioController3D _audio3D = null; + private static Dictionary _nonLocalizedSoundsDictionary = new Dictionary(); + private static Dictionary> _localizedSoundDictionary = new Dictionary>(); + + private static GameObject _parent = null; internal static void Init() { - GameObject audioParent = new GameObject("[AudioController]"); - - _controller = audioParent.AddComponent(); - - GameObject.DontDestroyOnLoad(audioParent); - - Dictionary musicAnsSoundsDictionary = new Dictionary(); - Dictionary> languageVoicesDictionary = new Dictionary>(); + _parent = new GameObject("[AudioController]"); - AudioClip[] music = Resources.LoadAll("Audio/Musics"); - AudioClip[] sounds = Resources.LoadAll("Audio/Sounds"); + GameObject.DontDestroyOnLoad(_parent); - for (int i = 0; i < music.Length; i++) - musicAnsSoundsDictionary.Add(music[i].name, music[i]); + AudioClip[] nonLocalizedSounds = Resources.LoadAll("Audio/NonLocalizedSounds"); - for (int i = 0; i < sounds.Length; i++) - musicAnsSoundsDictionary.Add(sounds[i].name, sounds[i]); + 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++) { @@ -40,94 +33,304 @@ namespace Core.Audio Dictionary voicesDictionary = new Dictionary(); - AudioClip[] voices = Resources.LoadAll("CoreAudio/Voices/" + language.ToString()); + AudioClip[] voices = Resources.LoadAll("CoreAudio/LocalizedSounds/" + language.ToString()); for (int i = 0; i < voices.Length; i++) voicesDictionary.Add(voices[i].name, voices[i]); - languageVoicesDictionary.Add(language, voicesDictionary); + _localizedSoundDictionary.Add(language, voicesDictionary); } + } - _audio2D = new AudioController2D(); - _audio2D.Init(audioParent.transform, musicAnsSoundsDictionary, languageVoicesDictionary); + public static AudioPlayer CreatePlayer(string clipName) => + CreatePlayer(FindAudioClip(clipName)); - _audio3D = new AudioController3D(); - _audio3D.Init(audioParent.transform, musicAnsSoundsDictionary, languageVoicesDictionary); - } + #region AudioPlayer manager - public static float MusicVolume + public static AudioPlayer CreatePlayer(AudioClip clip) { - get => SaveManager.GetFloat("MusicVolume", 1f); - set + if (clip == null) + return null; + + AudioPlayer player = _audioPlayers.Where(p => p.AudioClip == null).FirstOrDefault(); + + if (player == null) { - SaveManager.SetFloat("MusicVolume", value); - _audio2D.MusicVolume = value; + GameObject newPlayer = new GameObject("AudioPlayer"); + newPlayer.transform.SetParent(_parent.transform); + + newPlayer.AddComponent(); + player = newPlayer.AddComponent(); + + player.OnNeedDestroy += DestroyPlayer; + + _audioPlayers.Add(player); } + + player.Init(clip); + + return player; } - public static float SoundsVolume + private static void DestroyPlayer(AudioPlayer player) { - get => SaveManager.GetFloat("MusicVolume", 1f); - set - { - SaveManager.SetFloat("MusicVolume", value); - _audio2D.SoundsVolume = value; - } + _audioPlayers.Remove(player); + + GameObject gameObject = player.gameObject; + + GameObject.Destroy(player); + + player = gameObject.AddComponent(); + + player.OnNeedDestroy += DestroyPlayer; + + _audioPlayers.Add(player); } - public static float VoicesVolume + #endregion + + #region Volume + + public static void SetVolume(AudioGroup group, float volume) { - get => SaveManager.GetFloat("MusicVolume", 1f); - set + SaveManager.SetFloat(group.ToString() + "_volume", volume); + + for (int i = 0; i < _audioPlayers.Count; i++) { - SaveManager.SetFloat("MusicVolume", value); - _audio2D.VoicesVolume = value; + if (_audioPlayers[i].AudioClip != null && _audioPlayers[i].AudioGroup == group) + _audioPlayers[i].UpdateVolume(); } } - public static void PlayMusic(string name) => - _controller.StartCoroutine(_audio2D.PlayMusic(name)); + 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); - public static void StopMusic() => - _controller.StartCoroutine(_audio2D.StopMusic()); + if (clip == null) + return null; - public static float PlaySound(string name, bool isLoop = false) => - _audio2D.PlaySound(name, isLoop); + return FindPlayers(clip, -1, -1); + } - public static void StopSound(string name) + public static AudioPlayer[] FindPlayers(string clipName, AudioGroup group) { - _audio2D.StopSound(name); - _audio3D.StopSound(name); + AudioClip clip = FindAudioClip(clipName); + + if (clip == null) + return null; + + return FindPlayers(clip, (int)group, -1); } - public static float PlayVoice(string name) => - _audio2D.PlayVoice(name); + 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 void StopVoice(string name) + public static AudioPlayer[] FindPlayers(string clipName, AudioGroup group, SourceType type) { - _audio2D.StopVoice(name); - _audio3D.StopVoice(name); + AudioClip clip = FindAudioClip(clipName); + + if (clip == null) + return null; + + return FindPlayers(clip, (int)group, (int)type); } - public static float PlaySound(string name, Transform target, float minDistance, float maxDistance, bool isLoop = false) => - _audio3D.PlaySound(name, target, minDistance, maxDistance, isLoop); + 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 float PlayVoice(string name, Transform target, float minDistance, float maxDistance) => - _audio3D.PlayVoice(name, target, minDistance, maxDistance); + public static AudioPlayer[] FindPlayers(AudioClip clip, AudioGroup group, SourceType type) => + FindPlayers(clip, (int)group, (int)type); - private Transform _currentTarget = null; + public static AudioPlayer[] FindPlayers(AudioGroup group) => + FindPlayers(null, (int)group, -1); - private void Update() + 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) { - if (_currentTarget == null) + AudioPlayer[] audioPlayers = new AudioPlayer[0]; + + if (clip != null && group != -1 && type != -1) { - AudioListener listener = FindObjectOfType(); + AudioGroup audioGroup = (AudioGroup)group; + SourceType sourceType = (SourceType)type; + + audioPlayers = _audioPlayers.Where(p => p.AudioClip == clip && p.AudioGroup == audioGroup && p.SourceType == sourceType).ToArray(); - if (listener != null) - _currentTarget = listener.transform; + return audioPlayers; } - else - transform.position = _currentTarget.position; + + 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; } } } \ No newline at end of file diff --git a/Assets_DLL/Core/Audio/AudioController2D.cs b/Assets_DLL/Core/Audio/AudioController2D.cs deleted file mode 100644 index c4f9344..0000000 --- a/Assets_DLL/Core/Audio/AudioController2D.cs +++ /dev/null @@ -1,202 +0,0 @@ -using Core.Localization; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using Core.Settings; -using Core.Tools.Saves; -using System; -using System.Collections; - -namespace Core.Audio -{ - internal class AudioController2D - { - internal void Init(Transform parent, Dictionary musicAnsSounds, Dictionary> voicesDictionary) - { - GameObject audioParent = new GameObject("[2D]"); - audioParent.transform.SetParent(parent); - - _musicParent = new GameObject("[Music]"); - _musicParent.transform.SetParent(audioParent.transform); - - _soundsParent = new GameObject("[Sounds]"); - _soundsParent.transform.SetParent(audioParent.transform); - - _voicesParent = new GameObject("[Voices]"); - _voicesParent.transform.SetParent(audioParent.transform); - - _musicAndSounds = musicAnsSounds; - _voicesDictionary = voicesDictionary; - } - - private GameObject _musicParent = null; - private GameObject _soundsParent = null; - private GameObject _voicesParent = null; - - private AudioSource _musicSource = null; - private List _soundsSources = new List(); - private List _voicesSources = new List(); - - private Dictionary _musicAndSounds = new Dictionary(); - private Dictionary> _voicesDictionary = new Dictionary>(); - - internal float MusicVolume - { - get => SaveManager.GetFloat("MusicVolume", 1f); - set => _musicSource.volume = CoreSettings.data.musicVolume * value; - } - - internal float SoundsVolume - { - get => SaveManager.GetFloat("MusicVolume", 1f); - set - { - for (int i = 0; i < _soundsSources.Count; i++) - _soundsSources[i].volume = CoreSettings.data.soundsVolume * value; - } - } - - internal float VoicesVolume - { - get => PlayerPrefs.GetFloat("MusicVolume", 1f); - set - { - for (int i = 0; i < _voicesSources.Count; i++) - _voicesSources[i].volume = CoreSettings.data.voicesVolume * value; - } - } - - internal IEnumerator PlayMusic(string name) - { - if (_musicSource == null) - { - _musicSource = _musicParent.AddComponent(); - _musicSource.playOnAwake = false; - _musicSource.volume = CoreSettings.data.musicVolume * MusicVolume; - } - - while (_musicSource.volume > 0f) - { - yield return null; - _musicSource.volume -= Time.deltaTime / 2f; - } - - _musicSource.volume = 0; - - if (_musicAndSounds.ContainsKey(name)) - { - _musicSource.clip = _musicAndSounds[name]; - _musicSource.loop = true; - - _musicSource.gameObject.SetActive(true); - _musicSource.enabled = true; - - _musicSource.Play(); - - while (_musicSource.volume < MusicVolume) - { - yield return null; - _musicSource.volume += Time.deltaTime / 2f; - } - - _musicSource.volume = MusicVolume; - } - else - throw new ArgumentNullException($"music \"{name}\" not found"); - } - - internal IEnumerator StopMusic() - { - while (_musicSource.volume > 0f) - { - yield return null; - _musicSource.volume -= Time.deltaTime / 2f; - } - - _musicSource.volume = 0; - - _musicSource.Stop(); - - _musicSource.volume = MusicVolume; - } - - internal float PlaySound(string name, bool isLoop = false) - { - AudioSource playSource = _soundsSources.Where(s => !s.isPlaying).FirstOrDefault(); - - if (playSource == null) - { - playSource = _soundsParent.AddComponent(); - playSource.playOnAwake = false; - playSource.volume = CoreSettings.data.soundsVolume * SoundsVolume; - - _soundsSources.Add(playSource); - } - - if (_musicAndSounds.ContainsKey(name)) - { - playSource.clip = _musicAndSounds[name]; - playSource.loop = isLoop; - - playSource.gameObject.SetActive(true); - playSource.enabled = true; - - playSource.Play(); - - return _musicAndSounds[name].length; - } - else - throw new ArgumentNullException($"sound \"{name}\" not found"); - } - - internal void StopSound(string name) - { - AudioSource playSource = _soundsSources.Where(s => s.clip.name == name).FirstOrDefault(); - - if (playSource != null) - playSource.Stop(); - } - - internal float PlayVoice(string name) - { - AudioSource playSource = _voicesSources.Where(s => !s.isPlaying).FirstOrDefault(); - - if (playSource == null) - { - playSource = _voicesParent.AddComponent(); - playSource.loop = false; - playSource.playOnAwake = false; - playSource.volume = CoreSettings.data.voicesVolume * VoicesVolume; - - _voicesSources.Add(playSource); - } - - if (_voicesDictionary.ContainsKey(LocalizationManager.CurrentLanguage)) - { - if (_voicesDictionary[LocalizationManager.CurrentLanguage].ContainsKey(name)) - { - playSource.clip = _voicesDictionary[LocalizationManager.CurrentLanguage][name]; - - playSource.gameObject.SetActive(true); - playSource.enabled = true; - - playSource.Play(); - - return _voicesDictionary[LocalizationManager.CurrentLanguage][name].length; - } - else - throw new ArgumentNullException($"voice \"{name}\" not found"); - } - else - throw new ArgumentNullException($"Avoice \"{name}\" not found"); - } - - internal void StopVoice(string name) - { - AudioSource playSource = _voicesSources.Where(s => s.clip.name == name).FirstOrDefault(); - - if (playSource != null) - playSource.Stop(); - } - } -} diff --git a/Assets_DLL/Core/Audio/AudioController3D.cs b/Assets_DLL/Core/Audio/AudioController3D.cs deleted file mode 100644 index 9a6f020..0000000 --- a/Assets_DLL/Core/Audio/AudioController3D.cs +++ /dev/null @@ -1,154 +0,0 @@ -using Core.Localization; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using Core.Settings; -using Core.Tools.Saves; -using System; - -namespace Core.Audio -{ - internal class AudioController3D - { - internal void Init(Transform parent, Dictionary musicAnsSounds, Dictionary> voicesDictionary) - { - _musicAndSounds = musicAnsSounds; - _voicesDictionary = voicesDictionary; - } - - private List _soundsSources = new List(); - private List _voicesSources = new List(); - - private Dictionary _musicAndSounds = new Dictionary(); - private Dictionary> _voicesDictionary = new Dictionary>(); - - internal float SoundsVolume - { - get => SaveManager.GetFloat("MusicVolume", 1f); - set - { - for (int i = 0; i < _soundsSources.Count; i++) - { - if (_soundsSources[i] != null) - _soundsSources[i].volume = CoreSettings.data.soundsVolume * value; - } - } - } - - internal float VoicesVolume - { - get => PlayerPrefs.GetFloat("MusicVolume", 1f); - set - { - for (int i = 0; i < _voicesSources.Count; i++) - { - if (_voicesSources[i] != null) - _voicesSources[i].volume = CoreSettings.data.voicesVolume * value; - } - } - } - - internal float PlaySound(string name, Transform target, float minDistance, float maxDistance, bool isLoop = false) - { - AudioSource playSource = _soundsSources.Where(s => s != null && !s.isPlaying).FirstOrDefault(); - - Debug.LogError($"enable: {playSource.enabled}, active: {playSource.gameObject.activeSelf}"); - - if (playSource == null) - { - GameObject sound = new GameObject("Sound"); - playSource = sound.AddComponent(); - playSource.playOnAwake = false; - playSource.volume = CoreSettings.data.soundsVolume * SoundsVolume; - playSource.spatialBlend = 1f; - playSource.rolloffMode = AudioRolloffMode.Custom; - playSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, AnimationCurve.Linear(0f, 1f, 1f, 0f)); - - _soundsSources.Add(playSource); - } - - if (_musicAndSounds.ContainsKey(name)) - { - playSource.clip = _musicAndSounds[name]; - playSource.loop = isLoop; - playSource.minDistance = minDistance; - playSource.maxDistance = maxDistance; - playSource.transform.SetParent(target); - playSource.transform.localPosition = Vector3.zero; - playSource.spatialBlend = 1f; - playSource.rolloffMode = AudioRolloffMode.Custom; - playSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, AnimationCurve.Linear(0f, 1f, 1f, 0f)); - - playSource.gameObject.SetActive(true); - playSource.enabled = true; - - playSource.Play(); - - return _musicAndSounds[name].length; - } - else - throw new ArgumentNullException($"sound \"{name}\" not found"); - } - - internal void StopSound(string name) - { - AudioSource playSource = _soundsSources.Where(s => s != null && s.clip.name == name).FirstOrDefault(); - - if (playSource != null) - playSource.Stop(); - } - - internal float PlayVoice(string name, Transform target, float minDistance, float maxDistance) - { - AudioSource playSource = _voicesSources.Where(s => s != null && !s.isPlaying).FirstOrDefault(); - - if (playSource == null) - { - GameObject voice = new GameObject("Voice"); - playSource = voice.AddComponent(); - playSource.loop = false; - playSource.playOnAwake = false; - playSource.volume = CoreSettings.data.voicesVolume * VoicesVolume; - playSource.spatialBlend = 1f; - playSource.rolloffMode = AudioRolloffMode.Custom; - playSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, AnimationCurve.Linear(0f, 1f, 1f, 0f)); - - _voicesSources.Add(playSource); - } - - if (_voicesDictionary.ContainsKey(LocalizationManager.CurrentLanguage)) - { - if (_voicesDictionary[LocalizationManager.CurrentLanguage].ContainsKey(name)) - { - playSource.clip = _voicesDictionary[LocalizationManager.CurrentLanguage][name]; - playSource.minDistance = minDistance; - playSource.maxDistance = maxDistance; - playSource.transform.SetParent(target); - playSource.transform.localPosition = Vector3.zero; - playSource.spatialBlend = 1f; - playSource.rolloffMode = AudioRolloffMode.Custom; - playSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, AnimationCurve.Linear(0f, 1f, 1f, 0f)); - - playSource.gameObject.SetActive(true); - playSource.enabled = true; - - playSource.Play(); - - return _voicesDictionary[LocalizationManager.CurrentLanguage][name].length; - } - else - throw new ArgumentNullException($"voice \"{name}\" not found"); - } - else - throw new ArgumentNullException($"voice \"{name}\" not found"); - } - - internal void StopVoice(string name) - { - AudioSource playSource = _voicesSources.Where(s => s != null && s.clip.name == name).FirstOrDefault(); - - if (playSource != null) - playSource.Stop(); - } - } -} diff --git a/Assets_DLL/Core/Audio/AudioPlayer.cs b/Assets_DLL/Core/Audio/AudioPlayer.cs new file mode 100644 index 0000000..746574d --- /dev/null +++ b/Assets_DLL/Core/Audio/AudioPlayer.cs @@ -0,0 +1,190 @@ +using Core.Settings; +using System; +using System.Collections; +using UnityEngine; + +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 + { + internal event Action 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(); + + _onComplete = null; + + _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; + + 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)); + } + + return this; + } + + public AudioPlayer SetTarget(Transform target) + { + _target = target; + return this; + } + + public AudioPlayer SetMinDistance(float minDistance) + { + _audioSource.minDistance = minDistance; + return this; + } + + public AudioPlayer SetMaxDistance(float maxDistance) + { + _audioSource.maxDistance = maxDistance; + return this; + } + + public AudioPlayer SetCustomVolume(float volume) + { + _customVolume = volume; + + UpdateVolume(); + + return this; + } + + public AudioPlayer SetGroup(AudioGroup group) + { + _group = group; + + UpdateVolume(); + + return this; + } + + public AudioPlayer SetLoop(bool loop) + { + _isLoop = loop; + + _audioSource.loop = _isLoop; + + return this; + } + + public AudioPlayer OnComplete(Action onComplete) + { + _onComplete += onComplete; + + return this; + } + + public AudioPlayer Play() => + Play(0f); + + public AudioPlayer Play(float delay) + { + _playCoroutine = StartCoroutine(PlayCoroutine(delay)); + + return this; + } + + private IEnumerator PlayCoroutine(float delay) + { + if (_audioSource.isPlaying) + yield break; + + if (delay > 0f) + yield return new WaitForSeconds(delay); + + _audioSource.Play(); + + if (_isLoop) + yield break; + + while (_audioSource.isPlaying) + yield return null; + + _onComplete?.Invoke(); + + Stop(); + } + } +} diff --git a/Assets_DLL/Core/Audio/PlayAudioFile.cs b/Assets_DLL/Core/Audio/PlayAudioFile.cs index b2a89db..4f5658d 100644 --- a/Assets_DLL/Core/Audio/PlayAudioFile.cs +++ b/Assets_DLL/Core/Audio/PlayAudioFile.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Linq; using UnityEngine; using UnityEngine.UI; @@ -6,18 +7,6 @@ namespace Core.Audio { public sealed class PlayAudioFile : MonoBehaviour { - public enum SourceType - { - Flat = 0, - Surround = 1, - } - - public enum AudioFileType - { - Music = 0, - Sound = 1, - Voice = 2, - } public enum PlayType { @@ -27,10 +16,11 @@ namespace Core.Audio OnPlayParticle = 3, } - [SerializeField] private SourceType _sourceType = SourceType.Flat; - [SerializeField] private AudioFileType _audioFileType = AudioFileType.Music; + [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; @@ -41,61 +31,65 @@ namespace Core.Audio private bool _isPlaying = false; + private AudioPlayer _currentPlayer = null; + private void Awake() { - _button = GetComponent