HHWK0.1
This commit is contained in:
@@ -197,9 +197,13 @@ public class MonsterContral : MonoBehaviour
|
||||
fishenum = (FishTypeEnum)monsterData.fishTypeConfig.fishType;
|
||||
|
||||
// 路径结束后自动销毁
|
||||
Pool.Instance.Return(gameObject, time);
|
||||
StartCoroutine(yanchi(gameObject,time));
|
||||
}
|
||||
public IEnumerator yanchi(GameObject obj,float time)
|
||||
{
|
||||
yield return new WaitForSeconds(time);
|
||||
Pool.Instance.Return(gameObject);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// 状态机
|
||||
// ================================================================
|
||||
@@ -317,7 +321,7 @@ public class MonsterContral : MonoBehaviour
|
||||
|
||||
transform.position = next;
|
||||
}
|
||||
|
||||
public bool isRotate=true;
|
||||
/// <summary>
|
||||
/// 根据 forwordXYZ 字段将物体朝向目标点方向。
|
||||
/// 为空时 2D 鱼用 up,3D 鱼用 forward。
|
||||
@@ -325,6 +329,10 @@ public class MonsterContral : MonoBehaviour
|
||||
/// <param name="nextPos">下一帧目标位置</param>
|
||||
private void ApplyFacingDirection(Vector2 nextPos)
|
||||
{
|
||||
if (!isRotate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Vector2 toNext = nextPos - (Vector2)transform.position;
|
||||
Vector2 fromNext = (Vector2)transform.position - nextPos;
|
||||
|
||||
@@ -391,6 +399,7 @@ public class MonsterContral : MonoBehaviour
|
||||
{
|
||||
AudioManager.Instance.PlayerFX(res.dieAudio[0]);
|
||||
}
|
||||
CreateFishManager.Instance.DieFishList(guid);
|
||||
Pool.Instance.Return(gameObject);
|
||||
//Destroy(gameObject);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public class MonsterControl_BossBase : MonsterContral
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
isRotate = false;
|
||||
ZhuCam = GameManager.Instance.ZhuCam;
|
||||
|
||||
}
|
||||
@@ -133,9 +134,11 @@ public class MonsterControl_BossBase : MonsterContral
|
||||
|
||||
}
|
||||
}
|
||||
public bool isDieFish=false;
|
||||
public override void DieFish(RoomKillNotice obj = null)
|
||||
{
|
||||
|
||||
isDieFish = true;
|
||||
CreateFishManager.Instance.DieFishList(guid);
|
||||
GameManager.Instance.cameraShake.ShakePresets.Explosion2D(3f, 4f, 1f);
|
||||
if (obj != null)
|
||||
{
|
||||
@@ -151,7 +154,6 @@ public class MonsterControl_BossBase : MonsterContral
|
||||
int index = Random.Range(0, v.Count);
|
||||
AudioManager.Instance.PlayerFX(v[index]);
|
||||
}
|
||||
Pool.Instance.Return(gameObject);
|
||||
|
||||
|
||||
}
|
||||
@@ -175,24 +177,24 @@ public class MonsterControl_BossBase : MonsterContral
|
||||
case GameType.defaultPanel:
|
||||
break;
|
||||
case GameType.FLZY:
|
||||
{
|
||||
AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>("Assets/Art/XJMH/pw/pw_sprite/handbook/" + bossName + ".png");
|
||||
await handle.Task;
|
||||
Sprite sprite = handle.Result;
|
||||
CreateFishManager.Instance. currGameType.subUIManager.ShowBoardBoss(sprite, bossName);
|
||||
//{
|
||||
// AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>("Assets/Art/XJMH/pw/pw_sprite/handbook/" + bossName + ".png");
|
||||
// await handle.Task;
|
||||
// Sprite sprite = handle.Result;
|
||||
// CreateFishManager.Instance. currGameType.subUIManager.ShowBoardBoss(sprite, bossName);
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
break;
|
||||
case GameType.TGXX:
|
||||
//还没有写呢
|
||||
{
|
||||
AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>("Assets/Art/XJMH/pw/pw_sprite/handbook/" + bossName + ".png");
|
||||
await handle.Task;
|
||||
Sprite sprite = handle.Result;
|
||||
CreateFishManager.Instance.currGameType.subUIManager.ShowBoardBoss(sprite, bossName);
|
||||
//{
|
||||
// AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>("Assets/Art/XJMH/pw/pw_sprite/handbook/" + bossName + ".png");
|
||||
// await handle.Task;
|
||||
// Sprite sprite = handle.Result;
|
||||
// CreateFishManager.Instance.currGameType.subUIManager.ShowBoardBoss(sprite, bossName);
|
||||
|
||||
}
|
||||
//}
|
||||
break;
|
||||
case GameType.ZGXQ:
|
||||
|
||||
@@ -207,13 +209,13 @@ public class MonsterControl_BossBase : MonsterContral
|
||||
}
|
||||
break;
|
||||
case GameType.HHWK:
|
||||
{
|
||||
AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>("Assets/Art/XJMH/pw/pw_sprite/handbook/" + bossName + ".png");
|
||||
await handle.Task;
|
||||
Sprite sprite = handle.Result;
|
||||
CreateFishManager.Instance.currGameType.subUIManager.ShowBoardBoss(sprite, bossName);
|
||||
//{
|
||||
// AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>("Assets/Art/XJMH/pw/pw_sprite/handbook/" + bossName + ".png");
|
||||
// await handle.Task;
|
||||
// Sprite sprite = handle.Result;
|
||||
// CreateFishManager.Instance.currGameType.subUIManager.ShowBoardBoss(sprite, bossName);
|
||||
|
||||
}
|
||||
//}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -224,16 +226,19 @@ public class MonsterControl_BossBase : MonsterContral
|
||||
public override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
|
||||
if (isDieFish)
|
||||
{
|
||||
GameManager.Instance.StartCoroutine(yanchidie());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public float dieTime = 3f;
|
||||
|
||||
public Vector3 v3;
|
||||
IEnumerator yanchidie()
|
||||
{
|
||||
yield return new WaitForSeconds(dieTime);
|
||||
tMP_CurrBossScore.transform.parent.DOMove(CreateFishManager.Instance.currGameType.currSitData.tMP_GoldNum.transform.position, 0.5f).OnComplete(() =>
|
||||
tMP_CurrBossScore.transform.parent.DOMove(v3, 0.5f).OnComplete(() =>
|
||||
{
|
||||
|
||||
|
||||
|
||||
@@ -23,10 +23,14 @@ public class MonsterMoveLine
|
||||
public Vector2 end;
|
||||
}
|
||||
|
||||
public static async void LoadBezier()
|
||||
public static async Task LoadBezier()
|
||||
{
|
||||
await LoadBezierTxtAsync("MoveLine");
|
||||
}
|
||||
public static async Task UnLoadBezier()
|
||||
{
|
||||
await UnLoadBezierTxtAsync("MoveLine");
|
||||
}
|
||||
|
||||
public static async Task LoadSingleBezierTxtAsync(string path)
|
||||
{
|
||||
@@ -65,7 +69,9 @@ public class MonsterMoveLine
|
||||
List<string> keys = new List<string>();
|
||||
keys.Add(path);
|
||||
keys.Add(GameManager.Instance.gameData.currGameType.ToString());
|
||||
AsyncOperationHandle<IList<TextAsset>> handles = Addressables.LoadAssetsAsync<TextAsset>(keys, null, Addressables.MergeMode.Intersection);
|
||||
|
||||
AsyncOperationHandle<IList<TextAsset>> handles = Addressables.LoadAssetsAsync<TextAsset>(
|
||||
keys, null, Addressables.MergeMode.Intersection);
|
||||
await handles.Task;
|
||||
|
||||
foreach (var text in handles.Result)
|
||||
@@ -93,13 +99,51 @@ public class MonsterMoveLine
|
||||
curve.controlPoints.Add(points[i]);
|
||||
|
||||
curves.Add(curve);
|
||||
dic_BezierCurveDatas.Add(curve.name, curve);
|
||||
|
||||
// 改成索引器赋值,避免重复 key 报错
|
||||
dic_BezierCurveDatas[curve.name] = curve;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log("曲线读取完成共" + dic_BezierCurveDatas.Count + "条");
|
||||
}
|
||||
|
||||
public static async Task UnLoadBezierTxtAsync(string path)
|
||||
{
|
||||
List<string> keys = new List<string>();
|
||||
keys.Add(path);
|
||||
keys.Add(GameManager.Instance.gameData.currGameType.ToString());
|
||||
|
||||
AsyncOperationHandle<IList<TextAsset>> handles = Addressables.LoadAssetsAsync<TextAsset>(keys, null, Addressables.MergeMode.Intersection);
|
||||
await handles.Task;
|
||||
|
||||
foreach (var text in handles.Result)
|
||||
{
|
||||
var lines = text.text.Split('\n');
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line)) continue;
|
||||
|
||||
var parts = line.Split(';');
|
||||
string curveName = parts[0];
|
||||
|
||||
// 如果字典里有该曲线,移除
|
||||
if (dic_BezierCurveDatas.ContainsKey(curveName))
|
||||
{
|
||||
dic_BezierCurveDatas.Remove(curveName);
|
||||
}
|
||||
|
||||
// 从列表中移除对应曲线
|
||||
curves.RemoveAll(c => c.name == curveName);
|
||||
}
|
||||
}
|
||||
|
||||
// 释放 Addressables 资源
|
||||
Addressables.Release(handles);
|
||||
|
||||
Debug.Log("曲线卸载完成,剩余曲线数量:" + dic_BezierCurveDatas.Count);
|
||||
}
|
||||
|
||||
private static Vector2 ParseVector(string s)
|
||||
{
|
||||
var xy = s.Split(',');
|
||||
|
||||
@@ -176,7 +176,7 @@ public class BullitMove : MonoBehaviour
|
||||
var v2 = GameManager.Instance.gameData.currRoomData;
|
||||
if (true)
|
||||
{
|
||||
WebSocketSendList.KillFish(v2.roomId, userid,monster.monsterData.fishTypeConfig.fishNumber, monster.guid, GameManager.Instance.gameData.roomJoinNotice.cannonMultiple);
|
||||
WebSocketSendList.KillFish(v2.roomId, userid,monster.monsterData.fishTypeConfig.fishNumber, monster.guid, (int)CreateFishManager.Instance.currGameType.currSitData.consumeGoldNum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ 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.APIResponses.GameConfig_SubClass;
|
||||
using Assets.MyGame.Scripts.Net.WebResponses;
|
||||
using cfg;
|
||||
using Newtonsoft.Json;
|
||||
@@ -22,11 +23,11 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TMPro;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using UnityEngine;
|
||||
using static UnityEditor.FilePathAttribute;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
/// <summary>
|
||||
@@ -58,7 +59,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// <summary>fishArrayNumber → FishArrayConfig(鱼阵配置缓存)</summary>
|
||||
private Dictionary<string, FishArrayConfig> fishArrayConfigDic;
|
||||
|
||||
/// <summary>fishNumber → FishTypeConfig(与 fishDatas 相同来源,供内部高频使用)</summary>
|
||||
/// <summary>fishNumber → FishTypeConfig(与 fishDatas 相同来源,供内部使用)</summary>
|
||||
private Dictionary<string, FishTypeConfig> fishTypeConfigDic;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -66,10 +67,10 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/// <summary>全部存活鱼(包含 Boss / 小鱼 / 黄金鱼)</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey = new Dictionary<string, MonsterContral>();
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey = new Dictionary<string, MonsterContral>();
|
||||
|
||||
/// <summary>Boss 鱼</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_Boss = new Dictionary<string, MonsterContral>();
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_Boss = new Dictionary<string, MonsterContral>();
|
||||
|
||||
/// <summary>普通 / 黄金 / 特殊鱼(非 Boss)</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_Small = new Dictionary<string, MonsterContral>();
|
||||
@@ -96,6 +97,8 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
/// <summary>鱼的父节点(保持场景层级整洁)</summary>
|
||||
public Transform fishRoot;
|
||||
/// <summary>鱼的父节点(保持场景层级整洁)</summary>
|
||||
public Transform poolRoot;
|
||||
|
||||
/// <summary>当前房间可生成鱼列表(与 NativeArray 下标对齐)</summary>
|
||||
public List<RoomFishDetailConfig> spawnList;
|
||||
@@ -110,28 +113,32 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// <summary>arrayNumber → 该阵型所有可用生成配置</summary>
|
||||
private Dictionary<string, List<RoomFishDetailConfig>> yz_FishConfig_Line;
|
||||
/// <summary>列表下标 → arrayNumber(用于随机取阵型)</summary>
|
||||
private Dictionary<int, string> yz_FishConfig_Line_Dic;
|
||||
private Dictionary<int, string> yz_FishConfig_Line_Dic;
|
||||
/// <summary>arrayNumber → 列表下标(反向索引)</summary>
|
||||
private Dictionary<string, int> yz_FishConfig_Line_Dic1;
|
||||
private Dictionary<string, int> yz_FishConfig_Line_Dic1;
|
||||
/// <summary>二维列表,与字典保持同步(供随机无重复取阵型用)</summary>
|
||||
private List<List<RoomFishDetailConfig>> yz_FishConfig_Line_List;
|
||||
private List<List<RoomFishDetailConfig>> yz_FishConfig_Line_List;
|
||||
|
||||
// ------ Job System NativeArray ------
|
||||
private NativeArray<float> timers; // 每条鱼的累计计时
|
||||
private NativeArray<float> frequencies; // 每条鱼的生成间隔
|
||||
private NativeArray<int> shouldSpawn; // 1=本帧应尝试生成,0=冷却中
|
||||
private NativeArray<int> shouldSpawn; // 1=本帧应尝试生成,0=冷却中
|
||||
|
||||
// ------ 各类计时器 ------
|
||||
private float bossTimer = 1f; // Boss 刷新倒计时(秒)
|
||||
private float yzTimer; // 鱼阵刷新倒计时(秒)
|
||||
private float ptTimer = 3f; // 普通鱼批量启用倒计时(秒)
|
||||
private int yzCount; // 本轮同时激活阵型数量
|
||||
private int ptCount; // 本轮同时启用普通鱼数量
|
||||
private int yz_LineCount = 0; // 场景内鱼阵路线总数
|
||||
private RoomFishProbabilityConfig bossCreateData; // Boss 创建数据
|
||||
private float bossTimer = 999f; // Boss 刷新倒计时(秒)
|
||||
private RoomFishProbabilityConfig yzCreateData; // 鱼阵创建数据
|
||||
private float yzTimer=999f; // 鱼阵刷新倒计时(秒)
|
||||
private RoomFishProbabilityConfig ptCreateData; // 普通鱼创建数据
|
||||
private float ptTimer = 999f; // 普通鱼批量启用倒计时(秒)
|
||||
private int yzCount; // 本轮同时激活阵型数量
|
||||
private int ptCount; // 本轮同时启用普通鱼数量
|
||||
private int bossCount; // 本轮同时启用Boss鱼数量
|
||||
private int yz_LineCount = 0; // 场景内鱼阵路线总数
|
||||
|
||||
/// <summary>是否开启放鱼(false 时 Update 不执行生成逻辑)</summary>
|
||||
public bool fangzhu;
|
||||
|
||||
public bool isResources=false;
|
||||
// ================================================================
|
||||
// 懒加载属性
|
||||
// ================================================================
|
||||
@@ -180,17 +187,28 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
// 确保 FishRoot 存在
|
||||
if (fishRoot == null)
|
||||
fishRoot = new GameObject("FishRoot").transform;
|
||||
|
||||
if (poolRoot == null)
|
||||
fishRoot = new GameObject("poolRoot").transform;
|
||||
// 监听服务器下发的创鱼事件
|
||||
EventCenter.Instance.AddEventListener<SyncGameData>(
|
||||
ConstEventString.SyncGameData_CreateFish, CreateFish);
|
||||
|
||||
// 随机初始化计时器,避免所有类型同帧触发
|
||||
yzTimer = Random.Range(2f, 6f);
|
||||
yzCount = Random.Range(2, 5);
|
||||
ptCount = Random.Range(1, 4);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public void InitChuYu()
|
||||
{
|
||||
// 随机初始化计时器,避免所有类型同帧触发
|
||||
yzCount = Random.Range(yzCreateData.countRange[0], yzCreateData.countRange[1]);
|
||||
ptCount = Random.Range(ptCreateData.countRange[0], ptCreateData.countRange[1]);
|
||||
bossCount = Random.Range(ptCreateData.countRange[0], ptCreateData.countRange[1]);
|
||||
yzTimer = 0.5f ;
|
||||
ptTimer =0.5f ;
|
||||
bossTimer = 5f;
|
||||
//yzTimer = Random.Range(yzCreateData.timeRange[0], yzCreateData.timeRange[1]);
|
||||
//ptTimer = Random.Range(ptCreateData.timeRange[0], ptCreateData.timeRange[1]);
|
||||
//bossTimer = Random.Range(bossCreateData.timeRange[0], bossCreateData.timeRange[1]);
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
EventCenter.Instance.RemoveEventListener<SyncGameData>(
|
||||
@@ -206,6 +224,10 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!isResources)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 未初始化 或 未开启放鱼 → 跳过
|
||||
if (spawnList == null || !fangzhu) return;
|
||||
|
||||
@@ -214,8 +236,8 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
// ---- 1. 用 Job System 并行更新所有鱼的计时器 ----
|
||||
var job = new FishSpawnTimerJob
|
||||
{
|
||||
deltaTime = dt,
|
||||
timers = timers,
|
||||
deltaTime = dt,
|
||||
timers = timers,
|
||||
frequencies = frequencies,
|
||||
shouldSpawn = shouldSpawn,
|
||||
};
|
||||
@@ -244,11 +266,17 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
bossTimer -= dt;
|
||||
if (bossTimer > 0f) return;
|
||||
|
||||
bossTimer = 25f;
|
||||
|
||||
bossTimer = Random.Range(bossCreateData.timeRange[0], bossCreateData.timeRange[1]);
|
||||
|
||||
if (!fishTypeConfig.TryGetValue(FishTypeEnum.Boss鱼, out var bossList) || bossList.Count == 0)
|
||||
return;
|
||||
|
||||
//foreach (var item in bossList)
|
||||
//{
|
||||
// if (item.fishNumber == 13027.ToString())
|
||||
// {
|
||||
// item.isCreate = 2;
|
||||
// }
|
||||
//}
|
||||
bossList[Random.Range(0, bossList.Count)].isCreate = 2;
|
||||
}
|
||||
|
||||
@@ -258,8 +286,11 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
yzTimer -= dt;
|
||||
if (yzTimer > 0f) return;
|
||||
|
||||
yzTimer = Random.Range(1f, 3f);
|
||||
yzCount = Random.Range(2, 5);
|
||||
|
||||
yzCount = Random.Range(yzCreateData.countRange[0], yzCreateData.countRange[1]);
|
||||
|
||||
yzTimer = Random.Range(yzCreateData.timeRange[0], yzCreateData.timeRange[1]);
|
||||
|
||||
|
||||
int lineCount = yz_FishConfig_Line_List.Count;
|
||||
if (lineCount == 0) return;
|
||||
@@ -290,8 +321,11 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
ptTimer -= dt;
|
||||
if (ptTimer > 0f) return;
|
||||
|
||||
ptTimer = 3f;
|
||||
ptCount = Random.Range(1, 4);
|
||||
|
||||
ptCount = Random.Range(ptCreateData.countRange[0], ptCreateData.countRange[1]);
|
||||
|
||||
|
||||
ptTimer = Random.Range(ptCreateData.timeRange[0], ptCreateData.timeRange[1]);
|
||||
|
||||
if (!fishTypeConfig.TryGetValue(FishTypeEnum.普通鱼, out var normalList) || normalList.Count == 0)
|
||||
return;
|
||||
@@ -349,14 +383,14 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
var sgd = new SyncGameData
|
||||
{
|
||||
sitPos = GameManager.Instance.gameData.roomJoinNotice.position,
|
||||
sitPos = GameManager.Instance.gameData.roomJoinNotice.position,
|
||||
frameType = FrameDataType.createFish,
|
||||
time = BeijingTimeManager.Instance.CurrentTimestampMs,
|
||||
time = BeijingTimeManager.Instance.CurrentTimestampMs,
|
||||
frameData = new FrameData_CreateFish
|
||||
{
|
||||
fishNumber = fish.fishNumber,
|
||||
guid = Guid.NewGuid().ToString(),
|
||||
moveLineId = pathId.ToString()
|
||||
fishNumber = fish.fishNumber,
|
||||
guid = Guid.NewGuid().ToString(),
|
||||
moveLineId = pathId.ToString()
|
||||
}
|
||||
};
|
||||
|
||||
@@ -376,7 +410,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
FishYZ.Init();
|
||||
roomFishConfig = new Dictionary<GameTypeEnum, RoomFishConfig>();
|
||||
createDic = new Dictionary<GameTypeEnum, Dictionary<string, RoomFishDetailConfig>>();
|
||||
createDic = new Dictionary<GameTypeEnum, Dictionary<string, RoomFishDetailConfig>>();
|
||||
|
||||
var list = GameManager.Instance.gameConfig.roomFishConfigs;
|
||||
if (list == null || list.Count == 0) return;
|
||||
@@ -419,18 +453,18 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// <summary>
|
||||
/// 进入房间时初始化生成系统:加载当前房间配置、分配 NativeArray。
|
||||
/// </summary>
|
||||
public void InitSpawnSystem(GameTypeEnum gameType)
|
||||
public async void InitSpawnSystem(GameTypeEnum gameType)
|
||||
{
|
||||
EnsureInit();
|
||||
|
||||
// 初始化分类容器
|
||||
fishTypeConfig = new Dictionary<FishTypeEnum, List<RoomFishDetailConfig>>();
|
||||
yz_FishConfig_Line = new Dictionary<string, List<RoomFishDetailConfig>>();
|
||||
fishTypeConfig = new Dictionary<FishTypeEnum, List<RoomFishDetailConfig>>();
|
||||
yz_FishConfig_Line = new Dictionary<string, List<RoomFishDetailConfig>>();
|
||||
yz_FishConfig_Line_Dic = new Dictionary<int, string>();
|
||||
yz_FishConfig_Line_Dic1= new Dictionary<string, int>();
|
||||
yz_FishConfig_Line_List= new List<List<RoomFishDetailConfig>>();
|
||||
spawnList = new List<RoomFishDetailConfig>();
|
||||
spawnDic = new Dictionary<string, RoomFishDetailConfig>();
|
||||
yz_FishConfig_Line_Dic1 = new Dictionary<string, int>();
|
||||
yz_FishConfig_Line_List = new List<List<RoomFishDetailConfig>>();
|
||||
spawnList = new List<RoomFishDetailConfig>();
|
||||
spawnDic = new Dictionary<string, RoomFishDetailConfig>();
|
||||
|
||||
var config = RoomFishConfig[gameType];
|
||||
|
||||
@@ -459,10 +493,42 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
int currRoomLevel = GameManager.Instance.gameData.currRoomData.roomLevel;
|
||||
if (config.roomFishLevelList != null)
|
||||
{
|
||||
foreach (var item in config.roomFishProbabilityList)
|
||||
{
|
||||
if (item.roomLevel != currRoomLevel) continue;
|
||||
switch (item.type)
|
||||
{
|
||||
case 1:
|
||||
switch ((FishTypeEnum)item.fishType)
|
||||
{
|
||||
case FishTypeEnum.普通鱼:
|
||||
ptCreateData = item;
|
||||
break;
|
||||
case FishTypeEnum.Boss鱼:
|
||||
bossCreateData = item;
|
||||
|
||||
break;
|
||||
case FishTypeEnum.黄金鱼:
|
||||
break;
|
||||
case FishTypeEnum.特殊鱼:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
//yzTimer=item.
|
||||
yzCreateData = item;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach (var item in config.roomFishLevelList)
|
||||
{
|
||||
if (item.roomLevel != currRoomLevel) continue;
|
||||
|
||||
|
||||
if (item.type == 2)
|
||||
{
|
||||
spawnDic[item.fishNumber] = item;
|
||||
@@ -482,13 +548,13 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
// ---- 分配 Job System NativeArray ----
|
||||
int count = spawnList.Count;
|
||||
DisposeNativeArrays(); // 防止重复进房泄漏
|
||||
timers = new NativeArray<float>(count, Allocator.Persistent);
|
||||
timers = new NativeArray<float>(count, Allocator.Persistent);
|
||||
frequencies = new NativeArray<float>(count, Allocator.Persistent);
|
||||
shouldSpawn = new NativeArray<int>(count, Allocator.Persistent);
|
||||
shouldSpawn = new NativeArray<int>(count, Allocator.Persistent);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
timers[i] = 0f;
|
||||
timers[i] = 0f;
|
||||
frequencies[i] = spawnList[i].fishFrequency;
|
||||
shouldSpawn[i] = 1; // 初始全部允许生成
|
||||
}
|
||||
@@ -500,6 +566,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
if (key.StartsWith("鱼阵"))
|
||||
yz_LineCount++;
|
||||
}
|
||||
InitChuYu();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -529,7 +596,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
yz_FishConfig_Line_List.Add(new List<RoomFishDetailConfig>());
|
||||
|
||||
int newIdx = yz_FishConfig_Line_List.Count - 1;
|
||||
yz_FishConfig_Line_Dic[newIdx] = yz.arrayNumber;
|
||||
yz_FishConfig_Line_Dic[newIdx] = yz.arrayNumber;
|
||||
yz_FishConfig_Line_Dic1[yz.arrayNumber] = newIdx;
|
||||
}
|
||||
|
||||
@@ -540,23 +607,35 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// <summary>
|
||||
/// 关闭生成系统:清理列表,销毁场景内所有鱼对象。
|
||||
/// </summary>
|
||||
public void CloseSpawnSystem()
|
||||
public async void CloseSpawnSystem()
|
||||
{
|
||||
|
||||
//await Task.Delay(2000);
|
||||
spawnList = null;
|
||||
spawnDic = null;
|
||||
yz_FishConfig_Line_Dic = null;
|
||||
yz_FishConfig_Line = null;
|
||||
yz_FishConfig_Line_Dic1 = null;
|
||||
if (fishRoot == null) return;
|
||||
foreach (var item in fishDatas_hashCodekey)
|
||||
{
|
||||
if (item.Value.gameObject!=null)
|
||||
{
|
||||
Destroy(item.Value.gameObject);
|
||||
|
||||
for (int i = fishRoot.childCount - 1; i >= 0; i--)
|
||||
Destroy(fishRoot.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
fishDatas_hashCodekey.Clear();
|
||||
fishDatas_hashCodekey_Boss.Clear();
|
||||
fishDatas_hashCodekey_Small.Clear();
|
||||
//for (int i = fishDatas_hashCodekey.childCount - 1; i >= 0; i--)
|
||||
// Destroy(fishRoot.GetChild(i).gameObject);
|
||||
}
|
||||
|
||||
/// <summary>释放 NativeArray(避免 Unity 内存泄漏警告)。</summary>
|
||||
private void DisposeNativeArrays()
|
||||
{
|
||||
if (timers.IsCreated) timers.Dispose();
|
||||
if (timers.IsCreated) timers.Dispose();
|
||||
if (frequencies.IsCreated) frequencies.Dispose();
|
||||
if (shouldSpawn.IsCreated) shouldSpawn.Dispose();
|
||||
}
|
||||
@@ -604,16 +683,27 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
// 网络回调:创建鱼
|
||||
// ================================================================
|
||||
|
||||
///// <summary>
|
||||
///// 收到服务器 SyncGameData 创鱼事件,反序列化并执行实例化。
|
||||
///// </summary>
|
||||
//public void CreateFish(SyncGameData syncGameData)
|
||||
//{
|
||||
// var rotateData = JsonConvert.DeserializeObject<FrameData_CreateFish>(
|
||||
// syncGameData.frameData.ToString());
|
||||
// SpawnFishMainThread(rotateData, syncGameData.time);
|
||||
//}
|
||||
/// <summary>
|
||||
/// 收到服务器 SyncGameData 创鱼事件,反序列化并执行实例化。
|
||||
/// AI优化过的
|
||||
/// </summary>
|
||||
/// <param name="syncGameData"></param>
|
||||
public void CreateFish(SyncGameData syncGameData)
|
||||
{
|
||||
var rotateData = JsonConvert.DeserializeObject<FrameData_CreateFish>(
|
||||
syncGameData.frameData.ToString());
|
||||
SpawnFishMainThread(rotateData, syncGameData.time);
|
||||
var rotateData = FrameDataParser.Parse<FrameData_CreateFish>(syncGameData.frameData);
|
||||
if (rotateData != null)
|
||||
SpawnFishMainThread(rotateData, syncGameData.time);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 主线程实例化鱼对象(单体鱼 / 鱼阵分发)。
|
||||
/// </summary>
|
||||
@@ -655,19 +745,30 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
//var prefab = FishResourcesData.GetFishPrefab(int.Parse(fishType.fishNumber));
|
||||
//var fish = Instantiate(prefab, new Vector3(9999, 9999, 0), prefab.transform.rotation, fishRoot);
|
||||
var fish = Pool.Instance.Get(int.Parse(createFishData.fishNumber), new Vector3(9999, 9999, 0), Quaternion.identity,fishRoot);
|
||||
try
|
||||
{
|
||||
var fish = Pool.Instance.Get(int.Parse(createFishData.fishNumber), new Vector3(9999, 9999, 0), Quaternion.identity, fishRoot);
|
||||
var mc = fish.GetComponent<MonsterContral>() ?? fish.AddComponent<MonsterContral>();
|
||||
mc.monsterData.fishTypeConfig = FishDatas[createFishData.fishNumber];
|
||||
mc.guid = createFishData.guid;
|
||||
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
|
||||
mc.fishenum=(FishTypeEnum) fishType.fishType;
|
||||
// 按鱼类型放入对应字典
|
||||
RegisterFishInstance(mc, fishType.fishType);
|
||||
|
||||
var mc = fish.GetComponent<MonsterContral>() ?? fish.AddComponent<MonsterContral>();
|
||||
mc.monsterData.fishTypeConfig = FishDatas[createFishData.fishNumber];
|
||||
mc.guid = createFishData.guid;
|
||||
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
|
||||
mc.Init(createFishData.moveLineId, spawnDic[createFishData.fishNumber].times);
|
||||
|
||||
// 按鱼类型放入对应字典
|
||||
RegisterFishInstance(mc, fishType.fishType);
|
||||
Debug.Log($"[CreateFishManager] 生成鱼:{fishType.fishName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
mc.Init(createFishData.moveLineId, spawnDic[createFishData.fishNumber].times);
|
||||
Debug.LogError(createFishData.fishNumber);
|
||||
Debug.LogError(ex.Message);
|
||||
}
|
||||
|
||||
|
||||
Debug.Log($"[CreateFishManager] 生成鱼:{fishType.fishName}");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -707,8 +808,8 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
return;
|
||||
}
|
||||
|
||||
var prefab = FishResourcesData.GetFishPrefab(int.Parse(fishType.fishNumber));
|
||||
var pos = new Vector3(9999, 9999, 0);
|
||||
var prefab = FishResourcesData.GetFishPrefab(int.Parse(fishType.fishNumber));
|
||||
var pos = new Vector3(9999, 9999, 0);
|
||||
|
||||
if (!FishYZ.dicfishYZ.TryGetValue(yz.arrayNumber, out var pathList) || pathList.Count == 0)
|
||||
{
|
||||
@@ -761,6 +862,10 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
{
|
||||
foreach (int pathId in pathList)
|
||||
{
|
||||
if (!isResources)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
ShanXing(createFishData, yz, pos, prefab, pathId, count, time);
|
||||
yield return new WaitForSeconds(0.8f);
|
||||
}
|
||||
@@ -777,19 +882,19 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
for (int i = 1; i <= 16; i++)
|
||||
{
|
||||
// 交替正负角度,形成扇形分布
|
||||
float angle = i * 5f * (i % 2 == 0 ? -1f : 1f);
|
||||
float angle = i * 5f * (i % 2 == 0 ? -1f : 1f);
|
||||
var rotation = Quaternion.Euler(
|
||||
prefab.transform.eulerAngles + Vector3.forward * angle);
|
||||
|
||||
//var fish = Instantiate(prefab, pos, rotation, fishRoot);
|
||||
var fish = Pool.Instance.Get(int.Parse(yz.fishNumber), pos, rotation, fishRoot);
|
||||
var mc = fish.GetComponent<MonsterContral>();
|
||||
var mc = fish.GetComponent<MonsterContral>();
|
||||
|
||||
mc.monsterData.fishTypeConfig = FishDatas[yz.fishNumber];
|
||||
mc.guid = createFishData.guid + i;
|
||||
mc.guid = createFishData.guid + i;
|
||||
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
|
||||
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
//mc.fishenum = (FishTypeEnum)fishType.fishType;
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
fishDatas_hashCodekey_Small[mc.guid] = mc;
|
||||
|
||||
mc.Init(pathId.ToString(), cfg.times, true, yz.arrayNumber);
|
||||
@@ -807,20 +912,20 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
float angle = (360f / count) * i;
|
||||
float angle = (360f / count) * i;
|
||||
var rotation = Quaternion.Euler(
|
||||
prefab.transform.eulerAngles + Vector3.forward * angle);
|
||||
|
||||
//var fish = Instantiate(prefab, pos, rotation, fishRoot);
|
||||
var fish = Pool.Instance.Get(int.Parse(yz.fishNumber), pos, rotation, fishRoot);
|
||||
|
||||
var mc = fish.GetComponent<MonsterContral>();
|
||||
var mc = fish.GetComponent<MonsterContral>();
|
||||
|
||||
mc.monsterData.fishTypeConfig = FishDatas[yz.fishNumber];
|
||||
mc.guid = createFishData.guid + i;
|
||||
mc.guid = createFishData.guid + i;
|
||||
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
|
||||
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
fishDatas_hashCodekey_Small[mc.guid] = mc;
|
||||
|
||||
mc.Init(pathId.ToString(), cfg.times, true, yz.arrayNumber);
|
||||
@@ -837,17 +942,21 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (!isResources)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
//var fish = Instantiate(prefab, pos, prefab.transform.rotation, fishRoot);
|
||||
var fish = Pool.Instance.Get(int.Parse(yz.fishNumber), pos, Quaternion.identity, fishRoot);
|
||||
|
||||
var mc = fish.GetComponent<MonsterContral>() ?? fish.AddComponent<MonsterContral>();
|
||||
var mc = fish.GetComponent<MonsterContral>() ?? fish.AddComponent<MonsterContral>();
|
||||
|
||||
mc.monsterData.fishTypeConfig = FishDatas[yz.fishNumber];
|
||||
mc.guid = createFishData.guid + i;
|
||||
mc.guid = createFishData.guid + i;
|
||||
// 每条鱼额外减去已等待秒数,使路径起点与帧数同步
|
||||
mc.moveTime = ((BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f) - i;
|
||||
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
fishDatas_hashCodekey_Small[mc.guid] = mc;
|
||||
|
||||
mc.Init(pathId.ToString(), cfg.times, true, yz.arrayNumber);
|
||||
@@ -874,7 +983,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
count = Mathf.Min(count, max - min); // 不能超过范围
|
||||
var result = new HashSet<int>();
|
||||
var rand = new System.Random();
|
||||
var rand = new System.Random();
|
||||
|
||||
while (result.Count < count)
|
||||
result.Add(rand.Next(min, max));
|
||||
@@ -893,8 +1002,8 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
count = Mathf.Min(count, max - min);
|
||||
var keyList = keyCollection.ToList();
|
||||
var indices = new HashSet<int>();
|
||||
var rand = new System.Random();
|
||||
var result = new List<string>(count);
|
||||
var rand = new System.Random();
|
||||
var result = new List<string>(count);
|
||||
|
||||
while (indices.Count < count)
|
||||
{
|
||||
@@ -916,7 +1025,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
public List<string> SyncGameData_SendRendromDieFishID(
|
||||
int count, List<RedPacketRecord> coinNum, Vector3 v3Point)
|
||||
{
|
||||
var guids = new List<string>(count);
|
||||
var guids = new List<string>(count);
|
||||
var tempKeys = fishDatas_hashCodekey_Small.Keys.ToList();
|
||||
|
||||
// 若存活鱼不足 count,全部选取
|
||||
@@ -937,17 +1046,17 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
int posID = currGameType.currSitData.posID;
|
||||
var sgd = new SyncGameData
|
||||
{
|
||||
sitPos = posID,
|
||||
sitPos = posID,
|
||||
frameType = FrameDataType.randomDieFish,
|
||||
time = BeijingTimeManager.Instance.CurrentTimestampMs,
|
||||
time = BeijingTimeManager.Instance.CurrentTimestampMs,
|
||||
frameData = new FrameData_RandomDieFish
|
||||
{
|
||||
x = v3Point.x,
|
||||
y = v3Point.y,
|
||||
z = v3Point.z,
|
||||
guids = guids,
|
||||
x = v3Point.x,
|
||||
y = v3Point.y,
|
||||
z = v3Point.z,
|
||||
guids = guids,
|
||||
coinNum = coinNum,
|
||||
count = count
|
||||
count = count
|
||||
}
|
||||
};
|
||||
|
||||
@@ -956,13 +1065,13 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按 ID 杀死一条鱼(无特效版)。
|
||||
/// 鱼离场
|
||||
/// </summary>
|
||||
public void Id_DieFish_NotFX(string fishId)
|
||||
{
|
||||
if (!fishDatas_hashCodekey.TryGetValue(fishId, out var monster)) return;
|
||||
Pool.Instance.Return(monster.gameObject);
|
||||
|
||||
monster.DieFish();
|
||||
fishDatas_hashCodekey.Remove(fishId);
|
||||
}
|
||||
|
||||
@@ -992,18 +1101,18 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
monster.transform.position,
|
||||
UIManager.Instance.uiRoot.GetComponent<Canvas>());
|
||||
|
||||
var coinScript = award.GetComponent<CoinScript>();
|
||||
var endTra = new GameObject("CoinEndPoint").transform;
|
||||
endTra.position = v3Point;
|
||||
endTra.parent = coinScript.transform;
|
||||
var coinScript = award.GetComponent<CoinScript>();
|
||||
var endTra = new GameObject("CoinEndPoint").transform;
|
||||
endTra.position = v3Point;
|
||||
endTra.parent = coinScript.transform;
|
||||
coinScript.endPoint = endTra;
|
||||
coinScript.isBoss = true;
|
||||
coinScript.isBoss = true;
|
||||
coinScript.SetCoinCount(coinNum.Amount);
|
||||
}
|
||||
|
||||
MonsterDieList.Instance.SmallHuangYiHuang(
|
||||
monster.transform.position,
|
||||
monster.monsterData.fishTypeConfig.fishNumber, 1000);
|
||||
//MonsterDieList.Instance.SmallHuangYiHuang(
|
||||
// monster.transform.position,
|
||||
// monster.monsterData.fishTypeConfig.fishNumber, 1000);
|
||||
|
||||
monster.DieFish();
|
||||
fishDatas_hashCodekey.Remove(fishId);
|
||||
@@ -1017,7 +1126,25 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
for (int i = 0; i < ids.Count; i++)
|
||||
Id_DieFish_FX(ids[i], coinNum[i], v3Point);
|
||||
}
|
||||
public void DieFishList(string guid)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
fishDatas_hashCodekey.Remove(guid);
|
||||
if (fishDatas_hashCodekey_Boss.ContainsKey(guid))
|
||||
{
|
||||
fishDatas_hashCodekey_Boss.Remove(guid);
|
||||
|
||||
}
|
||||
if (fishDatas_hashCodekey_Small.ContainsKey(guid))
|
||||
{
|
||||
fishDatas_hashCodekey_Small.Remove(guid);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 收到服务器 WebSocket 杀鱼通知,处理金币加分、特效、音效。
|
||||
/// </summary>
|
||||
@@ -1027,7 +1154,15 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
.arguments[0];
|
||||
|
||||
Debug.Log($"[CreateFishManager] 杀鱼延迟:{DateTimeOffset.Now.ToUnixTimeSeconds() - killFish.timespan}s");
|
||||
|
||||
foreach (var item in currGameType.list_Sits)
|
||||
{
|
||||
if (item.user==killFish.userId)
|
||||
{
|
||||
item.monCotl_Lock=null;
|
||||
//item.lockFX.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fishDatas_hashCodekey.TryGetValue(killFish.fishId, out var monster)) return;
|
||||
|
||||
// 加分回调(在金币飞完后执行)
|
||||
@@ -1062,16 +1197,31 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
monster.transform.position,
|
||||
UIManager.Instance.uiRoot.GetComponent<Canvas>());
|
||||
|
||||
var coinScript = award.GetComponent<CoinScript>();
|
||||
coinScript.endPoint = currGameType.currSitData.transform;
|
||||
coinScript.isBoss = false;
|
||||
var coinScript = award.GetComponent<CoinScript>();
|
||||
foreach (var item in currGameType.list_Sits)
|
||||
{
|
||||
if (killFish.userId==item.user)
|
||||
{
|
||||
coinScript.endPoint = item.transform;
|
||||
}
|
||||
}
|
||||
|
||||
coinScript.isBoss = false;
|
||||
coinScript.SetCoinCount(killFish.gold);
|
||||
coinScript.JiaFen = onScoreAdd;
|
||||
coinScript.JiaFen = onScoreAdd;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Boss 鱼:显示浮动分数文本
|
||||
var bossCtrl = (MonsterControl_BossBase)monster;
|
||||
foreach (var item in currGameType.list_Sits)
|
||||
{
|
||||
if (killFish.userId == item.user)
|
||||
{
|
||||
bossCtrl.v3 = item.transform.position;
|
||||
}
|
||||
}
|
||||
|
||||
bossCtrl.tMP_CurrBossScore = Instantiate(
|
||||
monster.effect_DieAward != null ? monster.effect_DieAward : dieFXPrefabAwardTmp,
|
||||
currGameType.subPanelParent.parent)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Assets.MyGame.Scripts.Net.APIResponses.GameConfig_SubClass;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Assets.MyGame.Scripts.Net.API.GameConfig_SubClass
|
||||
@@ -26,6 +27,11 @@ namespace Assets.MyGame.Scripts.Net.API.GameConfig_SubClass
|
||||
/// 按房间等级出鱼配置
|
||||
/// </summary>
|
||||
public List<RoomFishLevelConfig> roomFishLevelList;
|
||||
/// <summary>
|
||||
/// 出鱼概率配置
|
||||
/// </summary>
|
||||
public List<RoomFishProbabilityConfig> roomFishProbabilityList= new List<RoomFishProbabilityConfig>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.MyGame.Scripts.Net.APIResponses.GameConfig_SubClass
|
||||
{
|
||||
[Serializable]
|
||||
public class RoomFishProbabilityConfig
|
||||
{
|
||||
public int roomLevel = 0;
|
||||
public int type = 0;
|
||||
public int fishType;
|
||||
public List<int> firstFishCountRange;
|
||||
public List<int> timeRange ;
|
||||
public List<int> countRange;
|
||||
public List<int> maxCountRange;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36d2691ff5a725b4a8b961d7bb54e1eb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -10,6 +10,34 @@ using UnityEngine;
|
||||
|
||||
namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
{
|
||||
|
||||
public static class FrameDataParser
|
||||
{
|
||||
public static T Parse<T>(object frameData) where T : class, new()
|
||||
{
|
||||
if (frameData == null) return null;
|
||||
|
||||
// 如果已经是目标类型,直接返回
|
||||
if (frameData is T typed) return typed;
|
||||
|
||||
// 如果是字符串,直接反序列化
|
||||
if (frameData is string str)
|
||||
return JsonConvert.DeserializeObject<T>(str);
|
||||
|
||||
// 如果是 JObject,轻量解析
|
||||
if (frameData is JObject jObj)
|
||||
return jObj.ToObject<T>();
|
||||
|
||||
// 兜底:调用 ToString 再反序列化
|
||||
return JsonConvert.DeserializeObject<T>(frameData.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Serializable]
|
||||
public enum FrameDataType
|
||||
{
|
||||
@@ -65,6 +93,7 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
public class FrameData_ChangeAutoTarget : FrameData
|
||||
{
|
||||
public string targetGuid;
|
||||
public string targetPostName;
|
||||
}
|
||||
[Serializable]
|
||||
public class FrameData_RandomDieFish : FrameData
|
||||
|
||||
@@ -210,6 +210,11 @@ namespace Assets.MyGame.Scripts.Net
|
||||
case GameType.FLZY:
|
||||
{
|
||||
var panel = UIManager.Instance.Get<GameMainPanel_FLZY>(UIPanel.MainGamePanelFLZY);
|
||||
if (panel.currSitData.user== userid)
|
||||
{
|
||||
UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelFLZY);
|
||||
break;
|
||||
}
|
||||
foreach (var item in panel.list_Sits)
|
||||
{
|
||||
if (item.user == userid)
|
||||
@@ -238,6 +243,11 @@ namespace Assets.MyGame.Scripts.Net
|
||||
case GameType.XJMH:
|
||||
{
|
||||
var panel = UIManager.Instance.Get<GameMainPanel_XJMH>(UIPanel.MainGamePanelXJMH);
|
||||
if (panel.currSitData.user == userid)
|
||||
{
|
||||
UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelXJMH);
|
||||
break;
|
||||
}
|
||||
foreach (var item in panel.list_Sits)
|
||||
{
|
||||
Debug.Log(item.user+"---"+ userid);
|
||||
@@ -252,6 +262,11 @@ namespace Assets.MyGame.Scripts.Net
|
||||
case GameType.HHWK:
|
||||
{
|
||||
var panel = UIManager.Instance.Get<GameMainPanel_HHWK>(UIPanel.MainGamePanelHHWK);
|
||||
if (panel.currSitData.user == userid)
|
||||
{
|
||||
UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelHHWK);
|
||||
break;
|
||||
}
|
||||
foreach (var item in panel.list_Sits)
|
||||
{
|
||||
if (item.user == userid)
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@@ -17,6 +18,10 @@ public class SitPosData : MonoBehaviour
|
||||
[Header("金币")]
|
||||
public TextMeshProUGUI tMP_TurretConsumeNum;
|
||||
public TextMeshProUGUI tMP_GoldNum;
|
||||
|
||||
public Button btn_TurretAdd;
|
||||
public Button btn_TurretMinus;
|
||||
|
||||
public long goldNum;
|
||||
public long consumeGoldNum;
|
||||
[Header("炮台")]
|
||||
@@ -27,6 +32,7 @@ public class SitPosData : MonoBehaviour
|
||||
public TurretData currentTurret;
|
||||
[Header("锁定")]
|
||||
public MonsterContral monCotl_Lock;
|
||||
public Transform monCotl_Lock_Position;
|
||||
public bool isLock=false;
|
||||
public GameObject lockFX;
|
||||
|
||||
@@ -45,6 +51,15 @@ public class SitPosData : MonoBehaviour
|
||||
// return td1.turretID.CompareTo(td2.turretLevel);
|
||||
//});
|
||||
dic_Turrets = list_Turrets.ToDictionary(td => td.turretID);
|
||||
btn_TurretAdd.onClick.AddListener(() =>
|
||||
{
|
||||
ChangeTurretAddConsumeNum(1000);
|
||||
});
|
||||
btn_TurretMinus.onClick.AddListener(() =>
|
||||
{
|
||||
ChangeTurretMinusConsumeNum(1000);
|
||||
|
||||
});
|
||||
}
|
||||
public void Update()
|
||||
{
|
||||
@@ -83,6 +98,18 @@ public class SitPosData : MonoBehaviour
|
||||
consumeGoldNum = n;
|
||||
tMP_TurretConsumeNum.text = consumeGoldNum.ToString();
|
||||
|
||||
}
|
||||
public void ChangeTurretAddConsumeNum(int n = 0)
|
||||
{
|
||||
consumeGoldNum += n;
|
||||
tMP_TurretConsumeNum.text = consumeGoldNum.ToString();
|
||||
|
||||
}
|
||||
public void ChangeTurretMinusConsumeNum(int n = 0)
|
||||
{
|
||||
consumeGoldNum -= n;
|
||||
tMP_TurretConsumeNum.text = consumeGoldNum.ToString();
|
||||
|
||||
}
|
||||
public bool ConsumeGold(int bl=1)
|
||||
{
|
||||
|
||||
@@ -3,9 +3,11 @@ using Spine.Unity;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using static UnityEngine.AddressableAssets.Addressables;
|
||||
|
||||
[Serializable]
|
||||
@@ -40,9 +42,9 @@ public class AudioResourcesData
|
||||
await Addressables.LoadAssetsAsync<AudioClip>(keys, audio =>
|
||||
{
|
||||
Debug.Log("加载音频: " + audio.name);
|
||||
Debug.Log("加载音频ID: " + name_IDDic[audio.name]);
|
||||
if (name_IDDic.ContainsKey(audio.name))
|
||||
{
|
||||
Debug.Log("加载音频ID: " + name_IDDic[audio.name]);
|
||||
audioClipDefaultDic.Add(name_IDDic[audio.name],audio);
|
||||
}
|
||||
}, MergeMode.Intersection).Task;
|
||||
@@ -52,7 +54,7 @@ public class AudioResourcesData
|
||||
}
|
||||
Debug.Log("加载了:"+ audioClipDic.Count);
|
||||
}
|
||||
public static async void LoadAudioGame()
|
||||
public static async Task LoadAudioGame()
|
||||
{
|
||||
GameType gameType=GameManager.Instance.gameData.currGameType;
|
||||
var keys = new List<string> { Audio_AALabel, gameType.ToString() };
|
||||
@@ -62,16 +64,52 @@ public class AudioResourcesData
|
||||
//Debug.Log("加载音频ID: " + name_IDDic[audio.name]);
|
||||
if (name_IDDic.ContainsKey(audio.name))
|
||||
{
|
||||
audioClipGameDic.Add(name_IDDic[audio.name], audio);
|
||||
audioClipGameDic[name_IDDic[audio.name]]= audio;
|
||||
}
|
||||
}, MergeMode.Intersection).Task;
|
||||
audioClipDic=new Dictionary<int, AudioClip>(audioClipDefaultDic);
|
||||
foreach (var item in audioClipGameDic)
|
||||
{
|
||||
audioClipDic.Add(item.Key,item.Value);
|
||||
audioClipDic[item.Key]=item.Value;
|
||||
}
|
||||
Debug.Log("加载了:"+ audioClipDic.Count);
|
||||
|
||||
}
|
||||
public static async Task UnLoadAudioGame()
|
||||
{
|
||||
GameType gameType = GameManager.Instance.gameData.currGameType;
|
||||
var keys = new List<string> { Audio_AALabel, gameType.ToString() };
|
||||
|
||||
// 加载对应的句柄(只是为了拿到引用,之后释放)
|
||||
AsyncOperationHandle<IList<AudioClip>> handle = Addressables.LoadAssetsAsync<AudioClip>(keys, null, MergeMode.Intersection);
|
||||
await handle.Task;
|
||||
|
||||
// 遍历卸载对应的音频
|
||||
foreach (var audio in handle.Result)
|
||||
{
|
||||
if (name_IDDic.ContainsKey(audio.name))
|
||||
{
|
||||
int id = name_IDDic[audio.name];
|
||||
if (audioClipGameDic.ContainsKey(id))
|
||||
{
|
||||
audioClipGameDic.Remove(id);
|
||||
Debug.Log($"卸载音频: {audio.name} (ID={id})");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 释放 Addressables 资源句柄
|
||||
Addressables.Release(handle);
|
||||
|
||||
// 重建总字典:保留默认音频 + 剩余游戏音频
|
||||
audioClipDic = new Dictionary<int, AudioClip>(audioClipDefaultDic);
|
||||
foreach (var item in audioClipGameDic)
|
||||
{
|
||||
audioClipDic[item.Key] = item.Value;
|
||||
}
|
||||
|
||||
Debug.Log("卸载完成,当前音频数量:" + audioClipDic.Count);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Spine.Unity;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using static UnityEngine.AddressableAssets.Addressables;
|
||||
@@ -39,22 +40,27 @@ public class FishResourcesData
|
||||
private static Dictionary<string,int> FishResourcesPrefabsDic ;//prefabpath--id
|
||||
private static Dictionary<string,int> FishResourcesSpineDieDic ;//dieSpinepath--id
|
||||
private static Dictionary<string,int> FishResourcesSpriteDic;//Spritepath--id
|
||||
static FishResourcesData()
|
||||
static FishResourcesData()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
async static void Init()
|
||||
{
|
||||
|
||||
string prefabFishPath = Resources.Load<TextAsset>("tbfishresources").text;
|
||||
var v = JsonConvert.DeserializeObject<List<FishResourcesData>>(prefabFishPath);
|
||||
FishResourcesPrefabsDic=new Dictionary<string, int>();
|
||||
FishResourcesPrefabsDic = new Dictionary<string, int>();
|
||||
fishResourcesDatasDic = new Dictionary<int, FishResourcesData>();
|
||||
FishResourcesSpineDieDic = new Dictionary<string, int>();
|
||||
FishResourcesSpriteDic = new Dictionary<string, int>();
|
||||
foreach (var item in v)
|
||||
{
|
||||
if (item.prefabFishResourcesPath!=null&& item.prefabFishResourcesPath != "")
|
||||
if (item.prefabFishResourcesPath != null && item.prefabFishResourcesPath != "")
|
||||
{
|
||||
Debug.Log($"添加鱼资源数据: {item.fishNumber} - {item.prefabFishResourcesPath}");
|
||||
FishResourcesPrefabsDic.Add(item.prefabFishResourcesPath, item.fishNumber);
|
||||
FishResourcesSpriteDic.Add(item.prefabFishResourcesPath, item.fishNumber);
|
||||
if (item.dieEffectAssets!=null&&item.dieEffectAssets!="")
|
||||
if (item.dieEffectAssets != null && item.dieEffectAssets != "")
|
||||
{
|
||||
FishResourcesSpineDieDic.Add(item.dieEffectAssets, item.fishNumber);
|
||||
}
|
||||
@@ -65,7 +71,6 @@ public class FishResourcesData
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Dictionary<int, GameObject> fishPrefabDic;//id--prefabs
|
||||
@@ -73,48 +78,145 @@ public class FishResourcesData
|
||||
public static Dictionary<int, Sprite> fishResourcesSpritesDic;//id--Sprite
|
||||
private static Dictionary<int, SkeletonDataAsset> diePrefabDic;//id--SkeletonDataAsset
|
||||
|
||||
public static async void LoadFishAssetsData()
|
||||
public static async Task LoadFishAssetsData()
|
||||
{
|
||||
// 清空对象池,避免残留
|
||||
Pool.Instance.Clear();
|
||||
if (fishPrefabDic != null)
|
||||
return;
|
||||
|
||||
fishPrefabDic = new Dictionary<int, GameObject>();
|
||||
diePrefabDic= new Dictionary<int, SkeletonDataAsset>();
|
||||
diePrefabDic = new Dictionary<int, SkeletonDataAsset>();
|
||||
fishResourcesSpritesDic = new Dictionary<int, Sprite>();
|
||||
|
||||
|
||||
// ---------------- Prefab ----------------
|
||||
var keys = new List<string> { prefabFish_AALabel, GameManager.Instance.gameData.currGameType.ToString() };
|
||||
await Addressables.LoadAssetsAsync<GameObject>(keys, prefab =>
|
||||
var prefabHandle = Addressables.LoadAssetsAsync<GameObject>(keys, prefab =>
|
||||
{
|
||||
if (FishResourcesPrefabsDic.ContainsKey(prefab.name))
|
||||
if (FishResourcesPrefabsDic.TryGetValue(prefab.name, out int id))
|
||||
{
|
||||
fishPrefabDic.Add(FishResourcesPrefabsDic[prefab.name], prefab);
|
||||
prefab.GetComponent<MonsterContral>().fishTypeID = FishResourcesPrefabsDic[prefab.name];
|
||||
// 防御性检查,避免重复覆盖
|
||||
if (fishPrefabDic.ContainsKey(id))
|
||||
Debug.LogWarning($"Prefab重复加载,覆盖ID={id}, 名称={prefab.name}");
|
||||
|
||||
Pool.Instance.dic.Add(FishResourcesPrefabsDic[prefab.name], new PoolData(prefab,CreateFishManager.Instance.fishRoot.gameObject));
|
||||
fishPrefabDic[id] = prefab;
|
||||
|
||||
// 防御性检查组件
|
||||
var mc = prefab.GetComponent<MonsterContral>();
|
||||
if (mc != null)
|
||||
mc.fishTypeID = id;
|
||||
|
||||
// 加入对象池
|
||||
Pool.Instance.dic[id] = new PoolData(prefab, CreateFishManager.Instance.poolRoot.gameObject, id);
|
||||
}
|
||||
}, MergeMode.Intersection).Task;
|
||||
}, MergeMode.Intersection);
|
||||
|
||||
await prefabHandle.Task;
|
||||
Addressables.Release(prefabHandle);
|
||||
Debug.Log($"加载完成,共 {fishPrefabDic.Count} 个鱼Prefab");
|
||||
keys = new List<string> {dieSpine_AALabel,/* GameManager.Instance.gameData.currGameType.ToString()*/GameManager.Instance.gameData.currGameType.ToString() };
|
||||
await Addressables.LoadAssetsAsync<SkeletonDataAsset>(keys, data =>
|
||||
|
||||
// ---------------- 死亡 Spine 动效 ----------------
|
||||
keys = new List<string> { dieSpine_AALabel, GameManager.Instance.gameData.currGameType.ToString() };
|
||||
var dieHandle = Addressables.LoadAssetsAsync<SkeletonDataAsset>(keys, data =>
|
||||
{
|
||||
if (FishResourcesSpineDieDic.ContainsKey(data.name))
|
||||
if (FishResourcesSpineDieDic.TryGetValue(data.name, out int id))
|
||||
{
|
||||
diePrefabDic.Add(FishResourcesSpineDieDic[data.name], data); }
|
||||
},MergeMode.Intersection).Task;
|
||||
if (diePrefabDic.ContainsKey(id))
|
||||
Debug.LogWarning($"死亡动效重复加载,覆盖ID={id}, 名称={data.name}");
|
||||
|
||||
diePrefabDic[id] = data;
|
||||
}
|
||||
}, MergeMode.Intersection);
|
||||
|
||||
await dieHandle.Task;
|
||||
Addressables.Release(dieHandle);
|
||||
Debug.Log($"加载完成,共 {diePrefabDic.Count} 个鱼死亡动效");
|
||||
|
||||
keys = new List<string> { Sprite_AALabel,/* GameManager.Instance.gameData.currGameType.ToString()*/GameManager.Instance.gameData.currGameType.ToString() };
|
||||
await Addressables.LoadAssetsAsync<Sprite>(keys, data =>
|
||||
// ---------------- 鱼 Sprite ----------------
|
||||
keys = new List<string> { Sprite_AALabel, GameManager.Instance.gameData.currGameType.ToString() };
|
||||
var spriteHandle = Addressables.LoadAssetsAsync<Sprite>(keys, data =>
|
||||
{
|
||||
if (FishResourcesSpriteDic.ContainsKey(data.name))
|
||||
if (FishResourcesSpriteDic.TryGetValue(data.name, out int id))
|
||||
{
|
||||
fishResourcesSpritesDic.Add(FishResourcesSpriteDic[data.name], data);
|
||||
if (fishResourcesSpritesDic.ContainsKey(id))
|
||||
Debug.LogWarning($"Sprite重复加载,覆盖ID={id}, 名称={data.name}");
|
||||
|
||||
fishResourcesSpritesDic[id] = data;
|
||||
}
|
||||
}, MergeMode.Intersection).Task;
|
||||
}, MergeMode.Intersection);
|
||||
|
||||
await spriteHandle.Task;
|
||||
Addressables.Release(spriteHandle);
|
||||
Debug.Log($"加载完成,共 {fishResourcesSpritesDic.Count} 个鱼Sprite");
|
||||
}
|
||||
|
||||
|
||||
public static async Task UnLoadFishAssetsData()
|
||||
{
|
||||
Pool.Instance.Clear();
|
||||
|
||||
// 卸载 Prefab
|
||||
var keys = new List<string> { prefabFish_AALabel, GameManager.Instance.gameData.currGameType.ToString() };
|
||||
var prefabHandle = Addressables.LoadAssetsAsync<GameObject>(keys, null, MergeMode.Intersection);
|
||||
await prefabHandle.Task;
|
||||
|
||||
if (prefabHandle.Result != null)
|
||||
{
|
||||
foreach (var prefab in prefabHandle.Result)
|
||||
{
|
||||
if (FishResourcesPrefabsDic.TryGetValue(prefab.name, out int id))
|
||||
{
|
||||
if (fishPrefabDic.Remove(id))
|
||||
{
|
||||
Debug.Log($"卸载鱼Prefab: {prefab.name} (ID={id})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Addressables.Release(prefabHandle);
|
||||
|
||||
// 卸载死亡 Spine 动效
|
||||
keys = new List<string> { dieSpine_AALabel, GameManager.Instance.gameData.currGameType.ToString() };
|
||||
var dieHandle = Addressables.LoadAssetsAsync<SkeletonDataAsset>(keys, null, MergeMode.Intersection);
|
||||
await dieHandle.Task;
|
||||
|
||||
if (dieHandle.Result != null)
|
||||
{
|
||||
foreach (var data in dieHandle.Result)
|
||||
{
|
||||
if (FishResourcesSpineDieDic.TryGetValue(data.name, out int id))
|
||||
{
|
||||
if (diePrefabDic.Remove(id))
|
||||
{
|
||||
Debug.Log($"卸载鱼死亡动效: {data.name} (ID={id})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Addressables.Release(dieHandle);
|
||||
|
||||
// 卸载鱼 Sprite
|
||||
keys = new List<string> { Sprite_AALabel, GameManager.Instance.gameData.currGameType.ToString() };
|
||||
var spriteHandle = Addressables.LoadAssetsAsync<Sprite>(keys, null, MergeMode.Intersection);
|
||||
await spriteHandle.Task;
|
||||
|
||||
if (spriteHandle.Result != null)
|
||||
{
|
||||
foreach (var sprite in spriteHandle.Result)
|
||||
{
|
||||
if (FishResourcesSpriteDic.TryGetValue(sprite.name, out int id))
|
||||
{
|
||||
if (fishResourcesSpritesDic.Remove(id))
|
||||
{
|
||||
Debug.Log($"卸载鱼Sprite: {sprite.name} (ID={id})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Addressables.Release(spriteHandle);
|
||||
|
||||
Debug.Log($"卸载完成,剩余Prefab数量: {fishPrefabDic.Count}, 死亡动效数量: {diePrefabDic.Count}, Sprite数量: {fishResourcesSpritesDic.Count}");
|
||||
}
|
||||
|
||||
|
||||
public static GameObject GetFishPrefab(int fishNumber)
|
||||
{
|
||||
if (fishPrefabDic != null && fishPrefabDic.ContainsKey(fishNumber))
|
||||
|
||||
Reference in New Issue
Block a user