using asap.core; using System.Threading.Tasks; using UniRx; using UnityEngine.AddressableAssets; using GameCore; using UnityEngine; using System.Collections.Generic; using cfg; using System; using System.Collections; public struct AquariumEnterMapScene { public bool isShowUI; } public struct EnterMaped { } public struct ChangeFishEvent { public List addFish; public List removeFish; } public class FishingAquariumAct : AGameAct { /// /// 1 == 进匹配 2 == 退出匹配 3 == 进水族馆 4 == 退出水族馆 5 == 退到匹配 /// public static int CloudType = 0; AquariumManager AM; CompositeDisposable disposables; GameObject aquarium; GameObject _light; AquariumFishController aquariumFishController; cfg.Tables _tables; AquariumInit aquariumInit; Material mutantMaterial; GameObject fxLeftEye; GameObject fxRightEye; AquariumPanel aquariumPanel; Dictionary fishUnDownloadAlter = new Dictionary(); public static EventAggregator eventAggregator; public override async Task StartAsync() { eventAggregator = new EventAggregator(); _tables = GContext.container.Resolve(); aquariumInit = _tables.TbAquariumInit.DataList[0]; disposables = new CompositeDisposable(); GContext.container.Unregister(); GContext.container.Unregister(); var fishingData = new FishingData(); GContext.container.RegisterInstance(fishingData); AM = new AquariumManager(); await AM.Synchrodata(); GContext.container.RegisterInstance(AM); eventAggregator.GetEvent().Subscribe(OnEnterMapScene).AddTo(disposables); eventAggregator.GetEvent().Subscribe(OnChangeFishEvent).AddTo(disposables); disposables.Add(GContext.OnEvent().Subscribe(OnInAquariumEnevt)); // 加载场景 GContext.Publish(new HideHomePanelEvent()); mutantMaterial = await Addressables.LoadAssetAsync(_tables.TbFishMutant.Material).Task; fxLeftEye = await Addressables.LoadAssetAsync(_tables.TbFishMutant.FxLeftEye).Task; fxRightEye = await Addressables.LoadAssetAsync(_tables.TbFishMutant.FxRightEye).Task; if (AM.data.isHome || AM.data.slotDatas == null) { await EnterStartScene(); } else { await EnterMapScene(); await Awaiters.Seconds(1); ShowAquariumPanel(); } return await base.StartAsync(); } async void ShowAquariumPanel() { GameObject go = await UIManager.Instance.ShowUILoad(UITypes.AquariumPanel); aquariumPanel = go.GetComponent(); aquariumPanel.Init(this); _ = StartCoroutine(StartTime()); aquariumFishController.cameraManager.MoveCamera(); } async Task EnterStartScene() { await LoadScene(); await UIManager.Instance.ShowUILoad(UITypes.AquariumDetectPanel); } /// /// 提前加载地图,之后加载UI /// /// async Task EnterMapScene() { List slotDatas = AM.data.slotDatas; for (int i = 0; i < AM.data.slot; i++) { AquariumSlotData slotData = slotDatas[i]; Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID); if (!fishUnDownloadAlter.ContainsKey(item.Quality - 1)) { int id = _tables.GetItemData(_tables.TbGlobalConfig.FishUnDownloadAlter[item.Quality - 1]).RedirectID; FishData fishData = _tables.TbFishData.GetOrDefault(id); fishUnDownloadAlter[item.Quality - 1] = await Addressables.LoadAssetAsync(fishData.Fbx).Task; } } await LoadScene(); InitFish(); } async Task LoadScene() { ReleaseAquarium(); var mapData = _tables.TbMapData.DataMap[AM.MapId]; string prefabName = mapData.AquariumPrefab; aquarium = await Addressables.InstantiateAsync(prefabName).Task; if (disposables == null) { ReleaseAquarium(); return; } aquariumFishController = aquarium.GetComponent(); aquariumFishController.fishManager.MaxLoadTime = 50; aquariumFishController.cameraManager.PlayAquarium(this); } async void OnEnterMapScene(AquariumEnterMapScene aem) { if (aem.isShowUI) { ShowAquariumPanel(); } else if (AM.data.isHome || AM.data.slotDatas == null) { CloudType = 5; await UIManager.Instance.ShowUINotLoading(UITypes.AquariumCloudPanel); await Awaiters.Seconds(0.75f); await EnterStartScene(); UIManager.Instance.DestroyUI(UITypes.AquariumReportPopupPanel); aquariumPanel = null; UIManager.Instance.DestroyUI(UITypes.AquariumPanel); GContext.Publish(new EndTransition()); } else { await EnterMapScene(); eventAggregator.Publish(new EnterMaped()); } } void OnChangeFishEvent(ChangeFishEvent e) { List removeFish = e.removeFish; if (removeFish != null && removeFish.Count > 0) { for (int i = 0; i < removeFish.Count; i++) { aquariumFishController.fishManager.RemoveFish(removeFish[i]); } } List addFish = e.addFish; if (addFish != null && addFish.Count > 0) { List slotDatas = AM.data.slotDatas; List aquariumResultDatas = AM.data.aquariumResultDatas; for (int i = 0; i < addFish.Count; i++) { //当蛋孵化时添加鱼 int index = addFish[i]; AquariumSlotData slotData = slotDatas[index]; var time = ZZTimeHelper.UtcNow(); if (slotData.FishHatchTime() < time && !slotData.IsResult() && !aquariumResultDatas[index].IsResult()) { EggToFish(slotData, index); } } } } /// ///蛋孵化 添加鱼 /// /// /// void EggToFish(AquariumSlotData slotData, int index) { aquariumFishController.fishEggManager.RemoveEgg(index); AddFish(slotData, index, slotData.fishMQ); } void OnInAquariumEnevt(InGradeAquariumEvent e) { Debug.Log("OnInAquariumEnevt"); if (aquarium != null) { aquarium.SetActive(e.type == 1); } } void InitFish() { List slotDatas = AM.data.slotDatas; if (slotDatas == null) { return; } aquariumFishController.fishManager.fishUnDownloadAlter = fishUnDownloadAlter; var time = ZZTimeHelper.UtcNow(); List aquariumResultDatas = AM.data.aquariumResultDatas; for (int i = 0; i < AM.data.slot; i++) { AquariumSlotData slotData = slotDatas[i]; slotData.index = i; var HatchTime = slotData.FishHatchTime(); if (HatchTime < time) { if (!slotData.IsResult() && !aquariumResultDatas[i].IsResult()) { //检查是否受伤 //正常的成长时间 自然时间+加速成长-总恢复时间 float normalH = (float)(time - HatchTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime; float injuryH = slotData.injuryGrowthTime; int fishQ = slotData.fishMQ; if (injuryH < normalH) { AM.data.aquariumHurtDatas[i].fishLQ = 0; } else { fishQ -= AM.data.aquariumHurtDatas[i].fishLQ; if (fishQ <= 0) { fishQ = 1; } } AddFish(slotData, i, fishQ); } } else { //初始化蛋 aquariumFishController.fishEggManager.AddEgg(slotData); } } } IEnumerator StartTime() { List slotDatas = AM.data.slotDatas; List aquariumResultDatas = AM.data.aquariumResultDatas; for (int i = 0; i < AM.Slot; i++) { if (!aquariumResultDatas[i].IsResult() && !slotDatas[i].IsResult()) { SetFishScale(slotDatas[i], i); } } while (aquariumPanel != null) { DateTime dateTime = ZZTimeHelper.UtcNow(); aquariumPanel.OnUpdate(dateTime); for (int i = 0; i < AM.Slot; i++) { if (!aquariumResultDatas[i].IsResult() && !slotDatas[i].IsResult() && slotDatas[i].FishGrowthTime() > dateTime) { SetFishScale(slotDatas[i], i); } } yield return Awaiters.Seconds(1); } } /// /// 加载鱼的模型 /// /// /// void AddFish(AquariumSlotData aquariumSlotData, int index, int count) { aquariumFishController.fishManager.AddFish( mutantMaterial, fxLeftEye, fxRightEye, aquariumSlotData, count, index); } GameObject reportPrefab; int reportIndex; public async Task LoadFish(int index, Transform fishParent) { reportIndex = index; AquariumSlotData slotData = AM.data.slotDatas[index]; Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID); var fishData = _tables.TbFishData.GetOrDefault(item.RedirectID); if (reportPrefab != null) { Addressables.ReleaseInstance(reportPrefab); reportPrefab = null; } var Prefab = await Addressables.InstantiateAsync(fishData.Fbx, fishParent).Task; if (fishParent == null || reportIndex != index) { Addressables.ReleaseInstance(Prefab); Prefab = null; return null; } else if (Prefab != null) { reportPrefab = Prefab; var fish = reportPrefab.GetComponent(); fish.animator.transform.localPosition = Vector3.zero; fish.EnableCollider(); fish.animator.Play("Swim01", 0, UnityEngine.Random.Range(0, 0.8f)); fish.animator.transform.localPosition = Vector3.zero; reportPrefab.transform.localPosition = Vector3.zero; reportPrefab.transform.localScale = Vector3.one * fishData.TankScale; var TankRotation = fishData.TankRotation; reportPrefab.transform.localRotation = Quaternion.Euler(TankRotation[0], TankRotation[1], TankRotation[2]); if (slotData.mutants <= 0 || mutantMaterial == null) { return reportPrefab; } float eyeScale = _tables.TbFishMutant.FxAquariumScale[fishData.Quality - 1]; if (fish.LeftEye != null && fxLeftEye != null) { var leftEye = Instantiate(fxLeftEye); leftEye.transform.localScale = Vector3.one * eyeScale; leftEye.transform.parent = fish.LeftEye; leftEye.transform.localPosition = Vector3.zero; leftEye.transform.localRotation = Quaternion.identity; } if (fish.RightEye != null && fxRightEye != null) { var rightEye = Instantiate(fxRightEye); rightEye.transform.localScale = Vector3.one * eyeScale; rightEye.transform.parent = fish.RightEye; rightEye.transform.localPosition = Vector3.zero; rightEye.transform.localRotation = Quaternion.identity; } Renderer[] meshRenderer = reportPrefab.GetComponentsInChildren(); if (meshRenderer != null && meshRenderer.Length > 0) { var render = meshRenderer[0]; var materials = render.materials; for (int i = 0; i < materials.Length; i++) { var material = materials[i]; var material_P = new Material(mutantMaterial); material_P.SetTexture("_BaseMap", material.GetTexture("_BaseMap")); material_P.SetTexture("_BumpMap", material.GetTexture("_BumpMap")); materials[i] = material_P; } render.materials = materials; } } return reportPrefab; } /// /// 刷新鱼的大小 /// /// /// void SetFishScale(AquariumSlotData slotData, int index) { var dateTime = ZZTimeHelper.UtcNow(); DateTime startTime = slotData.FishHatchTime(); float normalH = (float)(dateTime - startTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime; float progress = normalH / slotData.growthTime; if (progress > 1) { progress = 1; } Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID); FishData fishData = _tables.TbFishData.GetOrDefault(item.RedirectID); float scale = fishData.AquariumMinScale + (fishData.AquariumMaxScale - fishData.AquariumMinScale) * progress; aquariumFishController.fishManager.SetFishScale(index, scale, slotData.mutants, _tables.TbFishMutant.AquariumScale[fishData.Quality - 1]); } void ReleaseAquarium() { if (aquarium != null) { Addressables.ReleaseInstance(aquarium); aquarium = null; } } public override async System.Threading.Tasks.Task StopAsync() { if (reportPrefab != null) { Addressables.ReleaseInstance(reportPrefab); reportPrefab = null; } if (mutantMaterial != null) { Addressables.Release(mutantMaterial); mutantMaterial = null; } if (fxLeftEye != null) { Addressables.Release(fxLeftEye); fxLeftEye = null; } if (fxRightEye != null) { Addressables.Release(fxRightEye); fxRightEye = null; } eventAggregator = null; ReleaseAquarium(); if (fishUnDownloadAlter != null) { foreach (var item in fishUnDownloadAlter) { Addressables.Release(item.Value); } } disposables?.Dispose(); disposables = null; aquariumPanel = null; UIManager.Instance.DestroyUI(UITypes.AquariumDetectPanel); UIManager.Instance.DestroyUI(UITypes.AquariumPanel); GContext.container.Unregister(); GContext.container.Unregister(); await base.StopAsync(); } public void OnClickFish(int index) { aquariumPanel.OnClickFish(index); } #region UI操作 public bool CanDragMove() { return aquariumPanel != null && aquariumPanel.CanDragMove; } public void FollowFishCamera(AquariumSlotData slotData, bool isEgg) { if (isEgg) { var egg = aquariumFishController.fishEggManager.GetEgg(slotData.index); aquariumFishController.cameraManager.FollowFishCamera(egg); } else { var fish = aquariumFishController.fishManager.GetFish(slotData.index); aquariumFishController.cameraManager.FollowFishCamera(fish); } } public void StopFollowFishCamera() { aquariumFishController.cameraManager.StopFollowFishCamera(); } #endregion protected override void OnDestroy() { } }