备份CatanBuilding瘦身独立工程

This commit is contained in:
JSD\13999
2026-05-26 16:15:54 +08:00
commit 2d0e6a61b7
12001 changed files with 2431925 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
using asap.core;
using Game;
using System.Collections;
using UnityEngine;
using UnityEngine.AddressableAssets;
/// <summary>
/// 播放当前主场景的BGM 钓场、建造、无尽建造
/// </summary>
public struct EventMainBGM
{
}
public class OutPlaySound : MonoBehaviour
{
public enum PlayerType
{
None,
OnEnable,
OnAwake,
OnDisable,
}
public PlayerType playerType = PlayerType.OnEnable;
public SoundMainType mainType = SoundMainType.UI;
public bool isOutDisable = false;
public AssetReferenceT<AudioClip> assetReference;
public float delay = 0f;
public float startTimer = 0f;
AssetReferenceAudioClip assetReferenceAudioClip;
void Awake()
{
if (playerType == PlayerType.OnAwake)
{
PlaySound();
}
}
private void OnEnable()
{
if (playerType == PlayerType.OnEnable)
{
PlaySound();
}
}
private void OnDisable()
{
if (playerType == PlayerType.OnDisable)
{
PlaySound();
}
if (isOutDisable)
{
if (mainType != SoundMainType.BGM)
{
GContext.Publish(new FadeOutEvent(assetReferenceAudioClip.Sound));
assetReferenceAudioClip.mainType = SoundMainType.None;
}
else
{
GContext.Publish(new EventMainBGM());
}
}
}
IEnumerator DelayPlaySound()
{
yield return new WaitForSeconds(delay);
Play();
}
void Play()
{
// Debug.Log($"<color=#57965c>[Audio] {assetReference} Played on {gameObject}.</color>");
assetReferenceAudioClip = new AssetReferenceAudioClip(assetReference, isOutDisable, mainType, startTimer);
GContext.Publish(assetReferenceAudioClip);
}
public void PlaySound()
{
if (assetReference != null && assetReference.RuntimeKeyIsValid())
{
if (delay > 0.001f)
{
StartCoroutine(DelayPlaySound());
}
else
{
Play();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 86226173ed0e18040945739745cb48b7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using UnityEngine;
using asap.core.common;
namespace asap.core
{
public class Sound : MonoBehaviour, IPoolableObject
{
public AudioSource audioSource;
public SoundMainType soundMainType;
public void OnSpawn()
{
soundMainType = SoundMainType.None;
audioSource.volume = 1f;
}
public void OnDespawn()
{
soundMainType = SoundMainType.None;
audioSource.Stop();
audioSource.volume = 1f;
audioSource.priority = 128;
audioSource.loop = false;
audioSource.playOnAwake = false;
audioSource.clip = null;
audioSource.time = 0f;
audioSource.outputAudioMixerGroup = null;
}
private IObjectPool pool;
public void OnPoolCreate(IObjectPool objectPool)
{
pool = objectPool;
if (audioSource == null && this != null)
audioSource = GetComponent<AudioSource>();
}
public void OnPoolDestroy()
{
pool = null;
}
public void ReturnPool()
{
pool?.DespawnObject(this);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fed9d021895aa8b46a5fd35a8a85f459
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,323 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.AddressableAssets;
using UnityEngine.Assertions;
using asap.core.common;
using UnityEngine.ResourceManagement.AsyncOperations;
using System.Threading;
using System;
using UniRx;
namespace asap.core
{
public interface ISoundService
{
[Inject]
public IObjectPoolService poolService { set; }
public int MasterVol { get; set; }
public int BGMVol { get; set; }
public int SFXVol { get; set; }
public int VoiceVol { get; set; }
public Task InitAsync(string mixerAddr = "AudioMixer", string soundPrefabAddr = "sound",
string bgmGroupId = "BGM", string fishingGroupId = "Fishing", string uiGroupId = "UI", string voiceGroupId = "Voice");
public void Release();
public Sound GetNewBgmSound(AudioClip clip, bool loop = true, int priority = 0, float time = 0);
public Sound GetNewFishingSound(AudioClip clip, bool loop = false, int priority = 128, float time = 0);
public Sound GetNewUISound(AudioClip clip, bool loop = false, int priority = 128, float time = 0);
public Sound GetNewVoiceSound(AudioClip clip);
public void ReturnSound(Sound sound);
public void FadeIn(Sound sound, float duration);
public void FadeOut(Sound sound, float duration);
}
public struct LowpassEffectEvt
{
public bool active;
public float transTime;
}
public class SoundService : ISoundService
{
[Inject]
public IObjectPoolService poolService { set; private get; }
private AudioMixer mixer;
private AudioMixerGroup bgmGroup;
private AudioMixerGroup fishingGroup;
private AudioMixerGroup uiGroup;
private AudioMixerGroup voiceGroup;
private AsyncOperationHandle<AudioMixer> mixerHandle;
private AsyncOperationHandle<GameObject> soundPrefabHandle;
private Dictionary<Sound, CancellationTokenSource> SoundFadeTaskDic;
private float bgmVol = 0;
private float fishingVol = 0;
private const float Min_Vol = -80.0f;
private const float Max_Vol = 20.0f;
private const string Master_Vol_Param_Name = "masterVol";
private const string Bgm_Vol_Param_Name = "bgmVol";
private const string Fishing_Vol_Param_Name = "fishingVol";
private const string UI_Vol_Param_Name = "uiVol";
private const string Voice_Vol_Param_Name = "voiceVol";
private const string Lowpass_Cutoff_Frq = "low_cut";
private AudioMixerSnapshot normal;
//private AudioMixerSnapshot lowpass;
private IDisposable lowpassEvtDisposable;
private int _masterVol;
public int MasterVol
{
get { return _masterVol; }
set
{
_masterVol = value;
mixer.SetFloat(Master_Vol_Param_Name, VolInt2Float(_masterVol));
}
}
private int _bgmVol;
public int BGMVol
{
get { return _bgmVol; }
set
{
_bgmVol = value;
mixer.SetFloat(Bgm_Vol_Param_Name, VolInt2Float(_bgmVol) + bgmVol);
}
}
private int _sfxVol;
public int SFXVol
{
get { return _sfxVol; }
set
{
_sfxVol = value;
mixer.SetFloat(Fishing_Vol_Param_Name, VolInt2Float(_sfxVol) + fishingVol);
mixer.SetFloat(UI_Vol_Param_Name, VolInt2Float(_sfxVol));
}
}
private int _voiceVol;
public int VoiceVol
{
get { return _voiceVol; }
set
{
_voiceVol = value;
mixer.SetFloat(Voice_Vol_Param_Name, VolInt2Float(_voiceVol));
}
}
private float VolInt2Float(int value)
{
var vol = Mathf.Clamp(value, 0f, 100f) / 100.0f;
vol = Min_Vol + (Max_Vol - Min_Vol) * vol;
return vol;
}
private AudioMixerGroup FindMixerGroup(string groupId)
{
var groups = mixer.FindMatchingGroups(groupId);
if (groups != null && groups.Length > 0)
return groups[0];
else
{
Debug.LogWarning("Audio mixer group {groupId} is not found");
return null;
}
}
public async Task InitAsync(string mixerAddr = "AudioMixer", string soundPrefabAddr = "sound",
string bgmGroupId = "BGM", string fishingGroupId = "Fishing", string uiGroupId = "UI", string voiceGroupId = "Voice")
{
SoundFadeTaskDic = new Dictionary<Sound, CancellationTokenSource>();
mixerHandle = Addressables.LoadAssetAsync<AudioMixer>(mixerAddr);
mixer = await mixerHandle.Task;
Assert.IsNotNull(mixer);
mixer.GetFloat(Bgm_Vol_Param_Name, out bgmVol);
mixer.GetFloat(Fishing_Vol_Param_Name, out fishingVol);
bgmGroup = FindMixerGroup(bgmGroupId);
fishingGroup = FindMixerGroup(fishingGroupId);
uiGroup = FindMixerGroup(uiGroupId);
voiceGroup = FindMixerGroup(voiceGroupId);
normal = mixer.FindSnapshot("Snapshot");// ("normal");
//lowpass = mixer.FindSnapshot("lowpass");
Assert.IsNotNull(bgmGroup);
Assert.IsNotNull(fishingGroup);
Assert.IsNotNull(uiGroup);
soundPrefabHandle = Addressables.LoadAssetAsync<GameObject>(soundPrefabAddr);
var soundPrefab = await soundPrefabHandle.Task;
Assert.IsNotNull(soundPrefab);
var sound = soundPrefab.GetComponent<Sound>();
Assert.IsNotNull(sound);
lowpassEvtDisposable = GContext.OnEvent<LowpassEffectEvt>().Subscribe(OnLowpassEffectEvt);
poolService.CreatePool<Sound>(sound, 10, 50);
}
private void OnLowpassEffectEvt(LowpassEffectEvt evt)
{
//if (evt.active)
//{
// lowpass.TransitionTo(evt.transTime);
// return;
//}
normal.TransitionTo(evt.transTime);
}
public void Release()
{
foreach (var source in SoundFadeTaskDic.Values)
{
source.Cancel();
}
SoundFadeTaskDic.Clear();
SoundFadeTaskDic = null;
poolService.DestroyPool<Sound>();
Addressables.Release(mixerHandle);
Addressables.Release(soundPrefabHandle);
lowpassEvtDisposable.Dispose();
lowpassEvtDisposable = null;
}
public void FadeIn(Sound sound, float duration)
{
if (SoundFadeTaskDic.TryGetValue(sound, out var s))
{
s.Cancel();
SoundFadeTaskDic[sound].Dispose();
SoundFadeTaskDic.Remove(sound);
}
var source = new CancellationTokenSource();
var token = source.Token;
SoundFadeTaskDic.Add(sound, source);
DoFade(0f, 1f, sound, duration, token);
}
public void FadeOut(Sound sound, float duration)
{
if (SoundFadeTaskDic.TryGetValue(sound, out var s))
{
s.Cancel();
SoundFadeTaskDic[sound].Dispose();
SoundFadeTaskDic.Remove(sound);
}
var source = new CancellationTokenSource();
var token = source.Token;
SoundFadeTaskDic.Add(sound, source);
DoFade(1f, 0f, sound, duration, token);
}
public Sound GetNewBgmSound(AudioClip clip, bool loop = true, int priority = 0, float time = 0)
{
var sound = poolService.SpawnObject<Sound>();
Assert.IsNotNull(sound, "Sound Pool reached max num");
var audioSource = sound.audioSource;
audioSource.clip = clip;
audioSource.loop = loop;
audioSource.priority = priority;
audioSource.time = time;
audioSource.outputAudioMixerGroup = bgmGroup;
audioSource.Pause();
return sound;
}
public Sound GetNewFishingSound(AudioClip clip, bool loop = false, int priority = 128, float time = 0)
{
var sound = poolService.SpawnObject<Sound>();
Assert.IsNotNull(sound, "Sound Pool reached max num");
var audioSource = sound.audioSource;
audioSource.clip = clip;
audioSource.loop = loop;
audioSource.priority = priority;
audioSource.time = time;
audioSource.outputAudioMixerGroup = fishingGroup;
return sound;
}
public Sound GetNewUISound(AudioClip clip, bool loop = false, int priority = 128, float time = 0)
{
var sound = poolService.SpawnObject<Sound>();
Assert.IsNotNull(sound, "Sound Pool reached max num");
var audioSource = sound.audioSource;
audioSource.clip = clip;
audioSource.loop = loop;
audioSource.priority = priority;
audioSource.time = time;
audioSource.outputAudioMixerGroup = uiGroup;
return sound;
}
public Sound GetNewVoiceSound(AudioClip clip)
{
var sound = poolService.SpawnObject<Sound>();
Assert.IsNotNull(sound, "Sound Pool reached max num");
var audioSource = sound.audioSource;
audioSource.clip = clip;
audioSource.loop = false;
audioSource.priority = 128;
audioSource.time = 0;
audioSource.outputAudioMixerGroup = voiceGroup;
return sound;
}
public void ReturnSound(Sound sound)
{
if (SoundFadeTaskDic == null || sound == null)
return;
if (SoundFadeTaskDic.TryGetValue(sound, out var s))
{
s.Cancel();
SoundFadeTaskDic[sound].Dispose();
SoundFadeTaskDic.Remove(sound);
}
if (sound.enabled)
{
poolService.DespawnObject(sound);
}
}
private async void DoFade(float startVol, float endVol, Sound sound, float duration, CancellationToken ct)
{
var elapsedTime = 0f;
sound.audioSource.volume = startVol;
try
{
while (elapsedTime < duration)
{
if (ct.IsCancellationRequested)
{
break;
}
else
{
sound.audioSource.volume = Mathf.Lerp(startVol, endVol, elapsedTime / duration);
elapsedTime += Time.deltaTime;
await Task.Yield();
}
}
Assert.IsNotNull(sound);
sound.audioSource.volume = endVol;
}
finally
{
if (!ct.IsCancellationRequested && SoundFadeTaskDic != null)
{
SoundFadeTaskDic[sound].Dispose();
SoundFadeTaskDic.Remove(sound);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a55d9537d0d5d9649964b270864dfbe4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
public enum SoundType
{
BGM,
Fishing,
UI,
audio_ui_btn_back,
audio_ui_btn_cast,
ThrowingAudio,
ReelingAudio,
ReelingAudioReeling,
LineAudioReeling,
ComboOutAudio,
ComboLoopAudio,
ComboIntoAudio,
HPEvent,
audio_fishing_throwing_baitintowater,
audio_fishing_waiting_fishgathering,
audio_fishing_waiting,
audio_fishing_drawing_ready,
audio_fishing_welldone,
audio_fishing_switchrod,
audio_ui_targetcollect_collecting,
audio_ui_targetcollect_fly,
audio_fishing_linebreak,
audio_ui_fishingmap,
audio_ui_fishingmap_btn_levelup,
audio_ui_fishingmap_fishpointfly,
audio_ui_fishingmap_btn_detail,
audio_fishing_dash,
audio_fishing_fail_forcetoobig,
audio_fishing_fail_forcetoosmall,
audio_fishing_piercing,
audio_fishing_jumpout,
audio_fishing_jumpinto,
}
public enum SoundMainType
{
None,
BGM,
Fishing,
UI,
Voice,
UILoop
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 599ca3e4bb3f4cb459220a8f86d02856
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using asap.core;
using Game;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UI;
[RequireComponent(typeof(Toggle))]
[AddComponentMenu("UGUI/UI/UIToggleSound")]
public class UIToggleSound : MonoBehaviour
{
public AssetReferenceT<AudioClip> assetReference;
public float startTimer = 0f;
public bool isOn = true;
void Start()
{
var btn = gameObject.GetComponent<Toggle>();
if (null != btn)
{
btn.onValueChanged.AddListener(OnClick);
}
}
public void OnClick(bool isOn)
{
if (isOn != this.isOn)
{
return;
}
if (assetReference != null && assetReference.RuntimeKeyIsValid())
{
GContext.Publish(new AssetReferenceAudioClip(assetReference, time: startTimer));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 21ce79533f3d1cf499bdb8880e92d404
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: