1
This commit is contained in:
@@ -209,12 +209,21 @@ public class MonsterContral : MonoBehaviour
|
||||
fishenum = (FishTypeEnum)monsterData.fishTypeConfig.fishType;
|
||||
|
||||
// 路径结束后自动销毁
|
||||
StartCoroutine(yanchi(gameObject,time));
|
||||
StartCoroutine(yanchi(gameObject,time, isyuzhen));
|
||||
}
|
||||
public IEnumerator yanchi(GameObject obj,float time)
|
||||
public IEnumerator yanchi(GameObject obj,float time, bool isyuzhen)
|
||||
{
|
||||
if (isyuzhen)
|
||||
{
|
||||
Debug.Log($"[MonsterContral] 鱼阵 {yzID} 路线结束,等待 {time} 秒后销毁"+ guid);
|
||||
}
|
||||
yield return new WaitForSeconds(time);
|
||||
if (isyuzhen)
|
||||
{
|
||||
Debug.Log($"[MonsterContral] 鱼阵 {yzID} 路线结束,销毁对象" + guid);
|
||||
}
|
||||
CreateFishManager.Instance.Id_DieFish_NotFX(guid);
|
||||
|
||||
}
|
||||
// ================================================================
|
||||
// 状态机
|
||||
@@ -309,7 +318,9 @@ public class MonsterContral : MonoBehaviour
|
||||
|
||||
// 702 / 710:贝塞尔曲线路径
|
||||
case "702":
|
||||
case "710":
|
||||
case "7007":
|
||||
case "710": // 顺序阵:每条路径逐一延迟生成
|
||||
case "704":
|
||||
{
|
||||
Vector2 next = monsterData.moveLine.GetBezierPointJob(moveTime);
|
||||
if (fishenum != FishTypeEnum.Boss鱼)
|
||||
|
||||
@@ -262,7 +262,7 @@ public class MonsterControl_BossBase : MonsterContral
|
||||
|
||||
}
|
||||
public float dieTime = 3f;
|
||||
public Vector3 v3;
|
||||
public Vector3 v3;//分数飞出位置
|
||||
IEnumerator yanchidie()
|
||||
{
|
||||
yield return new WaitForSeconds(dieTime);
|
||||
|
||||
@@ -60,21 +60,9 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// <summary>fishArrayNumber → FishArrayConfig(鱼阵配置缓存)</summary>
|
||||
private Dictionary<string, FishArrayConfig> fishArrayConfigDic;
|
||||
|
||||
/// <summary>fishNumber → FishTypeConfig(与 fishDatas 相同来源,供内部使用)</summary>
|
||||
private Dictionary<string, FishTypeConfig> fishTypeConfigDic;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// 运行时鱼实例字典(guid 为 key)
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/// <summary>全部存活鱼(包含 Boss / 小鱼 / 黄金鱼)</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey = new Dictionary<string, MonsterContral>();
|
||||
|
||||
/// <summary>Boss 鱼</summary>
|
||||
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>();
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// UI 引用
|
||||
@@ -126,28 +114,56 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
private NativeArray<float> timers; // 每条鱼的累计计时
|
||||
private NativeArray<float> frequencies; // 每条鱼的生成间隔
|
||||
private NativeArray<int> shouldSpawn; // 1=本帧应尝试生成,0=冷却中
|
||||
// ----------------------------------------------------------------
|
||||
// 运行时鱼实例字典(guid 为 key)
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/// <summary>全部存活鱼(包含 Boss / 小鱼 / 黄金鱼)</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey = new Dictionary<string, MonsterContral>();
|
||||
/// <summary>普通鱼</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_Small = new Dictionary<string, MonsterContral>();
|
||||
/// <summary>Boss 鱼</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_Boss = new Dictionary<string, MonsterContral>();
|
||||
/// <summary>黄金</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_HJ = new Dictionary<string, MonsterContral>();
|
||||
/// <summary>特殊鱼(非 Boss)</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_TS = new Dictionary<string, MonsterContral>();
|
||||
/// <summary>特殊 Boss</summary>
|
||||
public Dictionary<string, MonsterContral> fishDatas_hashCodekey_TS_Boss = new Dictionary<string, MonsterContral>();
|
||||
// ------ 各类计时器 ------
|
||||
private RoomFishProbabilityConfig tsbossCreateData; // 特殊Boss 创建数据
|
||||
private float tsbossTimer = 999f; // 特殊Boss 刷新倒计时(秒)
|
||||
private int tsbossCount; // 本轮同时启用特殊Boss鱼数量
|
||||
private int tsbossQuanZhongCount; // 本轮同时启用特殊Boss鱼数量
|
||||
|
||||
private RoomFishProbabilityConfig tsCreateData; // 特殊鱼 创建数据
|
||||
private float tsTimer = 999f; // 特殊鱼 刷新倒计时(秒)
|
||||
private int tsCount; // 本轮同时启用特殊鱼数量
|
||||
private int tsQuanZhongCount; // 本轮同时启用特殊鱼数量
|
||||
|
||||
private RoomFishProbabilityConfig bossCreateData; // Boss 创建数据
|
||||
private float bossTimer = 999f; // Boss 刷新倒计时(秒)
|
||||
private int bossCount; // 本轮同时启用Boss鱼数量
|
||||
private int bossQuanZhongCount; // 本轮同时启用Boss鱼数量
|
||||
|
||||
private RoomFishProbabilityConfig yzCreateData; // 鱼阵创建数据
|
||||
private float yzTimer = 999f; // 鱼阵刷新倒计时(秒)
|
||||
private int yzCount; // 本轮同时激活阵型数量
|
||||
private int yz_LineCount = 0; // 场景内鱼阵路线总数
|
||||
private int yzQuanZhongCount = 0; // 场景内鱼阵路线总数
|
||||
|
||||
|
||||
private RoomFishProbabilityConfig ptCreateData; // 普通鱼创建数据
|
||||
private float ptTimer = 999f; // 普通鱼批量启用倒计时(秒)
|
||||
private int ptCount; // 本轮同时启用普通鱼数量
|
||||
private int ptQuanZhongCount; // 本轮同时启用普通鱼数量
|
||||
|
||||
private RoomFishProbabilityConfig hjCreateData; // 普通鱼创建数据
|
||||
private float hjTimer = 999f; // 黄金鱼批量启用倒计时(秒)
|
||||
private int yzCount; // 本轮同时激活阵型数量
|
||||
private int ptCount; // 本轮同时启用普通鱼数量
|
||||
private int hjCount; // 本轮同时启用黄金鱼数量
|
||||
private int tsCount; // 本轮同时启用特殊鱼数量
|
||||
private int bossCount; // 本轮同时启用特殊Boss鱼数量
|
||||
private int tsbossCount; // 本轮同时启用Boss鱼数量
|
||||
private int yz_LineCount = 0; // 场景内鱼阵路线总数
|
||||
|
||||
private int hjQuanZhongCount; // 本轮同时启用黄金鱼数量
|
||||
|
||||
|
||||
/// <summary>是否开启放鱼(false 时 Update 不执行生成逻辑)</summary>
|
||||
public bool fangzhu;
|
||||
public bool isResources = false;
|
||||
@@ -197,7 +213,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
base.Awake();
|
||||
yzCreateData = new RoomFishProbabilityConfig
|
||||
{
|
||||
countRange =new List<int> { 2, 3 },
|
||||
countRange = new List<int> { 2, 3 },
|
||||
firstFishCountRange = new List<int> { 2, 3 },
|
||||
roomLevel = 3,
|
||||
fishType = 0,
|
||||
@@ -227,7 +243,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
isCreateFish = BroadCastCreateFish();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
@@ -247,13 +263,14 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
ptCount = Random.Range(ptCreateData.countRange[0], ptCreateData.countRange[1]);
|
||||
hjCount = Random.Range(hjCreateData.countRange[0], hjCreateData.countRange[1]);
|
||||
bossCount = Random.Range(bossCreateData.countRange[0], bossCreateData.countRange[1]);
|
||||
tsbossCount = Random.Range(tsbossCreateData.countRange[0], tsbossCreateData.countRange[1]);
|
||||
tsCount = Random.Range(tsCreateData.countRange[0], tsCreateData.countRange[1]);
|
||||
yzTimer = 0.5f;
|
||||
ptTimer = 0.5f;
|
||||
hjTimer = 0.5f;
|
||||
tsTimer = 1f;
|
||||
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]);
|
||||
tsbossTimer = 5f;
|
||||
}
|
||||
/// <summary>
|
||||
/// 懒加载初始化:只执行一次,构建全部配置缓存字典。
|
||||
@@ -299,7 +316,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
fishArrayConfigDic = GameManager.Instance.gameConfig.fishArrayConfigs
|
||||
.ToDictionary(a => a.fishArrayNumber, a => a);
|
||||
|
||||
fishTypeConfigDic = GameManager.Instance.gameConfig.fishTypeConfigs
|
||||
fishDatas = GameManager.Instance.gameConfig.fishTypeConfigs
|
||||
.ToDictionary(f => f.fishNumber, f => f);
|
||||
}
|
||||
|
||||
@@ -324,16 +341,16 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
switch (GameManager.Instance.gameData.currGameType)
|
||||
{
|
||||
case GameType.FLZY:
|
||||
currGameType = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelFLZY);
|
||||
currGameType = UIManager.Instance.Get<GameMainPanel_FLZY>(UIPanel.MainGamePanelFLZY);
|
||||
break;
|
||||
case GameType.YYSC:
|
||||
currGameType = UIManager.Instance.Get<GameMainPanel_YYSC>(UIPanel.MainGamePanelYYSC);
|
||||
break;
|
||||
case GameType.XJMH:
|
||||
currGameType = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelXJMH);
|
||||
currGameType = UIManager.Instance.Get<GameMainPanel_XJMH>(UIPanel.MainGamePanelXJMH);
|
||||
break;
|
||||
case GameType.HHWK:
|
||||
currGameType = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelHHWK);
|
||||
currGameType = UIManager.Instance.Get<GameMainPanel_HHWK>(UIPanel.MainGamePanelHHWK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -407,6 +424,9 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
hjCreateData = item;
|
||||
break;
|
||||
case FishTypeEnum.特殊鱼:
|
||||
tsCreateData = item;
|
||||
break;
|
||||
case FishTypeEnum.特殊Boss:
|
||||
tsbossCreateData = item;
|
||||
break;
|
||||
default:
|
||||
@@ -430,6 +450,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
{
|
||||
spawnDic[item.fishNumber] = item;
|
||||
spawnList.Add(item);
|
||||
yzQuanZhongCount += item.fishWeight;
|
||||
TryAddToArrayLine(item);
|
||||
}
|
||||
else
|
||||
@@ -438,6 +459,27 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
// 等级鱼也加入 spawnDic / spawnList
|
||||
spawnDic[item.fishNumber] = item;
|
||||
spawnList.Add(item);
|
||||
fishDatas.TryGetValue(item.fishNumber, out var ft);
|
||||
switch ((FishTypeEnum)ft.fishType)
|
||||
{
|
||||
case FishTypeEnum.普通鱼:
|
||||
ptQuanZhongCount += item.fishWeight;
|
||||
break;
|
||||
case FishTypeEnum.Boss鱼:
|
||||
bossQuanZhongCount += item.fishWeight;
|
||||
break;
|
||||
case FishTypeEnum.黄金鱼:
|
||||
hjQuanZhongCount += item.fishWeight;
|
||||
break;
|
||||
case FishTypeEnum.特殊鱼:
|
||||
tsQuanZhongCount += item.fishWeight;
|
||||
break;
|
||||
case FishTypeEnum.特殊Boss:
|
||||
tsbossQuanZhongCount += item.fishWeight;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -533,12 +575,21 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
// ---- 3. 鱼阵定时激活 ----
|
||||
TickFishArraySpawn(dt);
|
||||
TickFishArraySpawn(dt);
|
||||
|
||||
// ---- 4. 普通鱼定时批量激活 ----
|
||||
TickNormalFishSpawn(dt);
|
||||
TickPTFishSpawn(dt);
|
||||
|
||||
// ---- 5. 遍历 shouldSpawn,向服务器发送生成请求 ----
|
||||
// ---- 5. 黄金鱼定时激活 ----
|
||||
TickHJFishSpawn(dt);
|
||||
|
||||
// ---- 5. 特殊鱼定时激活 ----
|
||||
TickTSFishSpawn(dt);
|
||||
|
||||
|
||||
// ---- 6. 特殊boss定时激活 ----
|
||||
TickTSBossSpawn(dt);
|
||||
|
||||
// ---- 7. 遍历 shouldSpawn,向服务器发送生成请求 ----
|
||||
ProcessSpawnRequests();
|
||||
return true;
|
||||
}
|
||||
@@ -552,63 +603,119 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
{
|
||||
bossTimer -= dt;
|
||||
if (bossTimer > 0f) return;
|
||||
bossCount = Random.Range(bossCreateData.countRange[0], bossCreateData.countRange[1]);
|
||||
|
||||
bossCount = Random.Range(bossCreateData.countRange[0], bossCreateData.countRange[1]);
|
||||
bossTimer = Random.Range(bossCreateData.timeRange[0], bossCreateData.timeRange[1]);
|
||||
|
||||
//bossTimer = 3f;
|
||||
if (!fishTypeConfig.TryGetValue(FishTypeEnum.Boss鱼, out var bossList) || bossList.Count == 0)
|
||||
return;
|
||||
if (fishTypeConfig.TryGetValue(FishTypeEnum.特殊Boss, out var TSbossList) && TSbossList.Count > 0)
|
||||
{
|
||||
bossList.AddRange(TSbossList);
|
||||
}
|
||||
|
||||
|
||||
StartCoroutine(buchongfu(bossList, bossCount));
|
||||
|
||||
foreach (var item in bossList)
|
||||
{
|
||||
if (item.fishNumber == 11041.ToString())
|
||||
{
|
||||
item.isCreate = 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>每 25 秒随机激活一条 特殊Boss 鱼。</summary>
|
||||
private void TickTSBossSpawn(float dt)
|
||||
{
|
||||
tsbossTimer -= dt;
|
||||
if (tsbossTimer > 0f) return;
|
||||
tsbossCount = Random.Range(tsbossCreateData.countRange[0], tsbossCreateData.countRange[1]);
|
||||
|
||||
tsbossTimer = Random.Range(tsbossCreateData.timeRange[0], tsbossCreateData.timeRange[1]);
|
||||
|
||||
if (!fishTypeConfig.TryGetValue(FishTypeEnum.特殊Boss, out var tsbossList) || tsbossList.Count == 0)
|
||||
return;
|
||||
|
||||
|
||||
StartCoroutine(buchongfu(tsbossList, tsbossCount));
|
||||
|
||||
|
||||
}
|
||||
private RoomFishDetailConfig GetRandomFishByWeight(List<RoomFishDetailConfig> configs)
|
||||
{
|
||||
if (configs == null || configs.Count == 0) return null;
|
||||
|
||||
int totalWeight = configs.Sum(c => c.fishWeight);
|
||||
int randWeight = Random.Range(0, totalWeight);
|
||||
|
||||
foreach (var cfg in configs)
|
||||
{
|
||||
randWeight -= cfg.fishWeight;
|
||||
if (randWeight <= 0) // 注意这里是 <= 0
|
||||
{
|
||||
return cfg;
|
||||
}
|
||||
}
|
||||
|
||||
return configs[configs.Count - 1]; // 理论上不会到这里
|
||||
}
|
||||
/// <summary>
|
||||
/// 从配置列表中按权重随机选择指定数量的鱼,不重复。
|
||||
/// </summary>
|
||||
private List<RoomFishDetailConfig> GetRandomFishByWeight(List<RoomFishDetailConfig> configs, int count)
|
||||
{
|
||||
var result = new List<RoomFishDetailConfig>();
|
||||
if (configs == null || configs.Count == 0 || count <= 0) return result;
|
||||
|
||||
// 拷贝一份候选集合,避免修改原始列表
|
||||
var candidates = new List<RoomFishDetailConfig>(configs);
|
||||
|
||||
count = Mathf.Min(count, candidates.Count); // 不超过候选数量
|
||||
|
||||
for (int k = 0; k < count; k++)
|
||||
{
|
||||
int totalWeight = candidates.Sum(c => c.fishWeight);
|
||||
int randWeight = Random.Range(0, totalWeight);
|
||||
|
||||
RoomFishDetailConfig chosen = null;
|
||||
foreach (var cfg in candidates)
|
||||
{
|
||||
randWeight -= cfg.fishWeight;
|
||||
if (randWeight <= 0) // 注意这里是 <= 0
|
||||
{
|
||||
chosen = cfg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (chosen != null)
|
||||
{
|
||||
result.Add(chosen);
|
||||
candidates.Remove(chosen); // 移除已选,保证不重复
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IEnumerator buchongfu(List<RoomFishDetailConfig> bossList, int count)
|
||||
{
|
||||
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
while (true)
|
||||
// 1. 先筛选出未重复的候选集合
|
||||
var candidates = bossList
|
||||
.Where(b => !fishDatas_hashCodekey_Boss.Values
|
||||
.Any(existing => existing.fishTypeID.ToString() == b.fishNumber))
|
||||
.ToList();
|
||||
|
||||
if (candidates.Count == 0)
|
||||
{
|
||||
int i = Random.Range(0, bossList.Count);
|
||||
if (fishDatas_hashCodekey_Boss.Count > 0)
|
||||
{
|
||||
foreach (var item in fishDatas_hashCodekey_Boss)
|
||||
{
|
||||
if (bossList[i].fishNumber != item.Value.fishTypeID.ToString())
|
||||
{
|
||||
bossList[i].isCreate = 2;
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bossList[i].isCreate = 2;
|
||||
yield break;
|
||||
}
|
||||
yield return null;
|
||||
yield break; // 没有可用候选,直接退出
|
||||
}
|
||||
|
||||
// 2. 在候选集合里做加权随机
|
||||
var chosen = GetRandomFishByWeight(candidates);
|
||||
|
||||
// 3. 标记激活
|
||||
chosen.isCreate = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>每 1~3 秒随机激活若干组鱼阵。</summary>
|
||||
private void TickFishArraySpawn(float dt)
|
||||
{
|
||||
@@ -638,6 +745,9 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
var chosen = lineList[Random.Range(0, lineList.Count)];
|
||||
chosen.isCreate = 2;
|
||||
|
||||
|
||||
|
||||
|
||||
// 同步更新 spawnDic 中的状态
|
||||
if (spawnDic.TryGetValue(chosen.fishNumber, out var spawnEntry))
|
||||
spawnEntry.isCreate = 2;
|
||||
@@ -645,7 +755,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
}
|
||||
|
||||
/// <summary>每 3 秒随机批量激活若干条普通鱼。</summary>
|
||||
private void TickNormalFishSpawn(float dt)
|
||||
private void TickPTFishSpawn(float dt)
|
||||
{
|
||||
ptTimer -= dt;
|
||||
if (ptTimer > 0f) return;
|
||||
@@ -658,21 +768,50 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
if (!fishTypeConfig.TryGetValue(FishTypeEnum.普通鱼, out var normalList) || normalList.Count == 0)
|
||||
return;
|
||||
if (fishTypeConfig.TryGetValue(FishTypeEnum.黄金鱼, out var normalList1) && normalList1.Count != 0)
|
||||
{
|
||||
normalList.AddRange(normalList1);
|
||||
|
||||
}
|
||||
if (fishTypeConfig.TryGetValue(FishTypeEnum.特殊鱼, out var normalList2) && normalList2.Count != 0)
|
||||
{
|
||||
normalList.AddRange(normalList2);
|
||||
}
|
||||
// 随机选 ptCount 个不重复下标
|
||||
var indices = RandomUniqueNumbers(
|
||||
Mathf.Min(ptCount, normalList.Count), 0, normalList.Count);
|
||||
var indices = GetRandomFishByWeight(normalList, ptCount);
|
||||
|
||||
foreach (int idx in indices)
|
||||
normalList[idx].isCreate = 2;
|
||||
foreach (var fish in indices)
|
||||
fish.isCreate = 2;
|
||||
}
|
||||
|
||||
/// <summary>每 3 秒随机批量激活若干条黄金鱼。</summary>
|
||||
private void TickHJFishSpawn(float dt)
|
||||
{
|
||||
hjTimer -= dt;
|
||||
if (hjTimer > 0f) return;
|
||||
|
||||
hjCount = Random.Range(hjCreateData.countRange[0], hjCreateData.countRange[1]);
|
||||
|
||||
|
||||
hjTimer = Random.Range(hjCreateData.timeRange[0], hjCreateData.timeRange[1]);
|
||||
|
||||
if (!fishTypeConfig.TryGetValue(FishTypeEnum.黄金鱼, out var hjlist) || hjlist.Count == 0)
|
||||
return;
|
||||
// 随机选 hjCount 个不重复下标
|
||||
var indices = GetRandomFishByWeight(hjlist, hjCount);
|
||||
foreach (var fish in indices)
|
||||
fish.isCreate = 2;
|
||||
}
|
||||
|
||||
/// <summary>每 3 秒随机批量激活若干条特殊鱼。</summary>
|
||||
private void TickTSFishSpawn(float dt)
|
||||
{
|
||||
tsTimer -= dt;
|
||||
if (tsTimer > 0f) return;
|
||||
|
||||
tsCount = Random.Range(tsCreateData.countRange[0], tsCreateData.countRange[1]);
|
||||
|
||||
|
||||
tsTimer = Random.Range(tsCreateData.timeRange[0], tsCreateData.timeRange[1]);
|
||||
|
||||
if (!fishTypeConfig.TryGetValue(FishTypeEnum.特殊鱼, out var tslist) || tslist.Count == 0)
|
||||
return;
|
||||
// 随机选 tsCount 个不重复下标
|
||||
var indices = GetRandomFishByWeight(tslist, tsCount);
|
||||
|
||||
foreach (var fish in indices)
|
||||
fish.isCreate = 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -717,7 +856,22 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
if (pathList != null && pathList.Count > 0)
|
||||
pathId = pathList[Random.Range(0, pathList.Count)];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (!fishArrayConfigDic.TryGetValue(fish.fishNumber, out var yz))
|
||||
{
|
||||
Debug.LogError($"[CreateFishManager] 找不到 fishArrayConfig: {fish.fishNumber}");
|
||||
return;
|
||||
}
|
||||
if (!FishYZ.dicfishYZ.TryGetValue(yz.arrayNumber, out var pathList) || pathList.Count == 0)
|
||||
{
|
||||
Debug.LogWarning($"[CreateFishManager] 鱼阵路线为空: {yz.arrayNumber}");
|
||||
return;
|
||||
}
|
||||
if (pathList != null && pathList.Count > 0)
|
||||
pathId = pathList[Random.Range(0, pathList.Count)];
|
||||
}
|
||||
var sgd = new SyncGameData
|
||||
{
|
||||
sitPos = GameManager.Instance.gameData.roomJoinNotice.position,
|
||||
@@ -765,7 +919,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
else if (cfg.type == 2)
|
||||
{
|
||||
// 鱼阵
|
||||
SpawnFishArray(createFishData, cfg, time);
|
||||
SpawnFishArray(createFishData, cfg.fishNumber, time);
|
||||
}
|
||||
}
|
||||
// ================================================================
|
||||
@@ -779,7 +933,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// <returns>成功返回 true,配置缺失返回 false。</returns>
|
||||
private bool OnlyFish(FrameData_CreateFish createFishData, long time)
|
||||
{
|
||||
if (!fishTypeConfigDic.TryGetValue(createFishData.fishNumber, out var fishType))
|
||||
if (!fishDatas.TryGetValue(createFishData.fishNumber, out var fishType))
|
||||
{
|
||||
Debug.LogError($"[CreateFishManager] 找不到 fishTypeConfig: {createFishData.fishNumber}");
|
||||
return false;
|
||||
@@ -787,6 +941,7 @@ 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);
|
||||
|
||||
try
|
||||
{
|
||||
var fish = Pool.Instance.Get(int.Parse(createFishData.fishNumber), new Vector3(9999, 9999, 0), Quaternion.identity, fishRoot);
|
||||
@@ -810,34 +965,66 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>将鱼实例注册到全局字典及对应分类字典。</summary>
|
||||
private void RegisterFishInstance(MonsterContral mc, int fishTypeId)
|
||||
{
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
|
||||
switch (fishTypeId)
|
||||
{
|
||||
case 1: // 普通鱼
|
||||
fishDatas_hashCodekey_Small[mc.guid] = mc;
|
||||
break;
|
||||
case 2: // Boss
|
||||
fishDatas_hashCodekey_Boss[mc.guid] = mc;
|
||||
|
||||
break;
|
||||
case 3: // 特殊鱼 / 黄金鱼
|
||||
fishDatas_hashCodekey_HJ[mc.guid] = mc;
|
||||
|
||||
break;
|
||||
case 4:
|
||||
fishDatas_hashCodekey_TS[mc.guid] = mc;
|
||||
|
||||
break;
|
||||
case 5:
|
||||
fishDatas_hashCodekey_TS_Boss[mc.guid] = mc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#region 鱼阵
|
||||
// ================================================================
|
||||
// 鱼阵生成(按 arrayNumber 前缀分发到对应阵型协程/方法)
|
||||
// ================================================================
|
||||
|
||||
/// <summary>根据鱼阵配置分发到对应的生成逻辑。</summary>
|
||||
private void SpawnFishArray(FrameData_CreateFish createFishData, RoomFishDetailConfig cfg, long time)
|
||||
private void SpawnFishArray(FrameData_CreateFish createFishData, string fishNumber, long time)
|
||||
{
|
||||
if (!fishArrayConfigDic.TryGetValue(cfg.fishNumber, out var yz))
|
||||
if (!fishArrayConfigDic.TryGetValue(fishNumber, out var yz))
|
||||
{
|
||||
Debug.LogError($"[CreateFishManager] 找不到 fishArrayConfig: {cfg.fishNumber}");
|
||||
Debug.LogError($"[CreateFishManager] 找不到 fishArrayConfig: {fishNumber}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fishTypeConfigDic.TryGetValue(yz.fishNumber, out var fishType))
|
||||
if (!fishDatas.TryGetValue(yz.fishNumber, out var fishType))
|
||||
{
|
||||
Debug.LogError($"[CreateFishManager] 鱼阵 fishType 缺失: {yz.fishNumber}");
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Debug.LogWarning($"[CreateFishManager] 鱼阵路线为空: {yz.arrayNumber}");
|
||||
return;
|
||||
}
|
||||
|
||||
var prefab = FishResourcesData.GetFishPrefab(int.Parse(fishType.fishNumber));
|
||||
var pos = new Vector3(9999, 9999, 0);
|
||||
|
||||
|
||||
|
||||
string prefix = yz.arrayNumber.Length >= 3
|
||||
? yz.arrayNumber.Substring(0, 3)
|
||||
: yz.arrayNumber;
|
||||
@@ -861,7 +1048,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
// ? pathList[Random.Range(0, pathList.Count)]
|
||||
// : -1;
|
||||
|
||||
StartCoroutine(YZ7007(createFishData, yz, pos, prefab, pathList[Random.Range(0, pathList.Count)], time, yz.fishCount));
|
||||
StartCoroutine(YZ7007(createFishData, yz, pos, prefab, time));
|
||||
//foreach (int pathId in pathList)
|
||||
//{
|
||||
// int actualPath = (prefix == "710") ? chosen710 : pathId;
|
||||
@@ -913,14 +1100,12 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
var fish = Pool.Instance.Get(int.Parse(yz.fishNumber), pos, rotation, fishRoot);
|
||||
|
||||
var mc = fish.GetComponent<MonsterContral>();
|
||||
RegisterFishInstance(mc, FishDatas[yz.fishNumber].fishType);
|
||||
|
||||
mc.monsterData.fishTypeConfig = FishDatas[yz.fishNumber];
|
||||
mc.guid = createFishData.guid + i;
|
||||
RegisterFishInstance(mc, FishDatas[yz.fishNumber].fishType);
|
||||
|
||||
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
|
||||
//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);
|
||||
}
|
||||
@@ -944,14 +1129,12 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
var fish = Pool.Instance.Get(int.Parse(yz.fishNumber), pos, rotation, fishRoot);
|
||||
|
||||
var mc = fish.GetComponent<MonsterContral>();
|
||||
RegisterFishInstance(mc, FishDatas[yz.fishNumber].fishType);
|
||||
|
||||
mc.monsterData.fishTypeConfig = FishDatas[yz.fishNumber];
|
||||
mc.guid = createFishData.guid + i;
|
||||
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
|
||||
RegisterFishInstance(mc, FishDatas[yz.fishNumber].fishType);
|
||||
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
fishDatas_hashCodekey_Small[mc.guid] = mc;
|
||||
mc.moveTime = (BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f;
|
||||
|
||||
mc.Init(pathId.ToString(), cfg.times, true, yz.arrayNumber);
|
||||
}
|
||||
@@ -961,11 +1144,10 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// 顺序阵:每隔 1s 生成一条鱼,共生成 count 条。
|
||||
/// </summary>
|
||||
private IEnumerator YZ7007(FrameData_CreateFish createFishData, FishArrayConfig yz,
|
||||
Vector3 pos, GameObject prefab, int pathId, long time, int count)
|
||||
Vector3 pos, GameObject prefab, long time)
|
||||
{
|
||||
var cfg = spawnDic[createFishData.fishNumber];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
for (int i = 0; i < yz.fishCount; i++)
|
||||
{
|
||||
if (!isResources)
|
||||
{
|
||||
@@ -975,41 +1157,22 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
var fish = Pool.Instance.Get(int.Parse(yz.fishNumber), pos, Quaternion.identity, fishRoot);
|
||||
|
||||
var mc = fish.GetComponent<MonsterContral>() ?? fish.AddComponent<MonsterContral>();
|
||||
RegisterFishInstance(mc, FishDatas[yz.fishNumber].fishType);
|
||||
|
||||
|
||||
mc.monsterData.fishTypeConfig = FishDatas[yz.fishNumber];
|
||||
mc.guid = createFishData.guid + i;
|
||||
RegisterFishInstance(mc, FishDatas[yz.fishNumber].fishType);
|
||||
// 每条鱼额外减去已等待秒数,使路径起点与帧数同步
|
||||
mc.moveTime = ((BeijingTimeManager.Instance.CurrentTimestampMs - time) / 1000f) - i;
|
||||
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
fishDatas_hashCodekey_Small[mc.guid] = mc;
|
||||
|
||||
mc.Init(pathId.ToString(), cfg.times, true, yz.arrayNumber);
|
||||
mc.Init(createFishData.moveLineId, cfg.times, true, yz.arrayNumber);
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>将鱼实例注册到全局字典及对应分类字典。</summary>
|
||||
private void RegisterFishInstance(MonsterContral mc, int fishTypeId)
|
||||
{
|
||||
fishDatas_hashCodekey[mc.guid] = mc;
|
||||
|
||||
switch (fishTypeId)
|
||||
{
|
||||
case 1: // 普通鱼
|
||||
case 3: // 特殊鱼 / 黄金鱼
|
||||
fishDatas_hashCodekey_Small[mc.guid] = mc;
|
||||
break;
|
||||
case 2: // Boss
|
||||
case 4:
|
||||
case 5:
|
||||
fishDatas_hashCodekey_Boss[mc.guid] = mc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1216,12 +1379,15 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
break;
|
||||
case FishTypeEnum.黄金鱼:
|
||||
fishDatas_hashCodekey_Small.Remove(fishId);
|
||||
fishDatas_hashCodekey_HJ.Remove(fishId);
|
||||
|
||||
break;
|
||||
case FishTypeEnum.特殊鱼:
|
||||
fishDatas_hashCodekey_Small.Remove(fishId);
|
||||
fishDatas_hashCodekey_TS.Remove(fishId);
|
||||
|
||||
break;
|
||||
case FishTypeEnum.特殊Boss:
|
||||
fishDatas_hashCodekey_TS_Boss.Remove(fishId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1254,13 +1420,11 @@ 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;
|
||||
coinScript.endPoint = endTra;
|
||||
var coinScript = award.GetComponent<BJBase>();
|
||||
coinScript.Init(coinNum.Amount, v3Point);
|
||||
coinScript.endPoint = v3Point;
|
||||
coinScript.isBoss = true;
|
||||
coinScript.SetCoinCount(coinNum.Amount);
|
||||
coinScript.SetCoinCount();
|
||||
}
|
||||
|
||||
//MonsterDieList.Instance.SmallHuangYiHuang(
|
||||
@@ -1295,16 +1459,13 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
// 4. 设置 CoinScript 的终点为 targetWorldPos
|
||||
var coinScript = award.GetComponent<CoinScript>();
|
||||
var endTra = new GameObject("CoinEndPoint_Random").transform;
|
||||
endTra.position = targetWorldPos;
|
||||
endTra.parent = coinScript.transform;
|
||||
|
||||
coinScript.endPoint = endTra;
|
||||
coinScript.Init(coinNum.Amount, targetWorldPos);
|
||||
coinScript.isBoss = true;
|
||||
coinScript.SetCoinCount(coinNum.Amount);
|
||||
coinScript.SetCoinCount();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 收到服务器 WebSocket 杀鱼通知,处理金币加分、特效、音效。
|
||||
@@ -1315,95 +1476,158 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
.arguments[0];
|
||||
|
||||
Debug.Log($"[CreateFishManager] 杀鱼延迟:{DateTimeOffset.Now.ToUnixTimeSeconds() - killFish.timespan}s");
|
||||
SitPosData sitData = null; //击杀玩家座位数据
|
||||
foreach (var item in currGameType.list_Sits)
|
||||
{
|
||||
if (item.user == killFish.userId)
|
||||
{
|
||||
item.monCotl_Lock = null;
|
||||
//item.lockFX.gameObject.SetActive(false);
|
||||
sitData = item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!fishDatas_hashCodekey.TryGetValue(killFish.fishId, out var monster)) return;
|
||||
monster.DieFish(killFish);
|
||||
// 加分回调(在金币飞完后执行)
|
||||
Action<int> onScoreAdd = audioID =>
|
||||
{
|
||||
var sitList = GetCurrentPanelSitList();
|
||||
if (sitList != null)
|
||||
{
|
||||
foreach (var sit in sitList)
|
||||
{
|
||||
if (sit.user != null && sit.user == killFish.userId)
|
||||
{
|
||||
sit.goldNum += killFish.gold;
|
||||
sit.tMP_GoldNum.text = sit.goldNum.ToString();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
AudioManager.Instance.PlayerFX(audioID);
|
||||
};
|
||||
|
||||
// 死亡粒子特效
|
||||
Instantiate(
|
||||
monster.effect_Die != null ? monster.effect_Die : dieFXPrefab,
|
||||
monster.transform.position, Quaternion.identity, transform.parent);
|
||||
|
||||
if (monster.fishenum != FishTypeEnum.Boss鱼)
|
||||
// 加分回调(在金币/加分面板飞完后执行)
|
||||
Action<int> onScoreAdd = audioID =>
|
||||
{
|
||||
// 普通鱼:金币飞向炮台
|
||||
var award = Instantiate(
|
||||
monster.effect_DieAward != null ? monster.effect_DieAward : dieFXPrefabAward,
|
||||
currGameType.subPanelParent.parent);
|
||||
try
|
||||
{
|
||||
award.GetComponent<RectTransform>().anchoredPosition =
|
||||
CoordinateTransformation.WorldPos_ToCanvas(
|
||||
monster.transform.position,
|
||||
UIManager.Instance.uiRoot.GetComponent<Canvas>());
|
||||
}
|
||||
catch
|
||||
{
|
||||
award.transform.position = monster.transform.position;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
var coinScript = award.GetComponent<BJBase>();
|
||||
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;
|
||||
}
|
||||
else
|
||||
var sitList = GetCurrentPanelSitList();
|
||||
sitData.goldNum += killFish.gold;
|
||||
sitData.tMP_GoldNum.text = sitData.goldNum.ToString();
|
||||
AudioManager.Instance.PlayerFX(audioID);
|
||||
};
|
||||
switch (monster.fishenum)
|
||||
{
|
||||
// Boss 鱼:显示浮动分数文本
|
||||
var bossCtrl = (MonsterControl_BossBase)monster;
|
||||
foreach (var item in currGameType.list_Sits)
|
||||
{
|
||||
if (killFish.userId == item.user)
|
||||
case FishTypeEnum.普通鱼:
|
||||
{
|
||||
bossCtrl.v3 = item.transform.position;
|
||||
// 普通鱼:金币飞向炮台
|
||||
var award = Instantiate(
|
||||
monster.effect_DieAward != null ? monster.effect_DieAward : dieFXPrefabAward,
|
||||
currGameType.subPanelParent.parent);
|
||||
try
|
||||
{
|
||||
award.GetComponent<RectTransform>().anchoredPosition =
|
||||
CoordinateTransformation.WorldPos_ToCanvas(
|
||||
monster.transform.position,
|
||||
UIManager.Instance.uiRoot.GetComponent<Canvas>());
|
||||
}
|
||||
catch
|
||||
{
|
||||
award.transform.position = monster.transform.position;
|
||||
|
||||
}
|
||||
|
||||
|
||||
var coinScript = award.GetComponent<BJBase>();
|
||||
coinScript.Init(killFish.gold, sitData.transform.position, killFish.userId, sitData.posID, killFish.param);
|
||||
|
||||
coinScript.isBoss = false;
|
||||
coinScript.SetCoinCount();
|
||||
coinScript.JiaFen = onScoreAdd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bossCtrl.currEffect_DieAward = Instantiate(
|
||||
monster.effect_DieAward != null ? monster.effect_DieAward : dieFXPrefabAwardTmp,
|
||||
currGameType.subPanelParent.parent);
|
||||
bossCtrl.action_effect_DieAward?.Invoke(bossCtrl.currEffect_DieAward);
|
||||
bossCtrl.JiaFen = onScoreAdd;
|
||||
case FishTypeEnum.Boss鱼:
|
||||
{
|
||||
// Boss 鱼:显示浮动分数文本
|
||||
var bossCtrl = (MonsterControl_BossBase)monster;
|
||||
|
||||
bossCtrl.v3 = sitData.transform.position;
|
||||
|
||||
bossCtrl.currEffect_DieAward = Instantiate(
|
||||
monster.effect_DieAward != null ? monster.effect_DieAward : dieFXPrefabAwardTmp,
|
||||
currGameType.subPanelParent.parent);
|
||||
bossCtrl.action_effect_DieAward?.Invoke(bossCtrl.currEffect_DieAward);
|
||||
bossCtrl.JiaFen = onScoreAdd;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case FishTypeEnum.黄金鱼:
|
||||
{
|
||||
// 普通鱼:金币飞向炮台
|
||||
var award = Instantiate(
|
||||
monster.effect_DieAward != null ? monster.effect_DieAward : dieFXPrefabAward,
|
||||
currGameType.subPanelParent.parent);
|
||||
try
|
||||
{
|
||||
award.GetComponent<RectTransform>().anchoredPosition =
|
||||
CoordinateTransformation.WorldPos_ToCanvas(
|
||||
monster.transform.position,
|
||||
UIManager.Instance.uiRoot.GetComponent<Canvas>());
|
||||
}
|
||||
catch
|
||||
{
|
||||
award.transform.position = monster.transform.position;
|
||||
|
||||
}
|
||||
|
||||
|
||||
var coinScript = award.GetComponent<BJBase>();
|
||||
coinScript.Init(killFish.gold, sitData.transform.position, killFish.userId, sitData.posID, killFish.param);
|
||||
|
||||
coinScript.isBoss = false;
|
||||
coinScript.SetCoinCount();
|
||||
coinScript.JiaFen = onScoreAdd;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case FishTypeEnum.特殊鱼:
|
||||
{
|
||||
// 普通鱼:金币飞向炮台
|
||||
var award = Instantiate(
|
||||
monster.effect_DieAward != null ? monster.effect_DieAward : dieFXPrefabAward,
|
||||
currGameType.subPanelParent.parent);
|
||||
try
|
||||
{
|
||||
award.GetComponent<RectTransform>().anchoredPosition =
|
||||
CoordinateTransformation.WorldPos_ToCanvas(
|
||||
monster.transform.position,
|
||||
UIManager.Instance.uiRoot.GetComponent<Canvas>());
|
||||
}
|
||||
catch
|
||||
{
|
||||
award.transform.position = monster.transform.position;
|
||||
|
||||
}
|
||||
|
||||
|
||||
var coinScript = award.GetComponent<BJBase>();
|
||||
coinScript.Init(killFish.gold, sitData.transform.position, killFish.userId, sitData.posID, killFish.param);
|
||||
|
||||
coinScript.isBoss = false;
|
||||
coinScript.SetCoinCount();
|
||||
coinScript.JiaFen = onScoreAdd;
|
||||
|
||||
}
|
||||
break;
|
||||
case FishTypeEnum.特殊Boss:
|
||||
{
|
||||
// Boss 鱼:显示浮动分数文本
|
||||
var bossCtrl = (MonsterControl_BossBase)monster;
|
||||
|
||||
bossCtrl.v3 = sitData.transform.position;
|
||||
|
||||
bossCtrl.currEffect_DieAward = Instantiate(
|
||||
monster.effect_DieAward != null ? monster.effect_DieAward : dieFXPrefabAwardTmp,
|
||||
currGameType.subPanelParent.parent);
|
||||
bossCtrl.action_effect_DieAward?.Invoke(bossCtrl.currEffect_DieAward);
|
||||
bossCtrl.JiaFen = onScoreAdd;
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
MonsterDieList.Instance.SmallHuangYiHuang(
|
||||
monster.transform.position,
|
||||
monster.monsterData.fishTypeConfig.fishNumber, 1000);
|
||||
|
||||
@@ -9,6 +9,7 @@ public enum TurretAnimType
|
||||
animator = 3
|
||||
}
|
||||
|
||||
|
||||
public enum TurretState
|
||||
{
|
||||
None = 0,
|
||||
@@ -20,6 +21,7 @@ public enum TurretState
|
||||
LaserEnd = 5
|
||||
}
|
||||
|
||||
|
||||
public class TurretData : MonoBehaviour
|
||||
{
|
||||
[Header("基础")]
|
||||
@@ -35,11 +37,13 @@ public class TurretData : MonoBehaviour
|
||||
public Animator new_CurrAnimation;
|
||||
public TurretAnimType currTurretType;
|
||||
public bool isFrenzy=false;
|
||||
|
||||
|
||||
[Header("动画名")]
|
||||
public string idleAnim;
|
||||
public string attackAnim;
|
||||
// 新增:狂暴专用攻击动画(已经是二倍速帧动画)
|
||||
public string frenzyAttackAnim;
|
||||
private bool useFrenzyAnim = false;
|
||||
|
||||
|
||||
public string laserStartAnim;
|
||||
public string laserLoopAnim;
|
||||
@@ -51,6 +55,9 @@ public class TurretData : MonoBehaviour
|
||||
{
|
||||
if (setPosData != null)
|
||||
setPosData.OnStateChange = ChangeState;
|
||||
|
||||
// 自动判断:如果狂暴攻击动画名不为空,就启用切换动画模式
|
||||
useFrenzyAnim = !string.IsNullOrEmpty(frenzyAttackAnim);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
@@ -88,19 +95,41 @@ public class TurretData : MonoBehaviour
|
||||
{
|
||||
isFrenzy = value;
|
||||
|
||||
if (skeletonAnimation != null)
|
||||
skeletonAnimation.timeScale = isFrenzy ? 2f : 1f;
|
||||
|
||||
if (new_CurrAnimation != null)
|
||||
new_CurrAnimation.speed = isFrenzy ? 2f : 1f;
|
||||
|
||||
if (old_CurrAnimation != null)
|
||||
if (!useFrenzyAnim) // 没有狂暴动画 → 用速度加倍
|
||||
{
|
||||
foreach (AnimationState state in old_CurrAnimation)
|
||||
state.speed = isFrenzy ? 2f : 1f;
|
||||
float speed = isFrenzy ? 2f : 1f;
|
||||
|
||||
if (skeletonAnimation != null)
|
||||
skeletonAnimation.timeScale = speed;
|
||||
|
||||
if (new_CurrAnimation != null)
|
||||
new_CurrAnimation.speed = speed;
|
||||
|
||||
if (old_CurrAnimation != null)
|
||||
{
|
||||
foreach (AnimationState state in old_CurrAnimation)
|
||||
state.speed = speed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 有狂暴动画 → 不做速度调整,保持 1 倍速
|
||||
if (skeletonAnimation != null)
|
||||
skeletonAnimation.timeScale = 1f;
|
||||
|
||||
if (new_CurrAnimation != null)
|
||||
new_CurrAnimation.speed = 1f;
|
||||
|
||||
if (old_CurrAnimation != null)
|
||||
{
|
||||
foreach (AnimationState state in old_CurrAnimation)
|
||||
state.speed = 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ChangeState(TurretState newState)
|
||||
{
|
||||
if (currState == newState) return;
|
||||
@@ -134,26 +163,24 @@ public class TurretData : MonoBehaviour
|
||||
string anim = state switch
|
||||
{
|
||||
TurretState.Idle => idleAnim,
|
||||
TurretState.Attack => attackAnim,
|
||||
|
||||
TurretState.Attack => (isFrenzy && useFrenzyAnim) ? frenzyAttackAnim : attackAnim,
|
||||
TurretState.LaserStart => laserStartAnim,
|
||||
TurretState.LaserLoop => laserLoopAnim,
|
||||
TurretState.LaserEnd => laserEndAnim,
|
||||
|
||||
_ => idleAnim
|
||||
};
|
||||
|
||||
bool loop = state == TurretState.Attack || state == TurretState.LaserLoop;
|
||||
|
||||
skeletonAnimation.AnimationState.SetAnimation(0, anim, loop);
|
||||
|
||||
// 激光开始 → 自动进入 Loop
|
||||
if (state == TurretState.LaserStart)
|
||||
{
|
||||
skeletonAnimation.AnimationState.AddAnimation(0, laserLoopAnim, true, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void PlayLegacy(TurretState state)
|
||||
{
|
||||
if (old_CurrAnimation == null) return;
|
||||
@@ -161,22 +188,29 @@ public class TurretData : MonoBehaviour
|
||||
string anim = state switch
|
||||
{
|
||||
TurretState.Idle => idleAnim,
|
||||
TurretState.Attack => attackAnim,
|
||||
|
||||
TurretState.Attack => (isFrenzy && useFrenzyAnim) ? frenzyAttackAnim : attackAnim,
|
||||
TurretState.LaserStart => laserStartAnim,
|
||||
TurretState.LaserLoop => laserLoopAnim,
|
||||
TurretState.LaserEnd => laserEndAnim,
|
||||
|
||||
_ => idleAnim
|
||||
};
|
||||
|
||||
old_CurrAnimation.Play(anim);
|
||||
}
|
||||
|
||||
|
||||
private void PlayAnimator(TurretState state)
|
||||
{
|
||||
if (new_CurrAnimation == null) return;
|
||||
|
||||
new_CurrAnimation.SetInteger("State", (int)state);
|
||||
if (state == TurretState.Attack && isFrenzy && useFrenzyAnim)
|
||||
{
|
||||
new_CurrAnimation.SetTrigger("FrenzyAttack");
|
||||
}
|
||||
else
|
||||
{
|
||||
new_CurrAnimation.SetInteger("State", (int)state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ZhanShenTurret : TurretData
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using Newtonsoft.Json;
|
||||
using Spine.Unity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using static UnityEngine.AddressableAssets.Addressables;
|
||||
|
||||
[Serializable]
|
||||
public class TurretResourcesData
|
||||
{
|
||||
public int turretNumber;
|
||||
public int turretType; // 1普通炮台 2战神 3翅膀
|
||||
public string prefabTurretResourcesPath;
|
||||
public int animationType; // 1spine 2animator 3animation
|
||||
public int attackAudio;
|
||||
|
||||
const string prefabTurret_AALabel = "TurretPrefab";
|
||||
const string turretSpine_AALabel = "TurretSpine";
|
||||
const string turretSprite_AALabel = "TurretSprite";
|
||||
|
||||
private static Dictionary<string, int> TurretPrefabsDic; // prefabPath -> id
|
||||
private static Dictionary<string, int> TurretSpineDic; // spinePath -> id
|
||||
private static Dictionary<string, int> TurretSpriteDic; // spritePath -> id
|
||||
|
||||
public static Dictionary<int, TurretResourcesData> turretResourcesDatasDic; // id -> data
|
||||
private static Dictionary<int, GameObject> turretPrefabDic; // id -> prefab
|
||||
private static Dictionary<int, Sprite> turretSpriteDic; // id -> sprite
|
||||
|
||||
static TurretResourcesData()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
async static void Init()
|
||||
{
|
||||
string turretPath = Resources.Load<TextAsset>("tbTurretResources").text;
|
||||
var list = JsonConvert.DeserializeObject<List<TurretResourcesData>>(turretPath);
|
||||
|
||||
TurretPrefabsDic = new Dictionary<string, int>();
|
||||
TurretSpineDic = new Dictionary<string, int>();
|
||||
TurretSpriteDic = new Dictionary<string, int>();
|
||||
turretResourcesDatasDic = new Dictionary<int, TurretResourcesData>();
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.prefabTurretResourcesPath))
|
||||
{
|
||||
TurretPrefabsDic[item.prefabTurretResourcesPath] = item.turretNumber;
|
||||
TurretSpriteDic[item.prefabTurretResourcesPath] = item.turretNumber;
|
||||
turretResourcesDatasDic[item.turretNumber] = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task LoadTurretAssetsData()
|
||||
{
|
||||
turretPrefabDic = new Dictionary<int, GameObject>();
|
||||
turretSpriteDic = new Dictionary<int, Sprite>();
|
||||
|
||||
var labels = new List<string>
|
||||
{
|
||||
prefabTurret_AALabel,
|
||||
turretSpine_AALabel,
|
||||
turretSprite_AALabel,
|
||||
GameManager.Instance.gameData.currGameType.ToString()
|
||||
};
|
||||
|
||||
Debug.Log("开始预下载炮台资源依赖...");
|
||||
var depHandle = Addressables.DownloadDependenciesAsync(labels, MergeMode.Intersection);
|
||||
await depHandle.Task;
|
||||
Addressables.Release(depHandle);
|
||||
Debug.Log("炮台依赖资源预下载完成!");
|
||||
|
||||
// ---------------- 1. 加载炮台 Prefab ----------------
|
||||
var prefabKeys = new List<string> { prefabTurret_AALabel, GameManager.Instance.gameData.currGameType.ToString() };
|
||||
var prefabHandle = Addressables.LoadAssetsAsync<GameObject>(prefabKeys, prefab =>
|
||||
{
|
||||
if (TurretPrefabsDic.TryGetValue(prefab.name, out int id))
|
||||
{
|
||||
turretPrefabDic[id] = prefab;
|
||||
}
|
||||
}, MergeMode.Intersection);
|
||||
|
||||
await prefabHandle.Task;
|
||||
Addressables.Release(prefabHandle);
|
||||
Debug.Log($"炮台 Prefab 加载完成,共 {turretPrefabDic.Count} 个");
|
||||
// ---------------- 3. 加载炮台 Sprite ----------------
|
||||
var spriteKeys = new List<string> { turretSprite_AALabel, GameManager.Instance.gameData.currGameType.ToString() };
|
||||
var spriteHandle = Addressables.LoadAssetsAsync<Sprite>(spriteKeys, data =>
|
||||
{
|
||||
if (TurretSpriteDic.TryGetValue(data.name, out int id))
|
||||
{
|
||||
turretSpriteDic[id] = data;
|
||||
}
|
||||
}, MergeMode.Intersection);
|
||||
|
||||
await spriteHandle.Task;
|
||||
Addressables.Release(spriteHandle);
|
||||
Debug.Log($"炮台 Sprite 加载完成,共 {turretSpriteDic.Count} 个");
|
||||
|
||||
Debug.Log("所有炮台资源加载完毕!");
|
||||
}
|
||||
|
||||
public static GameObject GetTurretPrefab(int turretNumber)
|
||||
{
|
||||
return turretPrefabDic.TryGetValue(turretNumber, out var prefab) ? prefab : null;
|
||||
}
|
||||
public static Sprite GetTurretSprite(int turretNumber)
|
||||
{
|
||||
return turretSpriteDic.TryGetValue(turretNumber, out var sprite) ? sprite : null;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77cc7a80613454948b89c32d4269f8c9
|
||||
guid: 796504e4488d4a842af7e183e6124ff9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
Reference in New Issue
Block a user