This commit is contained in:
2026-09-29 00:45:16 +08:00
parent f05f1580bd
commit c91eaef60b
3 changed files with 226 additions and 76 deletions
+164 -54
View File
@@ -218,6 +218,16 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
public List<GameObject> lockFX_Triple = new List<GameObject>(); // 三发锁定额外2个图标
public List<MonsterContral> tripleLockTargets = new List<MonsterContral>();
public List<Transform> tripleLockPositions = new List<Transform>();
/// <summary>
/// ⭐ 三发锁位是否处于"空置等手动点击"状态(索引与 tripleLockTargets 对齐)。
/// true = 该锁位打死后自动检测没找到鱼 → 保持空着,不再自动补位,必须玩家手动点击才锁。
/// </summary>
private readonly List<bool> tripleSlotIdle = new List<bool>();
/// <summary>
/// ⭐ 该锁位是否由玩家手动点选(索引与 tripleLockTargets 对齐)。
/// true = 玩家自己点的鱼 → 离场前一直跟,死了才换;手动身份会跟着鱼一起移入子锁位。
/// </summary>
private readonly List<bool> tripleSlotManual = new List<bool>();
// -------------------------
// UI
@@ -2021,37 +2031,23 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
// 确保 lockFX_Triple 有2个克隆的图标(+主图标=3个)
EnsureTripleLockIcons();
// ⭐ 固定3个锁位(不足的留空占位,下一帧由锁定系统自动尝试补一次)
EnsureTripleLockSlots(3);
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++)
for (int i = 0; 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);
}
bool has = i < targets.Count;
tripleLockTargets[i] = has ? targets[i].monster : null;
tripleLockPositions[i] = has ? targets[i].hitPos : null;
// ⭐ 自动建位:允许自动补位(补不到会转成"空置等手动点击"),不算玩家手动
tripleSlotIdle[i] = false;
tripleSlotManual[i] = false;
}
// 隐藏多余的
for (int i = targets.Count - 1; i < lockFX_Triple.Count; i++)
{
if (lockFX_Triple[i] != null)
lockFX_Triple[i].SetActive(false);
}
monCotl_Lock = targets[0].monster;
monCotl_Lock_Position = targets[0].hitPos;
isLock = targets[0].monster != null;
RefreshTripleIconVisibility();
}
private void EnsureTripleLockIcons()
@@ -2065,6 +2061,18 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
}
}
/// <summary>把锁位列表补齐到 count 个(用 null 占位,保证三个列表索引对齐)</summary>
public void EnsureTripleLockSlots(int count)
{
while (tripleLockTargets.Count < count)
{
tripleLockTargets.Add(null);
tripleLockPositions.Add(null);
tripleSlotIdle.Add(false);
tripleSlotManual.Add(false);
}
}
public void HideTripleLockIcons()
{
foreach (var icon in lockFX_Triple)
@@ -2074,69 +2082,163 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
}
tripleLockTargets.Clear();
tripleLockPositions.Clear();
tripleSlotIdle.Clear();
tripleSlotManual.Clear();
}
// ==================== 三发锁位(每个锁位独立维护) ====================
// ⭐ index=0 是主锁位(monCotl_Lock + 主 lockFX),1..2 对应 lockFX_Triple[index-1]
/// <summary>取 index(1..2) 对应的额外锁定图标</summary>
private GameObject GetTripleIcon(int index)
/// <summary>按每个锁位是否有鱼刷新3个锁定圈显示(有目标才有圈)</summary>
private void RefreshTripleIconVisibility()
{
int iconIdx = index - 1;
if (lockFX_Triple == null || iconIdx < 0 || iconIdx >= lockFX_Triple.Count) return null;
return lockFX_Triple[iconIdx];
if (lockFX != null)
lockFX.SetActive(tripleLockTargets.Count > 0 && tripleLockTargets[0] != null);
for (int i = 0; i < lockFX_Triple.Count; i++)
{
if (lockFX_Triple[i] == null) continue;
int slot = i + 1;
lockFX_Triple[i].SetActive(slot < tripleLockTargets.Count && tripleLockTargets[slot] != null);
}
}
/// <summary>替换单个三发锁位(锁位独立:某条鱼死了只补这一个锁位,其他锁位不动)</summary>
/// <summary>替换单个三发锁位(自动补位用:锁位独立,只补这一个,其他锁位不动)</summary>
public void SetTripleLockSlot(int index, MonsterContral monster, Transform hitPos)
{
if (index < 0) return;
while (tripleLockTargets.Count <= index)
{
tripleLockTargets.Add(null);
tripleLockPositions.Add(null);
}
EnsureTripleLockSlots(index + 1);
tripleLockTargets[index] = monster;
tripleLockPositions[index] = hitPos;
tripleSlotIdle[index] = false;
tripleSlotManual[index] = false; // 自动补的位不算玩家手动
if (index == 0)
{
monCotl_Lock = monster;
monCotl_Lock_Position = hitPos;
isLock = monster != null;
if (lockFX != null) lockFX.SetActive(isLock);
}
else
{
var icon = GetTripleIcon(index);
if (icon != null) icon.SetActive(monster != null);
}
RefreshTripleIconVisibility();
}
/// <summary>清空单个三发锁位(该锁位暂时没鱼可补):保留槽位占位,只隐藏该锁位图标</summary>
/// <summary>
/// 清空单个三发锁位:该位打死后自动检测没找到鱼 → 保留占位、隐藏该位图标,
/// 并标记"空置等手动点击"(不再自动补位,必须玩家点击才锁)。
/// </summary>
public void ClearTripleLockSlot(int index)
{
if (index < 0 || index >= tripleLockTargets.Count) return;
tripleLockTargets[index] = null;
if (index < tripleLockPositions.Count) tripleLockPositions[index] = null;
tripleLockPositions[index] = null;
tripleSlotIdle[index] = true;
tripleSlotManual[index] = false;
if (index == 0)
{
monCotl_Lock = null;
monCotl_Lock_Position = null;
isLock = false;
if (lockFX != null) lockFX.SetActive(false);
}
else
RefreshTripleIconVisibility();
}
/// <summary>该锁位是否处于"空置等手动点击"状态(不再自动补位)</summary>
public bool IsTripleSlotIdle(int index)
{
return index >= 0 && index < tripleSlotIdle.Count && tripleSlotIdle[index];
}
/// <summary>
/// 该锁位是否是玩家手动点选的鱼(手动身份跟着鱼一起移入子锁位)。
/// true → 离场前一直跟,只有鱼死了才换。
/// </summary>
public bool IsTripleSlotManual(int index)
{
return index >= 0 && index < tripleSlotManual.Count && tripleSlotManual[index];
}
/// <summary>三个锁位是否还有任意一个有效目标(鱼还活着)</summary>
public bool HasAnyTripleTarget
{
get
{
var icon = GetTripleIcon(index);
if (icon != null) icon.SetActive(false);
foreach (var m in tripleLockTargets)
if (m != null && m.gameObject.activeInHierarchy) return true;
return false;
}
}
/// <summary>当前三发锁位上有效的鱼 guid 列表(开火同步 monsterIDs 用)</summary>
public List<string> GetTripleLockGuids()
{
var list = new List<string>();
foreach (var m in tripleLockTargets)
if (m != null && !m.isDead && m.gameObject.activeInHierarchy)
list.Add(m.guid);
return list;
}
/// <summary>该 guid 的鱼是否已经在某个三发锁位上</summary>
public bool IsFishInTripleSlots(string guid)
{
if (string.IsNullOrEmpty(guid)) return false;
foreach (var m in tripleLockTargets)
if (m != null && m.guid == guid) return true;
return false;
}
/// <summary>
/// ⭐ 手动点击锁鱼(战神+三发+锁定):新点的鱼占主锁位,原来锁位上的鱼依次排到子锁位,
/// 最多保留3个(超过时最旧的被挤掉)。
/// 手动身份跟着鱼一起转移(移入子锁位后依然是手动锁定,离场前不会被自动换掉);
/// 挤位前会先"紧凑化",跳过空位/死鱼,避免有空位时误丢掉还活着的锁定目标。
/// </summary>
public void PushTripleLockSlot(MonsterContral monster, Transform hitPos)
{
EnsureTripleLockIcons();
// ① 收集现有锁位上还活着的鱼(跳过空位和死鱼),按 新→旧 顺序,最多留2个
var keepMon = new List<MonsterContral>();
var keepPos = new List<Transform>();
var keepManual = new List<bool>();
for (int i = 0; i < tripleLockTargets.Count && keepMon.Count < 2; i++)
{
var m = tripleLockTargets[i];
if (m == null || !m.gameObject.activeInHierarchy) continue;
if (m == monster) continue; // 同一条鱼不重复占位
keepMon.Add(m);
keepPos.Add(i < tripleLockPositions.Count ? tripleLockPositions[i] : null);
keepManual.Add(i < tripleSlotManual.Count && tripleSlotManual[i]);
}
// ② 新点的鱼占主锁位,其余依次排到子锁位
EnsureTripleLockSlots(3);
tripleLockTargets[0] = monster;
tripleLockPositions[0] = hitPos;
tripleSlotIdle[0] = false;
tripleSlotManual[0] = true; // 玩家手动点的
for (int i = 1; i < 3; i++)
{
int k = i - 1;
bool has = k < keepMon.Count;
tripleLockTargets[i] = has ? keepMon[k] : null;
tripleLockPositions[i] = has ? keepPos[k] : null;
// ⭐ 空位标记"等手动点击":玩家在自己点选,空位不再自动补
tripleSlotIdle[i] = !has;
tripleSlotManual[i] = has && keepManual[k];
}
monCotl_Lock = monster;
monCotl_Lock_Position = hitPos;
isLock = true;
RefreshTripleIconVisibility();
}
/// <summary>
/// 主锁位空缺时,把其他存活的锁位提升为主锁,避免主锁死掉导致整个三发模式中断。
/// 提升后原锁位留空,下一帧会自动补新目标。成功返回 true。
/// 提升后原锁位留空并允许自动补一次。成功返回 true。
/// </summary>
public bool PromoteTripleLockSlotToMain()
{
@@ -2150,13 +2252,21 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
tripleLockPositions[0] = pos;
tripleLockTargets[i] = null;
tripleLockPositions[i] = null;
var icon = GetTripleIcon(i);
if (icon != null) icon.SetActive(false);
if (i < tripleSlotIdle.Count)
{
tripleSlotIdle[0] = tripleSlotIdle[i];
tripleSlotIdle[i] = false; // 让出的位置允许自动补一次
}
if (i < tripleSlotManual.Count)
{
tripleSlotManual[0] = tripleSlotManual[i]; // 手动身份跟着鱼提升
tripleSlotManual[i] = false;
}
monCotl_Lock = mon;
monCotl_Lock_Position = pos;
isLock = true;
if (lockFX != null) lockFX.SetActive(true);
RefreshTripleIconVisibility();
return true;
}
return false;