You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中DFS查找回合制Tile游戏可移动区域时触发空引用异常

空引用异常排查与解决

问题原因

错误触发在FindNeighbouringTiles方法的射线检测链式调用处(对应报错行UnitManager.cs:103)。当向网格边缘外的方向发射射线时,射线未命中任何Collider,此时Physics2D.Raycast(...)返回的RaycastHit2D对象的collider属性为null,直接链式访问.collider.gameObject.GetComponent<Tile>()就会触发空引用异常。

比如起始Tile位于(1,1)时,若某个方向超出16×9的网格范围,射线找不到对应Tile的Collider,就会触发该错误。

解决方法

1. 修复射线检测的空引用问题

拆分射线检测的调用步骤,先判断是否命中Collider,再获取Tile组件,同时优化射线检测逻辑:

public List<Tile> FindNeighbouringTiles(Tile origin)
{
    List<Tile> neighbouringTiles = new List<Tile>();
    // 假设所有Tile都放在名为"Tile"的图层,通过LayerMask过滤仅检测Tile
    int tileLayerMask = LayerMask.GetMask("Tile");
    // 射线检测距离设为1(假设Tile之间的间距为1单位)
    float rayDistance = 1f;

    // 向上检测相邻Tile
    RaycastHit2D upHit = Physics2D.Raycast(origin.transform.position, Vector2.up, rayDistance, tileLayerMask);
    if (upHit.collider != null)
    {
        Tile upTile = upHit.collider.GetComponent<Tile>();
        if (upTile != null) neighbouringTiles.Add(upTile);
    }

    // 向下检测相邻Tile
    RaycastHit2D downHit = Physics2D.Raycast(origin.transform.position, Vector2.down, rayDistance, tileLayerMask);
    if (downHit.collider != null)
    {
        Tile downTile = downHit.collider.GetComponent<Tile>();
        if (downTile != null) neighbouringTiles.Add(downTile);
    }

    // 向左检测相邻Tile
    RaycastHit2D leftHit = Physics2D.Raycast(origin.transform.position, Vector2.left, rayDistance, tileLayerMask);
    if (leftHit.collider != null)
    {
        Tile leftTile = leftHit.collider.GetComponent<Tile>();
        if (leftTile != null) neighbouringTiles.Add(leftTile);
    }

    // 向右检测相邻Tile
    RaycastHit2D rightHit = Physics2D.Raycast(origin.transform.position, Vector2.right, rayDistance, tileLayerMask);
    if (rightHit.collider != null)
    {
        Tile rightTile = rightHit.collider.GetComponent<Tile>();
        if (rightTile != null) neighbouringTiles.Add(rightTile);
    }

    return neighbouringTiles;
}
  • 添加射线距离参数,避免射线无限制穿透;
  • 使用LayerMask仅检测Tile图层,无需临时禁用自身Collider,减少潜在逻辑问题;
  • 分步判断collider和Tile组件是否为空,彻底规避空引用。

2. 优化DFS遍历性能(可选)

原代码中visited使用List<Tile>,Contains方法为O(n)时间复杂度,网格较大时遍历效率低下。建议替换为HashSet<Tile>:

HashSet<Tile> visited = new HashSet<Tile>(); // 替换原List<Tile>

HashSet的Contains和Add操作均为O(1),能显著提升DFS的遍历速度。

3. 后续移动步数限制实现建议

当需要添加移动步数限制时,可在DFS过程中记录每个Tile的步数(从起点到该Tile的距离),当步数超过限制时停止遍历。可以通过字典存储每个Tile对应的步数,或者在Tile类中临时添加步数字段。


内容的提问来源于stack exchange,提问作者HGBadger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:47:15