Files
5.24BuYu/Assets/MyGame/Scripts/Turret/SitPosData.cs
T

350 lines
11 KiB
C#
Raw Normal View History

2026-02-03 11:35:19 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
2026-03-09 09:25:01 +08:00
using UnityEngine.UI;
2026-02-03 11:35:19 +08:00
public class SitPosData : MonoBehaviour
{
2026-06-08 21:23:40 +08:00
/// <summary>本地玩家的座位引用(由游戏面板初始化时设置)</summary>
public static SitPosData localPlayerSit;
2026-06-16 19:12:37 +08:00
/// <summary>当前房间房主座位(人机请求由房主发送,房主退出后自动继承)</summary>
public static SitPosData roomOwnerSit;
2026-06-08 21:23:40 +08:00
2026-05-02 23:52:48 +08:00
// -------------------------
2026-05-04 17:21:52 +08:00
// 玩家基础信息
2026-05-02 23:52:48 +08:00
// -------------------------
2026-05-04 17:21:52 +08:00
[Header("玩家信息")]
2026-03-18 17:26:14 +08:00
public string user;
2026-06-13 01:25:41 +08:00
[Tooltip("座位编号 0~3。0,1=下方 2,3=上方")]
2026-02-03 11:35:19 +08:00
public int posID;
2026-06-16 19:12:37 +08:00
[Tooltip("是否为人机")]
public bool isBot = false;
2026-05-02 23:52:48 +08:00
2026-06-13 01:25:41 +08:00
/// <summary>posID>=2 = 上方,需要翻转(0,1=下方;2,3=上方)</summary>
public bool IsFlipped => posID >= 2;
2026-03-27 15:18:35 +08:00
[Header("金币")]
2026-05-02 23:52:48 +08:00
public long goldNum;
public long consumeGoldNum;
2026-02-03 11:35:19 +08:00
public TextMeshProUGUI tMP_GoldNum;
2026-06-19 18:18:04 +08:00
public TextMeshProUGUI tMP_DiamondNum;
2026-05-04 17:21:52 +08:00
public TextMeshProUGUI tMP_TurretConsumeNum;
2026-05-01 06:26:50 +08:00
2026-05-02 23:52:48 +08:00
// -------------------------
2026-06-08 21:23:40 +08:00
// 炮台管理(动态克隆)
2026-05-02 23:52:48 +08:00
// -------------------------
2026-05-04 17:21:52 +08:00
[Header("炮台")]
2026-06-08 21:23:40 +08:00
[Tooltip("炮台实例化的父节点")]
public Transform turretParent;
2026-05-04 17:21:52 +08:00
2026-06-08 21:23:40 +08:00
[Tooltip("炮台锚点位置(相对 turretParent)")]
public Vector2 turretAnchoredPos = Vector2.zero;
[Tooltip("当前装备的炮台编号")]
public int currentTurretNumber;
/// <summary>当前运行中的炮台实例</summary>
2026-02-03 11:35:19 +08:00
public TurretData currentTurret;
2026-05-02 23:52:48 +08:00
// 状态机入口(GameMainPanel 调用)
public Action<TurretState> OnStateChange;
// -------------------------
// 炮台旋转
// -------------------------
2026-05-04 17:21:52 +08:00
[Header("炮台旋转")]
2026-05-02 23:52:48 +08:00
public Transform tra_CurrTurret;
public float currentAngle;
// -------------------------
// 锁定系统
// -------------------------
2026-05-04 17:21:52 +08:00
[Header("锁定系统")]
2026-03-09 09:25:01 +08:00
public MonsterContral monCotl_Lock;
2026-05-01 06:26:50 +08:00
public Transform monCotl_Lock_Position;
2026-05-04 17:21:52 +08:00
public bool isLock = false;
2026-06-21 00:28:59 +08:00
public GameObject lockFX; // 主锁定图标(单发/双倍用)
public List<GameObject> lockFX_Triple = new List<GameObject>(); // 三发锁定额外2个图标
public List<MonsterContral> tripleLockTargets = new List<MonsterContral>();
public List<Transform> tripleLockPositions = new List<Transform>();
2026-02-03 11:35:19 +08:00
2026-05-02 23:52:48 +08:00
// -------------------------
// UI
// -------------------------
2026-05-04 17:21:52 +08:00
[Header("UI")]
2026-05-02 23:52:48 +08:00
public Button btn_TurretAdd;
public Button btn_TurretMinus;
2026-03-27 15:18:35 +08:00
2026-05-02 23:52:48 +08:00
private void Awake()
2026-02-03 11:35:19 +08:00
{
2026-05-27 19:47:06 +08:00
btn_TurretAdd.onClick.AddListener(() => ChangeTurretAddConsumeNum());
btn_TurretMinus.onClick.AddListener(() => ChangeTurretMinusConsumeNum());
}
2026-06-08 21:23:40 +08:00
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;
2026-06-16 19:12:37 +08:00
// 房主退出 → 自动继承给第一个非人机玩家
if (roomOwnerSit == this)
{
roomOwnerSit = null;
TransferRoomOwner();
}
}
/// <summary>房主退出后,将房主身份转移给第一个活跃的非人机玩家</summary>
public static void TransferRoomOwner()
{
var list = FindObjectsOfType<SitPosData>();
foreach (var sit in list)
{
if (!sit.isBot && sit.gameObject.activeInHierarchy && sit != roomOwnerSit)
{
roomOwnerSit = sit;
break;
}
}
}
/// <summary>分配房主(首个非人机玩家)</summary>
public static void AssignRoomOwner(SitPosData sit)
{
if (roomOwnerSit == null && !sit.isBot)
roomOwnerSit = sit;
2026-06-08 21:23:40 +08:00
}
// ==================== 炮台加载(动态克隆) ====================
/// <summary>
/// 根据炮台编号,从 Addressables 加载预制体并克隆到 turretParent。
/// 位置/旋转/缩放保持预制体原始值,不动。
/// </summary>
public void LoadTurret(int turretNumber)
2026-02-09 10:44:38 +08:00
{
2026-02-03 11:35:19 +08:00
if (currentTurret != null)
2026-06-08 21:23:40 +08:00
{
Destroy(currentTurret.gameObject);
currentTurret = null;
}
2026-05-02 23:52:48 +08:00
2026-06-08 21:23:40 +08:00
currentTurretNumber = turretNumber;
2026-05-04 17:21:52 +08:00
2026-06-08 21:23:40 +08:00
// 从 TurretResourcesData 拿预制体
GameObject prefab = TurretResourcesData.GetTurretPrefab(turretNumber);
if (prefab == null)
{
Debug.LogWarning($"[SitPosData] 炮台预制体未加载: #{turretNumber}");
return;
}
2026-02-03 11:35:19 +08:00
2026-06-08 21:23:40 +08:00
// 克隆到父节点
GameObject instance = Instantiate(prefab, turretParent, false);
instance.SetActive(true);
// 固定位置归零,由外部父节点定位
var rt = instance.GetComponent<RectTransform>();
if (rt != null)
rt.anchoredPosition = turretAnchoredPos;
currentTurret = instance.GetComponent<TurretData>();
if (currentTurret == null)
{
Debug.LogError($"[SitPosData] 预制体上未找到 TurretData 组件: #{turretNumber}");
Destroy(instance);
return;
}
currentTurret.turretNumber = turretNumber;
// 缓存旋转节点
tra_CurrTurret = currentTurret.transform.GetChild(0);
// 绑定状态机入口
2026-05-02 23:52:48 +08:00
OnStateChange = currentTurret.ChangeState;
2026-02-03 11:35:19 +08:00
2026-06-08 21:23:40 +08:00
Debug.Log($"[SitPosData] 炮台已加载: #{turretNumber}");
}
2026-05-18 18:39:11 +08:00
2026-06-08 21:23:40 +08:00
/// <summary>根据炮台编号字符串加载。</summary>
public void LoadTurret(string turretNumberStr)
{
if (int.TryParse(turretNumberStr, out int num))
LoadTurret(num);
2026-02-03 11:35:19 +08:00
}
2026-05-02 23:52:48 +08:00
// -------------------------
// 切换状态(GameMainPanel 调用)
// -------------------------
public void ChangeState(TurretState state)
2026-02-03 11:35:19 +08:00
{
2026-05-02 23:52:48 +08:00
OnStateChange?.Invoke(state);
2026-05-01 06:26:50 +08:00
}
2026-05-02 23:52:48 +08:00
// -------------------------
2026-05-04 17:21:52 +08:00
// 炮台旋转(GameMainPanel 调用)
2026-05-02 23:52:48 +08:00
// -------------------------
public void SetRotation(float angle)
{
currentAngle = angle;
2026-05-04 17:21:52 +08:00
if (tra_CurrTurret != null)
tra_CurrTurret.rotation = Quaternion.Euler(0, 0, angle);
2026-05-02 23:52:48 +08:00
}
// -------------------------
// 获取发射点(给 GameMainPanel)
// -------------------------
public Vector2 GetBulletStartPos()
{
2026-06-08 21:23:40 +08:00
return currentTurret != null
? currentTurret.GetBulletStartWorldPos()
: Vector2.zero;
2026-05-02 23:52:48 +08:00
}
2026-06-08 21:23:40 +08:00
// ==================== 金币消耗 ====================
2026-05-02 23:52:48 +08:00
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;
}
2026-06-08 21:23:40 +08:00
int indexConsume = 0;
2026-05-27 19:47:06 +08:00
public void ChangeTurretAddConsumeNum()
2026-05-01 06:26:50 +08:00
{
2026-06-08 21:23:40 +08:00
if (CreateFishManager.Instance.currGameType.paoBeiList.Count - 1 > indexConsume)
2026-05-27 19:47:06 +08:00
indexConsume++;
else
indexConsume = 0;
2026-06-16 02:28:58 +08:00
AudioManager.Instance.PlayerFX(62011);
2026-06-08 21:23:40 +08:00
2026-05-27 19:47:06 +08:00
consumeGoldNum = CreateFishManager.Instance.currGameType.paoBeiList[indexConsume];
2026-05-01 06:26:50 +08:00
tMP_TurretConsumeNum.text = consumeGoldNum.ToString();
2026-06-19 18:18:04 +08:00
CreateFishManager.Instance.currGameType?.SyncCannonMultiple((int)consumeGoldNum);
2026-05-01 06:26:50 +08:00
}
2026-05-02 23:52:48 +08:00
2026-05-27 19:47:06 +08:00
public void ChangeTurretMinusConsumeNum()
2026-05-01 06:26:50 +08:00
{
2026-06-08 21:23:40 +08:00
if (indexConsume > 0)
2026-05-27 19:47:06 +08:00
indexConsume--;
else
indexConsume = CreateFishManager.Instance.currGameType.paoBeiList.Count - 1;
2026-06-16 02:28:58 +08:00
AudioManager.Instance.PlayerFX(62010);
2026-06-08 21:23:40 +08:00
2026-05-27 19:47:06 +08:00
consumeGoldNum = CreateFishManager.Instance.currGameType.paoBeiList[indexConsume];
2026-05-01 06:26:50 +08:00
tMP_TurretConsumeNum.text = consumeGoldNum.ToString();
2026-06-19 18:18:04 +08:00
CreateFishManager.Instance.currGameType?.SyncCannonMultiple((int)consumeGoldNum);
2026-02-03 11:35:19 +08:00
}
2026-05-04 17:21:52 +08:00
2026-06-08 21:23:40 +08:00
// ==================== 锁定系统 ====================
2026-05-04 17:21:52 +08:00
public void SetLockTarget(MonsterContral monster, Transform hitPos)
{
monCotl_Lock = monster;
monCotl_Lock_Position = hitPos;
isLock = monster != null;
lockFX.SetActive(isLock);
2026-06-21 00:28:59 +08:00
// 非三发锁定 → 隐藏额外图标
if (!isLock) HideTripleLockIcons();
}
/// <summary>
/// 设置三发锁定目标(3个目标分别追踪)
/// </summary>
public void SetTripleLockTargets(List<(MonsterContral monster, Transform hitPos)> targets)
{
if (targets == null || targets.Count == 0)
{
HideTripleLockIcons();
return;
}
// 确保 lockFX_Triple 有2个克隆的图标(+主图标=3个)
EnsureTripleLockIcons();
tripleLockTargets.Clear();
tripleLockPositions.Clear();
// 第一个目标用主 lockFX
var primary = targets[0];
monCotl_Lock = primary.monster;
monCotl_Lock_Position = primary.hitPos;
isLock = true;
lockFX.SetActive(true);
tripleLockTargets.Add(primary.monster);
tripleLockPositions.Add(primary.hitPos);
// 第二个和第三个目标用 lockFX_Triple
for (int i = 1; i < targets.Count && i < 3; i++)
{
int idx = i - 1;
if (idx < lockFX_Triple.Count && lockFX_Triple[idx] != null)
{
lockFX_Triple[idx].SetActive(true);
tripleLockTargets.Add(targets[i].monster);
tripleLockPositions.Add(targets[i].hitPos);
}
}
// 隐藏多余的
for (int i = targets.Count - 1; i < lockFX_Triple.Count; i++)
{
if (lockFX_Triple[i] != null)
lockFX_Triple[i].SetActive(false);
}
}
private void EnsureTripleLockIcons()
{
while (lockFX_Triple.Count < 2 && lockFX != null)
{
var clone = GameObject.Instantiate(lockFX, lockFX.transform.parent);
clone.name = lockFX.name + "_Triple" + (lockFX_Triple.Count + 1);
clone.transform.localScale = lockFX.transform.localScale * 0.5f;
lockFX_Triple.Add(clone);
}
}
public void HideTripleLockIcons()
{
foreach (var icon in lockFX_Triple)
{
if (icon != null)
icon.SetActive(false);
}
tripleLockTargets.Clear();
tripleLockPositions.Clear();
2026-05-04 17:21:52 +08:00
}
public void ClearLock()
{
monCotl_Lock = null;
monCotl_Lock_Position = null;
isLock = false;
lockFX.SetActive(false);
2026-06-21 00:28:59 +08:00
HideTripleLockIcons();
2026-05-27 19:47:06 +08:00
ChangeState(TurretState.Idle);
2026-05-04 17:21:52 +08:00
}
2026-02-03 11:35:19 +08:00
}