feat(SignalCycle):实现提前检测信号循环,触发重启

This commit is contained in:
2025-10-28 09:03:48 +08:00
parent b06d21114b
commit 1410837faa
7 changed files with 83 additions and 41 deletions

View File

@@ -3,6 +3,7 @@ using Script.Gameplay.Connect;
using Script.Gameplay.Global;
using Script.Gameplay.Interface;
using UnityEngine;
using UnityEngine.Experimental.GlobalIllumination;
namespace Script.Gameplay.Facility
{
@@ -112,7 +113,7 @@ namespace Script.Gameplay.Facility
{
SendSignal(active, sender);
}
if (active)
{
CurrentNeedSignalCount++;
@@ -142,15 +143,15 @@ namespace Script.Gameplay.Facility
/// <param name="sender">让此物体触发发送的来源者</param>
public virtual void SendSignal(bool active, GameObject sender)
{
if(!IsEnableSendSignal) return;
if (!IsEnableSendSignal) return;
if (ConnectionLines != null)
{
// if (ISignalSender.IsSendToSignalSender(this.gameObject))
// {
// // 防止信号回传给发送者自己
// BUGManager.Instance.LogStackOverflowBUG(this.transform);
// return;
// }
// 利用DFS检测是否存在连接环
if (DfsCheckConnectionRing(this.gameObject))
{
StartCoroutine(GameManager.Instance.ReStartGame());
return;
}
foreach (var line in ConnectionLines)
{
@@ -159,9 +160,63 @@ namespace Script.Gameplay.Facility
{
continue;
}
line.OnSignalReceived(active, this.gameObject);
}
}
}
public static bool DfsCheckConnectionRing(GameObject root)
{
if (root == null) return false;
var rootConnect = root.GetComponent<IConnectable>();
if (rootConnect == null) return false;
var visited = new HashSet<GameObject>();
// 内部递归 DFSparent 用于避免把返回到父节点误判为环
bool Dfs(GameObject current, GameObject parent)
{
if (current == null) return false;
visited.Add(current);
var conn = current.GetComponent<IConnectable>();
if (conn == null) return false;
foreach (var line in conn.ConnectionLines)
{
if (line == null) continue;
GameObject a = line.PointA?.GetGameObject();
GameObject b = line.PointB?.GetGameObject();
GameObject neighbor = null;
if (a == current) neighbor = b;
else if (b == current) neighbor = a;
else continue; // 如果这条线并未连接到 current跳过
if (neighbor == null) continue;
// 如果邻居是父节点,跳过(因为这是无向边回到父)
if (neighbor == parent) continue;
// 已访问到其他非父节点,说明存在环
if (visited.Contains(neighbor))
{
return true;
}
if (Dfs(neighbor, current))
{
return true;
}
}
return false;
}
return Dfs(root, null);
}
}
}