using System;using System.Linq;using System.Collections.Generic;using System.Threading;using System.Threading.Tasks; public partial class GetUiSubject { public async Task GetUI() { if (this == null) return; var container = GContext.container; var loginLifetime = container.Resolve().LoginLifetime; HomePanel homePanel = null; if (!fishingData.isMapBuff && !IsHideHomeMap) { var go = await UIManager.Instance.RestartShowUI(UITypes.HomePanel); if (this == null || loginLifetime.IsCancellationRequested || !ReferenceEquals(container, GContext.container)) return; homePanel = go.GetComponent(); } //实例 container.Resolve(); //这里确认补单 await container.Resolve().ReleaseReplenishment(); if (this == null || loginLifetime.IsCancellationRequested || !ReferenceEquals(container, GContext.container)) return; await Awaiters.SecondsRealtime(0.5f); if (this == null || loginLifetime.IsCancellationRequested || !ReferenceEquals(container, GContext.container)) return; container.Resolve().ShowRankTierChange(); if (fishingData.isMapBuff) { fishingData.isMapBuff = false; } else { fishingBehavior?.RodBehaviour.gameObject.SetActive(true); fishingBehavior.cameraAnimator.speed = 1; GContext.Publish(new ShowHandEvent() { isShow = true }); SetMapShow(!IsHideHomeMap); if (IsHideHomeMap) { IsHideHomeMap = false; } else if (homePanel != null) { homePanel.OnStart(); } } } public async Task NewEnterMap(PlayableDirector camera_timeline) { if (this == null) return; var container = GContext.container; var loginLifetime = container.Resolve().LoginLifetime; camera_timeline.gameObject.SetActive(true); fishingBehavior.cameraAnimator.enabled = false; fishingBehavior.cameraAnimator.transform.localEulerAngles = Vector3.zero; fishingBehavior.cameraAnimator.transform.localPosition = Vector3.zero; await Awaiters.Seconds((float)camera_timeline.duration); if (this == null || loginLifetime.IsCancellationRequested || !ReferenceEquals(container, GContext.container)) return; camera_timeline.gameObject.SetActive(false); fishingData.mainCamera.transform.localEulerAngles = Vector3.zero; fishingData.mainCamera.transform.localPosition = Vector3.zero; fishingBehavior.cameraAnimator.enabled = true; GContext.Publish(new EventBGMSound(_curMapData.BGM)); fishingBehavior.cameraAnimator.Play("EnterMap", -1, 0); await OnCameraSpeedEvent(); if (this == null || loginLifetime.IsCancellationRequested || !ReferenceEquals(container, GContext.container)) return; var go = await UIManager.Instance.RestartShowUI(UITypes.HomePanel); if (this == null || loginLifetime.IsCancellationRequested || !ReferenceEquals(container, GContext.container)) return; HomePanel homePanel = go.GetComponent(); homePanel.OnStart(); } public async Task OnCameraSpeedEvent() { if (this == null) return; var container = GContext.container; var loginLifetime = container.Resolve().LoginLifetime; fishingBehavior.cameraAnimator.speed = 1; await Awaiters.Seconds(fishingData.fishingBehaviorConf.rodEnterMapDelay); if (this == null || loginLifetime.IsCancellationRequested || !ReferenceEquals(container, GContext.container)) return; fishingBehavior?.RodBehaviour.gameObject.SetActive(true); GContext.Publish(new ShowHandEvent() { isShow = true }); } } public partial class ManagerSubject { public async Task Init(System.Action progress) { if (residentClip != null || disposables != null) Release(); var version = ++initializationVersion; var container = GContext.container; _tables = container.Resolve(); var opMap = new Dictionary>(); CompositeDisposable pendingSubscriptions = null; bool transferred = false; try { await soundService.InitAsync(); if (version != initializationVersion || !ReferenceEquals(container, GContext.container)) return; foreach (var addr in residentFish) { if (!opMap.ContainsKey(addr)) opMap.Add(addr, Addressables.LoadAssetAsync(addr)); } var tasks = opMap.Values.Select(_ => _.Task).ToArray(); var total = (float)tasks.Length; while (true) { var completed = tasks.Count(_ => _.IsCompleted); if (completed == total) { progress.Invoke(1f); break; } progress.Invoke(completed / total); await Awaiters.NextFrame; if (version != initializationVersion || !ReferenceEquals(container, GContext.container)) return; } if (version != initializationVersion || !ReferenceEquals(container, GContext.container)) return; var loadedClips = opMap.ToDictionary(_ => _.Key, _ => _.Value.Result); pendingSubscriptions = new CompositeDisposable(); GContext.OnEvent().Subscribe(PlaySound).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(PlayRewardSound).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(PlayFishingSound).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(PlayMusic).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(FadeOutEvent).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(PlaySoundByReference).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(PlayVoiceSoundByReference).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(OnChangeRodData).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(OnSoundMute).AddTo(pendingSubscriptions); GContext.OnEvent().Subscribe(OnSoundStateEvent).AddTo(pendingSubscriptions); soundService.BGMVol = container.Resolve().Music ? 80 : 0; soundService.SFXVol = container.Resolve().Sound ? 80 : 0; soundService.VoiceVol = container.Resolve().Sound ? 80 : 0; residentClip = loadedClips; disposables = pendingSubscriptions; transferred = true; } finally { if (!transferred) { pendingSubscriptions?.Dispose(); if (version == initializationVersion) Release(); foreach (var handle in opMap.Values) if (handle.IsValid()) Addressables.Release(handle); } } } public void Release() { initializationVersion++; if (disposables != null) { disposables.Dispose(); disposables = null; } if (residentClip != null) { foreach (var item in residentClip) { if (item.Value != null) { Addressables.Release(item.Value); } } residentClip.Clear(); } if (rewardSoundDic != null) { rewardSoundDic.Clear(); } if (soundService != null) { foreach (var s in _activeFishingLoopSounds.ToList()) { if (s != null) { s.audioSource.Stop(); soundService.ReturnSound(s); } } } _activeFishingLoopSounds.Clear(); if (soundService != null) { soundService.Release(); } if (BGM_Clip != null) { Addressables.Release(BGM_Clip); BGM_Clip = null; } if (BGM_Sound != null && BGM_Sound.gameObject != null) { GameObject.Destroy(BGM_Sound.gameObject); BGM_Sound = null; } BGMName = null; } } public partial class ServiceSubject { public async Task InitAsync(string mixerAddr = "AudioMixer", string soundPrefabAddr = "sound", string bgmGroupId = "BGM", string fishingGroupId = "Fishing", string uiGroupId = "UI", string voiceGroupId = "Voice") { if (mixerHandle.IsValid() || soundPrefabHandle.IsValid() || lowpassEvtDisposable != null) Release(); var version = ++initializationVersion; SoundFadeTaskDic = new Dictionary(); AsyncOperationHandle pendingMixer = default; AsyncOperationHandle pendingPrefab = default; IDisposable pendingSubscription = null; bool transferred = false; try { pendingMixer = Addressables.LoadAssetAsync(mixerAddr); var loadedMixer = await pendingMixer.Task; if (version != initializationVersion) return; mixer = loadedMixer; 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"); Assert.IsNotNull(bgmGroup); Assert.IsNotNull(fishingGroup); Assert.IsNotNull(uiGroup); pendingPrefab = Addressables.LoadAssetAsync(soundPrefabAddr); var soundPrefab = await pendingPrefab.Task; if (version != initializationVersion) return; Assert.IsNotNull(soundPrefab); var sound = soundPrefab.GetComponent(); Assert.IsNotNull(sound); poolService.CreatePool(sound, 10, 50); pendingSubscription = GContext.OnEvent().Subscribe(OnLowpassEffectEvt); mixerHandle = pendingMixer; soundPrefabHandle = pendingPrefab; lowpassEvtDisposable = pendingSubscription; transferred = true; } finally { if (!transferred) { pendingSubscription?.Dispose(); if (version == initializationVersion) Release(); if (pendingPrefab.IsValid()) Addressables.Release(pendingPrefab); if (pendingMixer.IsValid()) Addressables.Release(pendingMixer); } } } public void Release() { initializationVersion++; if (SoundFadeTaskDic != null) { foreach (var source in SoundFadeTaskDic.Values) { source.Cancel(); } SoundFadeTaskDic.Clear(); SoundFadeTaskDic = null; } poolService?.DestroyPool(); if (mixerHandle.IsValid()) Addressables.Release(mixerHandle); mixerHandle = default; if (soundPrefabHandle.IsValid()) Addressables.Release(soundPrefabHandle); soundPrefabHandle = default; lowpassEvtDisposable?.Dispose(); lowpassEvtDisposable = null; } } public partial class StageSubject : StageBase { public async Task RunPrefix() { if (stopping || this == null) return; var loginLifetime = UserService.LoginLifetime; LoadingScreen.SetProgress(0.54f); await Awaiters.NextFrame; if (stopping || this == null || loginLifetime.IsCancellationRequested) return; // wait authorize , 5 sec max var checkAuthorTimes = 0; while (checkAuthorTimes < 10 && !UserService.IsAuthorized) { await Task.Delay(500); if (stopping || this == null || loginLifetime.IsCancellationRequested) return; checkAuthorTimes++; } if (!UserService.IsAuthorized) { Debug.LogWarning("[FishingStage::startAsync] Api Svr not author"); } if (GContext.container.Resolve().Get("DEBUG", "0") == "1") { var console = await UnityEngine.AddressableAssets.Addressables.InstantiateAsync("IngameDebugConsole").Task; if (stopping || this == null || loginLifetime.IsCancellationRequested) { if (console != null) UnityEngine.AddressableAssets.Addressables.ReleaseInstance(console); return; } } await GContext.container.Resolve().Init((progress) => { if (!stopping && this != null && !loginLifetime.IsCancellationRequested) LoadingScreen.SetProgress(0.55f + progress * 0.2f); }); if (stopping || this == null || loginLifetime.IsCancellationRequested) return; Applied=true; } public override async Task Stop() { stopping = true; GContext.container.Unregister(); GContext.container.Unregister(); GContext.container.Resolve()?.DisposeSubscriptions(); GContext.container.Unregister(); disposable?.Dispose(); disposable = null; _autoRestart?.Dispose(); _autoRestart = null; await base.Stop(); } protected override void OnDestroy() { stopping = true; } public async Task RunCatch(){ var loginLifetime=UserService.LoginLifetime; try { await base.StartAsync(); } catch (System.Exception ex) when (stopping || this == null || loginLifetime.IsCancellationRequested) { Debug.LogWarning($"[FishingStage] Startup stopped, cancelled or stage destroyed: {ex.GetType().Name}: {ex.Message}"); return; } if (stopping || this == null || loginLifetime.IsCancellationRequested) return; CatchCompleted=true; } }