飞机场存档
This commit is contained in:
@@ -5,6 +5,15 @@ using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>炮台控制模式</summary>
|
||||
public enum TurretControlMode
|
||||
{
|
||||
/// <summary>普通模式:动态克隆炮台,显示金币+钻石,按钮打开面板切换</summary>
|
||||
Normal = 0,
|
||||
/// <summary>星际迷航模式:座位子对象激活/停用,只显示金币,长按炮台弹出扇形切换</summary>
|
||||
XJMH = 1
|
||||
}
|
||||
|
||||
public class SitPosData : MonoBehaviour
|
||||
{
|
||||
/// <summary>本地玩家的座位引用(由游戏面板初始化时设置)</summary>
|
||||
@@ -41,6 +50,10 @@ public class SitPosData : MonoBehaviour
|
||||
[Tooltip("炮台实例化的父节点")]
|
||||
public Transform turretParent;
|
||||
|
||||
[Header("炮台控制模式")]
|
||||
[Tooltip("Normal=普通模式(动态克隆炮台,显示金币+钻石,按钮切换); XJMH=星际迷航模式(座位子对象激活/停用,只显示金币,长按扇形切换)")]
|
||||
public TurretControlMode turretControlMode = TurretControlMode.Normal;
|
||||
|
||||
[Tooltip("炮台锚点位置(相对 turretParent)")]
|
||||
public Vector2 turretAnchoredPos = Vector2.zero;
|
||||
|
||||
@@ -50,6 +63,14 @@ public class SitPosData : MonoBehaviour
|
||||
/// <summary>当前运行中的炮台实例</summary>
|
||||
public TurretData currentTurret;
|
||||
|
||||
// -------------------------
|
||||
// XJMH 炮台列表(星际迷航专用)
|
||||
// -------------------------
|
||||
[Header("XJMH 炮台列表")]
|
||||
[Tooltip("XJMH 模式专用:在 Inspector 中拖入座位下的所有炮台子对象(带 TurretData 组件)。" +
|
||||
"数量不多,建议按炮台编号升序排列,便于扇形切换按索引选择。")]
|
||||
public List<TurretData> xjmhTurretList = new List<TurretData>();
|
||||
|
||||
// 状态机入口(GameMainPanel 调用)
|
||||
public Action<TurretState> OnStateChange;
|
||||
|
||||
@@ -90,8 +111,63 @@ public class SitPosData : MonoBehaviour
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
btn_TurretAdd.onClick.AddListener(() => ChangeTurretAddConsumeNum());
|
||||
btn_TurretMinus.onClick.AddListener(() => ChangeTurretMinusConsumeNum());
|
||||
if (btn_TurretAdd != null)
|
||||
btn_TurretAdd.onClick.AddListener(() => ChangeTurretAddConsumeNum());
|
||||
if (btn_TurretMinus != null)
|
||||
btn_TurretMinus.onClick.AddListener(() => ChangeTurretMinusConsumeNum());
|
||||
|
||||
// XJMH 模式:隐藏钻石显示(只显示金币)
|
||||
if (turretControlMode == TurretControlMode.XJMH && tMP_DiamondNum != null)
|
||||
tMP_DiamondNum.gameObject.SetActive(false);
|
||||
|
||||
// XJMH 模式:炮台是座位自带子对象,预制体里已摆好,不需要加载。
|
||||
// 这里只做引用初始化,不做激活/停用。
|
||||
if (turretControlMode == TurretControlMode.XJMH)
|
||||
InitXJMHTurret();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XJMH 模式:炮台是座位自带子对象,预制体里已摆好激活状态,不需要 LoadTurret 加载。
|
||||
/// 此方法只做引用初始化:从 <see cref="xjmhTurretList"/> 取第一个激活的炮台赋给 currentTurret,
|
||||
/// 并绑定旋转节点、状态机入口、世界坐标缓存。不做任何激活/停用操作。
|
||||
/// </summary>
|
||||
private void InitXJMHTurret()
|
||||
{
|
||||
if (xjmhTurretList == null || xjmhTurretList.Count == 0)
|
||||
{
|
||||
Debug.LogWarning($"[SitPosData] XJMH 炮台列表未配置,座位 {posID} 无炮台可用");
|
||||
return;
|
||||
}
|
||||
|
||||
// 优先取列表中第一个激活的炮台;若全部未激活,取 list[0]
|
||||
TurretData found = null;
|
||||
foreach (var td in xjmhTurretList)
|
||||
{
|
||||
if (td == null) continue;
|
||||
if (td.gameObject.activeSelf)
|
||||
{
|
||||
found = td;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == null)
|
||||
{
|
||||
found = xjmhTurretList[0];
|
||||
found.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
currentTurret = found;
|
||||
currentTurretNumber = found.turretNumber;
|
||||
|
||||
Transform parent = turretParent != null ? turretParent : transform;
|
||||
tra_CurrTurret = currentTurret.transform.parent != parent
|
||||
? currentTurret.transform.parent
|
||||
: currentTurret.transform;
|
||||
|
||||
OnStateChange = currentTurret.ChangeState;
|
||||
UpdateTurretWorldPos();
|
||||
|
||||
Debug.Log($"[SitPosData] XJMH 炮台引用已初始化: #{currentTurretNumber}");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
@@ -127,13 +203,17 @@ public class SitPosData : MonoBehaviour
|
||||
{
|
||||
localPlayerSit = this;
|
||||
|
||||
var cannonUsing = GameManager.Instance.user.cannonUsing;
|
||||
if (cannonUsing != null && int.TryParse(cannonUsing.number, out int num))
|
||||
LoadTurret(num);
|
||||
// XJMH 模式:炮台是座位自带子对象,Awake 已初始化引用,不需要加载
|
||||
if (turretControlMode != TurretControlMode.XJMH)
|
||||
{
|
||||
var cannonUsing = GameManager.Instance.user.cannonUsing;
|
||||
if (cannonUsing != null && int.TryParse(cannonUsing.number, out int num))
|
||||
LoadTurret(num);
|
||||
|
||||
var wingUsing = GameManager.Instance.user.wingUsing;
|
||||
if (wingUsing != null && int.TryParse(wingUsing.number, out int wingNum))
|
||||
LoadWing(wingNum);
|
||||
var wingUsing = GameManager.Instance.user.wingUsing;
|
||||
if (wingUsing != null && int.TryParse(wingUsing.number, out int wingNum))
|
||||
LoadWing(wingNum);
|
||||
}
|
||||
}
|
||||
|
||||
// 非人机玩家加入时,自动分配为首个房主
|
||||
@@ -177,13 +257,28 @@ public class SitPosData : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 炮台加载(动态克隆) ====================
|
||||
// ==================== 炮台加载 ====================
|
||||
|
||||
/// <summary>
|
||||
/// 根据炮台编号,从 Addressables 加载预制体并克隆到 turretParent。
|
||||
/// 位置/旋转/缩放保持预制体原始值,不动。
|
||||
/// 根据炮台编号加载炮台。
|
||||
/// Normal 模式:从 Addressables 加载预制体并克隆到 turretParent。
|
||||
/// XJMH 模式:炮台是座位子对象,激活对应编号子对象、停用其他。
|
||||
/// </summary>
|
||||
public void LoadTurret(int turretNumber)
|
||||
{
|
||||
if (turretControlMode == TurretControlMode.XJMH)
|
||||
{
|
||||
SwitchTurretChild(turretNumber);
|
||||
return;
|
||||
}
|
||||
LoadTurretNormal(turretNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 普通模式:从 Addressables 加载预制体并克隆到 turretParent。
|
||||
/// 位置/旋转/缩放保持预制体原始值,不动。
|
||||
/// </summary>
|
||||
private void LoadTurretNormal(int turretNumber)
|
||||
{
|
||||
// ⭐ 换炮台时只清活跃子弹(清屏),保留池缓存(同 prefab 能复用)
|
||||
// 用 ClearActive 而非 ClearAll:ClearAll 会清池导致永远不复用
|
||||
@@ -225,17 +320,153 @@ public class SitPosData : MonoBehaviour
|
||||
currentTurret.turretNumber = turretNumber;
|
||||
|
||||
// 缓存旋转节点
|
||||
//tra_CurrTurret = currentTurret.transform.GetChild(0);
|
||||
tra_CurrTurret = currentTurret.transform.parent;
|
||||
|
||||
// 绑定状态机入口
|
||||
OnStateChange = currentTurret.ChangeState;
|
||||
|
||||
// ⭐ 缓存炮台在世界坐标(Z=0平面)的位置,bot AI/锁定检测距离时用
|
||||
// 和子弹起点(GetBulletStartWorldPos)用相同的 UI→世界 转换方式
|
||||
UpdateTurretWorldPos();
|
||||
|
||||
Debug.Log($"[SitPosData] 炮台已加载: #{turretNumber}");
|
||||
Debug.Log($"[SitPosData] 炮台已加载(Normal): #{turretNumber}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XJMH 模式:炮台都是座位的子对象,激活对应编号的炮台、停用其他。
|
||||
/// 不需要 Instantiate/Destroy,只做激活/停用,无需额外处理。
|
||||
/// 优先从 <see cref="xjmhTurretList"/> 查找,列表为空时回退遍历子对象。
|
||||
/// </summary>
|
||||
private void SwitchTurretChild(int turretNumber)
|
||||
{
|
||||
BulletPool.Instance.ClearActive();
|
||||
|
||||
// 炮台挂载根:turretParent 优先,否则用座位自身
|
||||
Transform parent = turretParent != null ? turretParent : transform;
|
||||
|
||||
// 优先用 Inspector 配置的炮台列表
|
||||
TurretData found = null;
|
||||
if (xjmhTurretList != null && xjmhTurretList.Count > 0)
|
||||
{
|
||||
foreach (var td in xjmhTurretList)
|
||||
{
|
||||
if (td == null) continue;
|
||||
bool active = td.turretNumber == turretNumber;
|
||||
td.gameObject.SetActive(active);
|
||||
if (active) found = td;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 回退:列表未配置时遍历子对象
|
||||
for (int i = 0; i < parent.childCount; i++)
|
||||
{
|
||||
var child = parent.GetChild(i);
|
||||
var td = child.GetComponent<TurretData>();
|
||||
if (td == null) continue;
|
||||
|
||||
if (td.turretNumber == turretNumber)
|
||||
{
|
||||
child.gameObject.SetActive(true);
|
||||
found = td;
|
||||
}
|
||||
else
|
||||
{
|
||||
child.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found == null)
|
||||
{
|
||||
Debug.LogWarning($"[SitPosData] XJMH 子对象中未找到炮台 #{turretNumber}");
|
||||
return;
|
||||
}
|
||||
|
||||
currentTurretNumber = turretNumber;
|
||||
currentTurret = found;
|
||||
// 炮台若挂在中间旋转容器下,用容器作为旋转节点;否则用炮台自身
|
||||
tra_CurrTurret = currentTurret.transform.parent != parent
|
||||
? currentTurret.transform.parent
|
||||
: currentTurret.transform;
|
||||
|
||||
OnStateChange = currentTurret.ChangeState;
|
||||
UpdateTurretWorldPos();
|
||||
|
||||
Debug.Log($"[SitPosData] 炮台已切换(XJMH): #{turretNumber}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XJMH 模式:按列表索引直接切换炮台。
|
||||
/// 用于扇形切换 UI 中按位置选择炮台,避免再做编号匹配。
|
||||
/// </summary>
|
||||
/// <param name="index">xjmhTurretList 中的索引</param>
|
||||
/// <returns>切换成功返回 true;索引越界或列表为空返回 false</returns>
|
||||
public bool SwitchTurretByIndex(int index)
|
||||
{
|
||||
if (turretControlMode != TurretControlMode.XJMH) return false;
|
||||
if (xjmhTurretList == null || index < 0 || index >= xjmhTurretList.Count) return false;
|
||||
|
||||
var td = xjmhTurretList[index];
|
||||
if (td == null) return false;
|
||||
|
||||
// 命中当前炮台则无需切换
|
||||
if (td.turretNumber == currentTurretNumber) return true;
|
||||
|
||||
SwitchTurretChild(td.turretNumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XJMH 模式:根据当前炮台在 xjmhTurretList 中的索引返回下一个炮台编号。
|
||||
/// 用于"切换到下一把"的快捷操作。循环切换,列表为空返回 -1。
|
||||
/// </summary>
|
||||
public int GetNextTurretNumber()
|
||||
{
|
||||
if (turretControlMode != TurretControlMode.XJMH) return -1;
|
||||
if (xjmhTurretList == null || xjmhTurretList.Count == 0) return -1;
|
||||
|
||||
int currIdx = xjmhTurretList.FindIndex(td => td != null && td.turretNumber == currentTurretNumber);
|
||||
if (currIdx < 0) return xjmhTurretList[0].turretNumber;
|
||||
|
||||
int nextIdx = (currIdx + 1) % xjmhTurretList.Count;
|
||||
return xjmhTurretList[nextIdx].turretNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前可用的炮台编号列表。
|
||||
/// Normal 模式:从资源表按类型查询。
|
||||
/// XJMH 模式:优先从 <see cref="xjmhTurretList"/> 读取,列表为空时回退扫描座位子对象。
|
||||
/// </summary>
|
||||
public List<int> GetAvailableTurretNumbers()
|
||||
{
|
||||
var result = new List<int>();
|
||||
if (turretControlMode == TurretControlMode.XJMH)
|
||||
{
|
||||
// 优先用配置的炮台列表
|
||||
if (xjmhTurretList != null && xjmhTurretList.Count > 0)
|
||||
{
|
||||
foreach (var td in xjmhTurretList)
|
||||
if (td != null) result.Add(td.turretNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 回退:扫描座位子对象
|
||||
Transform parent = turretParent != null ? turretParent : transform;
|
||||
for (int i = 0; i < parent.childCount; i++)
|
||||
{
|
||||
var td = parent.GetChild(i).GetComponent<TurretData>();
|
||||
if (td != null)
|
||||
result.Add(td.turretNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var list = TurretResourcesData.GetTurretDataByType(1);
|
||||
if (list != null)
|
||||
result = list.ConvertAll(d => d.turretNumber);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -286,6 +517,9 @@ public class SitPosData : MonoBehaviour
|
||||
/// </summary>
|
||||
public void LoadWing(int turretNumber)
|
||||
{
|
||||
// XJMH 模式没有翅膀概念,直接跳过
|
||||
if (turretControlMode == TurretControlMode.XJMH) return;
|
||||
|
||||
// 先清理已有翅膀(保留预设的 Camera,它是用来渲染翅膀到 RawImage 的)
|
||||
for (int i = wingParent.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user