using System; using System.Collections.Generic; using System.Linq; using TMPro; using UnityEngine; using UnityEngine.UI; public class SitPosData : MonoBehaviour { /// 本地玩家的座位引用(由游戏面板初始化时设置) public static SitPosData localPlayerSit; /// 当前房间房主座位(人机请求由房主发送,房主退出后自动继承) public static SitPosData roomOwnerSit; // ------------------------- // 玩家基础信息 // ------------------------- [Header("玩家信息")] public string user; [Tooltip("座位编号 0~3。0,1=下方 2,3=上方")] public int posID; [Tooltip("是否为人机")] public bool isBot = false; /// posID>=2 = 上方,需要翻转(0,1=下方;2,3=上方) public bool IsFlipped => posID >= 2; [Header("金币")] public long goldNum; public long consumeGoldNum; public TextMeshProUGUI tMP_GoldNum; public TextMeshProUGUI tMP_TurretConsumeNum; // ------------------------- // 炮台管理(动态克隆) // ------------------------- [Header("炮台")] [Tooltip("炮台实例化的父节点")] public Transform turretParent; [Tooltip("炮台锚点位置(相对 turretParent)")] public Vector2 turretAnchoredPos = Vector2.zero; [Tooltip("当前装备的炮台编号")] public int currentTurretNumber; /// 当前运行中的炮台实例 public TurretData currentTurret; // 状态机入口(GameMainPanel 调用) public Action OnStateChange; // ------------------------- // 炮台旋转 // ------------------------- [Header("炮台旋转")] public Transform tra_CurrTurret; public float currentAngle; // ------------------------- // 锁定系统 // ------------------------- [Header("锁定系统")] public MonsterContral monCotl_Lock; public Transform monCotl_Lock_Position; public bool isLock = false; public GameObject lockFX; // ------------------------- // UI // ------------------------- [Header("UI")] public Button btn_TurretAdd; public Button btn_TurretMinus; private void Awake() { btn_TurretAdd.onClick.AddListener(() => ChangeTurretAddConsumeNum()); btn_TurretMinus.onClick.AddListener(() => ChangeTurretMinusConsumeNum()); } private void OnEnable() { // 如果是本地玩家的座位,自动注册为 localPlayerSit if (user == GameManager.Instance?.user?.id) { localPlayerSit = this; // 加载玩家当前装备的炮台 var cannonUsing = GameManager.Instance.user.cannonUsing; if (cannonUsing != null && int.TryParse(cannonUsing.number, out int num)) LoadTurret(num); } } private void OnDisable() { if (localPlayerSit == this) localPlayerSit = null; // 房主退出 → 自动继承给第一个非人机玩家 if (roomOwnerSit == this) { roomOwnerSit = null; TransferRoomOwner(); } } /// 房主退出后,将房主身份转移给第一个活跃的非人机玩家 public static void TransferRoomOwner() { var list = FindObjectsOfType(); foreach (var sit in list) { if (!sit.isBot && sit.gameObject.activeInHierarchy && sit != roomOwnerSit) { roomOwnerSit = sit; break; } } } /// 分配房主(首个非人机玩家) public static void AssignRoomOwner(SitPosData sit) { if (roomOwnerSit == null && !sit.isBot) roomOwnerSit = sit; } // ==================== 炮台加载(动态克隆) ==================== /// /// 根据炮台编号,从 Addressables 加载预制体并克隆到 turretParent。 /// 位置/旋转/缩放保持预制体原始值,不动。 /// public void LoadTurret(int turretNumber) { if (currentTurret != null) { Destroy(currentTurret.gameObject); currentTurret = null; } currentTurretNumber = turretNumber; // 从 TurretResourcesData 拿预制体 GameObject prefab = TurretResourcesData.GetTurretPrefab(turretNumber); if (prefab == null) { Debug.LogWarning($"[SitPosData] 炮台预制体未加载: #{turretNumber}"); return; } // 克隆到父节点 GameObject instance = Instantiate(prefab, turretParent, false); instance.SetActive(true); // 固定位置归零,由外部父节点定位 var rt = instance.GetComponent(); if (rt != null) rt.anchoredPosition = turretAnchoredPos; currentTurret = instance.GetComponent(); if (currentTurret == null) { Debug.LogError($"[SitPosData] 预制体上未找到 TurretData 组件: #{turretNumber}"); Destroy(instance); return; } currentTurret.turretNumber = turretNumber; // 缓存旋转节点 tra_CurrTurret = currentTurret.transform.GetChild(0); // 绑定状态机入口 OnStateChange = currentTurret.ChangeState; Debug.Log($"[SitPosData] 炮台已加载: #{turretNumber}"); } /// 根据炮台编号字符串加载。 public void LoadTurret(string turretNumberStr) { if (int.TryParse(turretNumberStr, out int num)) LoadTurret(num); } // ------------------------- // 切换状态(GameMainPanel 调用) // ------------------------- public void ChangeState(TurretState state) { OnStateChange?.Invoke(state); } // ------------------------- // 炮台旋转(GameMainPanel 调用) // ------------------------- public void SetRotation(float angle) { currentAngle = angle; if (tra_CurrTurret != null) tra_CurrTurret.rotation = Quaternion.Euler(0, 0, angle); } // ------------------------- // 获取发射点(给 GameMainPanel) // ------------------------- public Vector2 GetBulletStartPos() { return currentTurret != null ? currentTurret.GetBulletStartWorldPos() : Vector2.zero; } // ==================== 金币消耗 ==================== public bool ConsumeGold(int mul = 1) { long temp = goldNum - consumeGoldNum * mul; if (temp < 0) return false; goldNum = temp; tMP_GoldNum.text = goldNum.ToString(); return true; } int indexConsume = 0; public void ChangeTurretAddConsumeNum() { if (CreateFishManager.Instance.currGameType.paoBeiList.Count - 1 > indexConsume) indexConsume++; else indexConsume = 0; AudioManager.Instance.PlayerFX(62011); consumeGoldNum = CreateFishManager.Instance.currGameType.paoBeiList[indexConsume]; tMP_TurretConsumeNum.text = consumeGoldNum.ToString(); } public void ChangeTurretMinusConsumeNum() { if (indexConsume > 0) indexConsume--; else indexConsume = CreateFishManager.Instance.currGameType.paoBeiList.Count - 1; AudioManager.Instance.PlayerFX(62010); consumeGoldNum = CreateFishManager.Instance.currGameType.paoBeiList[indexConsume]; tMP_TurretConsumeNum.text = consumeGoldNum.ToString(); } // ==================== 锁定系统 ==================== public void SetLockTarget(MonsterContral monster, Transform hitPos) { monCotl_Lock = monster; monCotl_Lock_Position = hitPos; isLock = monster != null; lockFX.SetActive(isLock); } public void ClearLock() { monCotl_Lock = null; monCotl_Lock_Position = null; isLock = false; lockFX.SetActive(false); ChangeState(TurretState.Idle); } }