using Assets.MyGame.Scripts.Net; using Assets.MyGame.Scripts.Net.API; using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass; using Assets.MyGame.Scripts.Net.APIResponses.Enum; using Assets.MyGame.Scripts.Net.WebResponses; using cfg; using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Threading; using Unity.Collections; using Unity.Jobs; using UnityEditor; using UnityEngine; using Random = UnityEngine.Random; public class CreateFishManager : MonoSingleton { #region //这里不用了 但是留着 /*public CreateFishData createFishData; public async void InitCreateFishData(string path) { createFishData = await Addressables.LoadAssetAsync(path).Task; } public string path;*/ /// /// 全局配置(外部初始化) /// //public GameConfig M_GameConfig { get { return GameManager.Instance.gameConfig; } } #endregion public GameConfig M_GameConfig => GameManager.Instance.gameConfig; // 缓存字段 private Dictionary roomFishConfig; private Dictionary> createDic; private Dictionary fishDatas; public Dictionary fishDatas_hashCodekey=new Dictionary(); public Dictionary FishDatas { get { if (fishDatas != null) return fishDatas; fishDatas =new Dictionary(); foreach (var item in M_GameConfig.fishTypeConfigs) { fishDatas.Add(item.fishNumber, item); } return fishDatas; } } #region 初始化鱼生成配置 /// /// 懒加载初始化(只执行一次) /// private void EnsureInit() { if (roomFishConfig != null) return; FishYZ.Init(); roomFishConfig = new Dictionary(); createDic = new Dictionary>(); var list = GameManager.Instance.gameConfig.roomFishConfigs; if (list == null || list.Count == 0) return; foreach (var item in list) { GameTypeEnum gameType = (GameTypeEnum)item.gameType; // 安全添加(避免重复 key 抛异常) roomFishConfig[gameType] = item; // 初始化子字典 var fishDic = new Dictionary(); createDic[gameType] = fishDic; // 普通鱼 if (item.normalFishList != null) { foreach (var fish in item.normalFishList) fishDic[fish.fishNumber] = fish; } // 等级鱼(若与基础鱼相同素材替换基础的) if (item.roomFishLevelList != null) { foreach (var fish in item.roomFishLevelList) fishDic[fish.fishNumber] = fish; } } } /// /// 房间鱼配置(按游戏类型) /// public Dictionary RoomFishConfig { get { EnsureInit(); return roomFishConfig; } } /// /// 鱼号 → 鱼配置(按游戏类型) /// public Dictionary> CreateDic { get { EnsureInit(); return createDic; } } #endregion #region // 鱼生成计时器相关 private NativeArray timers; private NativeArray frequencies; private NativeArray shouldSpawn; public GameObject dieFXPrefab; private List spawnList; // 当前房间的鱼配置 public void InitSpawnSystem(GameTypeEnum gameType) { EnsureInit(); var config = RoomFishConfig[gameType]; spawnList = new List(); // 合并普通鱼 + 等级鱼 spawnList.AddRange(config.normalFishList); spawnList.AddRange(config.roomFishLevelList); int count = spawnList.Count; timers = new NativeArray(count, Allocator.Persistent); frequencies = new NativeArray(count, Allocator.Persistent); shouldSpawn = new NativeArray(count, Allocator.Persistent); for (int i = 0; i < count; i++) { timers[i] = 0; frequencies[i] = spawnList[i].fishFrequency; shouldSpawn[i] = 0; } } public void CloseSpawnSystem() { spawnList = null; } #endregion /// /// 鱼的父节点(用于层级管理) /// public Transform fishRoot; protected void Awake() { if (fishRoot == null) { fishRoot = new GameObject("FishRoot").transform; } // CreateSingleFish(); new FishResourcesData(); //这里用来测试加载鱼预制体 } private void Update() { if (spawnList == null) return; var job = new FishSpawnTimerJob { deltaTime = Time.deltaTime, timers = timers, frequencies = frequencies, shouldSpawn = shouldSpawn }; JobHandle handle = job.Schedule(); handle.Complete(); // 主线程执行生成 for (int i = 0; i < spawnList.Count; i++) { if (shouldSpawn[i] == 1) { var fish = spawnList[i]; SpawnFishMainThread(fish); } } } private async void SpawnFishMainThread(RoomFishDetailConfig cfg) { if (cfg.type==1) { bool flowControl = OnlyFish(cfg); if (!flowControl) { return; } } else if (cfg.type==2) { //cfg.fishNumber;3 var yz = GameManager.Instance.gameConfig.fishArrayConfigs.Find(a => a.fishArrayNumber == cfg.fishNumber); foreach (var item in GameManager.Instance.gameConfig.fishArrayConfigs) { if (item.arrayNumber==cfg.fishNumber) { Debug.Log(item); } } FishTypeConfig fishType = null; foreach (var item in M_GameConfig.fishTypeConfigs) { if (item.fishNumber == yz.fishNumber) { fishType = item; } } // 3. 出生点 Vector3 pos = new Vector3( 9999, 9999, 0 ); var prefab = FishResourcesData.GetFishPrefab(fishType.fishNumber); int pathId = 0; int count = 0; List list = new List(); switch (yz.arrayNumber.Substring(0, 3)) { case "700": list = FishYZ.dicfishYZ[yz.arrayNumber]; StartCoroutine( IeShanXing(cfg, yz, pos, prefab, list)); break; case "701": list = FishYZ.dicfishYZ[yz.arrayNumber]; foreach (var item in list) Quan(cfg, yz, pos, prefab, item, 10); break; case "702": list = FishYZ.dicfishYZ[yz.arrayNumber]; foreach (var item in list) { StartCoroutine(YZ7007(cfg, yz, pos, prefab, item)); } break; case "7007": list = FishYZ.dicfishYZ[yz.arrayNumber]; foreach (var item in list) { StartCoroutine(YZ7007(cfg, yz, pos, prefab, item)); } break; default: break; } //// 4. 实例化 //GameObject fish = Instantiate(prefab, pos, Quaternion.identity, fishRoot); //var v = fish.GetComponent(); } } IEnumerator IeShanXing(RoomFishDetailConfig cfg, FishArrayConfig yz, Vector3 pos, GameObject prefab, List list) { foreach (var item in list) { ShanXing(cfg, yz, pos, prefab, item, 10); yield return new WaitForSeconds(0.8f); } } private void ShanXing(RoomFishDetailConfig cfg, FishArrayConfig yz, Vector3 pos, GameObject prefab, int pathId,int count) { for (int i = 1; i <= 16; i++) { // 4. 实例化 GameObject fish = Instantiate(prefab, pos, Quaternion.Euler((i * 5 * (i % 2 == 0 ? -1 : 1)) * Vector3.forward), fishRoot); var v = fish.GetComponent(); v.monsterData.fishTypeConfig = FishDatas[yz.fishNumber]; v.hashCode = v.gameObject.GetHashCode().ToString(); fishDatas_hashCodekey[v.hashCode] = v; //int pathId = list[Random.Range(0, list.Count)]; v.Init(MonsterMoveLine.dic_BezierCurveDatas["鱼阵" + (pathId)],cfg.times, true, yz.arrayNumber); } } private void Quan(RoomFishDetailConfig cfg, FishArrayConfig yz, Vector3 pos, GameObject prefab, int pathId,int count) { for (int i = 0; i < count; i++) { // 4. 实例化 GameObject fish = Instantiate(prefab, pos, Quaternion.Euler((360 / count) * i * Vector3.forward), fishRoot); var v = fish.GetComponent(); v.monsterData.fishTypeConfig = FishDatas[yz.fishNumber]; v.hashCode = v.gameObject.GetHashCode().ToString(); fishDatas_hashCodekey[v.hashCode] = v; //int pathId = list[Random.Range(0, list.Count)]; v.Init(MonsterMoveLine.dic_BezierCurveDatas["鱼阵" + (pathId)], cfg.times, true, yz.arrayNumber); } } //顺序出 IEnumerator YZ7007(RoomFishDetailConfig cfg, FishArrayConfig yz, Vector3 pos, GameObject prefab, int pathId) { List list = FishDatas[yz.fishNumber].pathList; for (int i = 0; i < 8; i++) { yield return new WaitForSeconds(1f); //// 4. 实例化 //GameObject fish = Instantiate(prefab, pos, Quaternion.Euler((360 / 20) * i * Vector3.forward), fishRoot); //var v = fish.GetComponent(); //v.monsterData.roomFishDetailConfig = cfg; //v.hashCode = v.gameObject.GetHashCode().ToString(); //fishDatas_hashCodekey[v.hashCode] = v; ////int pathId = list[Random.Range(0, list.Count)]; //v.Init(MonsterMoveLine.dic_BezierCurveDatas["鱼阵" + (pathId + 1)], 15, true, cfg.fishNumber); //v.fishType = (FishTypeEnum)FishDatas[yz.fishNumber].fishType; // 4. 实例化 GameObject fish = Instantiate(prefab, pos, Quaternion.identity, fishRoot); var v = fish.GetComponent(); // 5. 初始化路径 if (v == null) { v = fish.AddComponent(); } v.monsterData.fishTypeConfig = FishDatas[yz.fishNumber]; v.hashCode = v.gameObject.GetHashCode().ToString(); fishDatas_hashCodekey[v.hashCode] = v; v.Init(MonsterMoveLine.dic_BezierCurveDatas["鱼阵" + pathId], 10); } } private bool OnlyFish(RoomFishDetailConfig cfg) { // 1. 找到鱼的基础配置 FishTypeConfig fishType = M_GameConfig.fishTypeConfigs .Find(f => f.fishNumber == cfg.fishNumber); if (fishType == null) { Debug.LogError($"找不到鱼配置:{cfg.fishNumber}"); return false; } // 2. 加载 Prefab(imageUrl 你可以换成自己的字段) //var prefab = await Addressables.LoadAssetAsync(fishType.imageUrl).Task; var prefab = FishResourcesData.GetFishPrefab(fishType.fishNumber); // 3. 出生点 Vector3 pos = new Vector3( 9999, 9999, 0 ); // 4. 实例化 GameObject fish = Instantiate(prefab, pos, Quaternion.identity, fishRoot); var v = fish.GetComponent(); // 5. 初始化路径 if (v == null) { v = fish.AddComponent(); } v.monsterData.fishTypeConfig = FishDatas[cfg.fishNumber]; v.hashCode = v.gameObject.GetHashCode().ToString(); fishDatas_hashCodekey[v.hashCode] = v; var list = FishDatas[cfg.fishNumber].pathList; int pathId = list[Random.Range(0, list.Count)]; v.Init(MonsterMoveLine.dic_BezierCurveDatas["曲线" + pathId], 10); //v.monsterData.moveLine.Init(MonsterMoveLine.dic_BezierCurveDatas["曲线" + Random.Range(1, 4).ToString()], 10); ////初始化 //GameObject obj = Instantiate(prefab, Vector3.one * 999, Quaternion.identity); //var v = obj.GetComponent(); ////v.dic_AnimKeyAnimName.Add(CharacterAnimationType.move, "stand2"); //v.monsterData.moveLine.Init(MonsterMoveLine.dic_BezierCurveDatas["曲线" + Random.Range(1, 4).ToString()], 10); Debug.Log($"生成鱼:{fishType.fishName}"); return true; } public void CreateFishArray(string arrayNumber) { var array = M_GameConfig.fishArrayConfigs .Find(a => a.fishArrayNumber == arrayNumber); if (array == null) { Debug.LogError($"找不到鱼阵:{arrayNumber}"); return; } // 未来扩展:阵型、路径、Boss、普通鱼 //// array.ty.fishNumber // // 2. 加载 Prefab(imageUrl 你可以换成自己的字段) // //var prefab = await Addressables.LoadAssetAsync(fishType.imageUrl).Task; // var prefab = FishResourcesData.CreateFishPrefab(fishType.fishNumber); // // 3. 随机出生点 // Vector3 pos = new Vector3( // Random.Range(-8f, 8f), // Random.Range(-5f, 5f), // 0 // ); // // 4. 实例化 // GameObject fish = Instantiate(prefab, pos, Quaternion.identity, fishRoot); // var v = fish.GetComponent(); // // 5. 初始化路径 // if (v == null) // { // v = fish.AddComponent(); // } // v.monsterData.roomFishDetailConfig = cfg; // v.hashCode = v.gameObject.GetHashCode().ToString(); // fishDatas_hashCodekey[v.hashCode] = v; // var list = FishDatas[cfg.fishNumber].pathList; // int pathId = list[Random.Range(0, list.Count)]; // v.monsterData.moveLine.Init(MonsterMoveLine.dic_BezierCurveDatas["曲线" + pathId], 10); // v.fishType = (FishTypeEnum)FishDatas[cfg.fishNumber].fishType; // //v.monsterData.moveLine.Init(MonsterMoveLine.dic_BezierCurveDatas["曲线" + Random.Range(1, 4).ToString()], 10); // ////初始化 // //GameObject obj = Instantiate(prefab, Vector3.one * 999, Quaternion.identity); // //var v = obj.GetComponent(); // ////v.dic_AnimKeyAnimName.Add(CharacterAnimationType.move, "stand2"); // //v.monsterData.moveLine.Init(MonsterMoveLine.dic_BezierCurveDatas["曲线" + Random.Range(1, 4).ToString()], 10); // Debug.Log($"生成鱼:{fishType.fishName}"); } public void EnterRoom(GameTypeEnum gameType) { InitSpawnSystem(gameType); } public void ExitRoom() { CloseSpawnSystem(); } // ============================================================ // 1. 生成单条鱼 // ============================================================ public async void CreateSingleFish(string fishNumber, int pathId) { switch ((GameTypeEnum)GameManager.Instance.gameData.currGameType) { case GameTypeEnum.风雷之渊: break; case GameTypeEnum.太古仙墟: break; case GameTypeEnum.中国象棋: break; case GameTypeEnum.星际迷航: break; case GameTypeEnum.黑神话悟空: break; default: break; } } public void DesFish(string msg) { var killFish = JsonConvert.DeserializeObject>(msg).arguments[0]; Debug.Log("时间123:" + (DateTimeOffset.Now.ToUnixTimeSeconds() - killFish.timespan) + "秒"); if (fishDatas_hashCodekey.ContainsKey(killFish.fishId)) { var monster = fishDatas_hashCodekey[killFish.fishId]; Instantiate(monster.effect_Die == null ? dieFXPrefab : monster.effect_Die, monster.transform.position, Quaternion.identity, transform.parent); Destroy(monster.gameObject); fishDatas_hashCodekey.Remove(killFish.fishId); //GameManager.Instance.gameData.roomJoinNotice.gold += killFish.gold; var list = UIManager.Instance.Get(UIPanel.MainGamePanelXJMH).list_Sits; foreach (var item in list) { if (item.user!=null) { if (item.user.id==killFish.userId) { item.goldNum +=killFish.gold; } } } } } }