检查禁用的导航网格代理(播放器)是否在导航网格上

Check if disabled navmesh agent (player) is on navmesh

我在播放器上使用 navmesh/agent 作为辅助自动路径功能,除非用户单击地板上的某个点以走向,否则代理始终处于禁用状态。一旦到达目的地,代理将再次被禁用。

我需要一种方法来检查玩家当前是否在导航网格上,是否在可容忍的阈值内,而无需启用导航网格代理。或者,如果有一种方法可以在不禁用 navmeshagent 的情况下删除播放器绑定 'effect',因为我也可以用它来解决我的问题。

我猜在伪代码中,这就是我试图在 禁用 navmeshagent 的情况下实现的目标:

if (!agent.isOnNavMesh){ DisableClickSelection();}

我正在考虑比较玩家和导航网格的 Y 变换以获得高度差并使用它来确定玩家是否在导航网格上的可能性,但我不知道如何去做导航网格在特定 X 和 Z 点的 Y 变换。也许我可以使用光线投射?我不确定最好的方法。就像我说的,如果有一种方法可以删除播放器上代理的播放器绑定 'effect' 但保持代理启用,我也可以使用它。

您应该可以通过使用 NavMesh.SamplePosition() 来做到这一点。该方法基本上在给定位置周围的球形半径内搜索导航网格上最近的点。您需要做的就是验证返回的位置与玩家位置垂直对齐,并且是on/above。

这里有一个关于如何在代码中应用它的想法:

// Don't set this too high, or NavMesh.SamplePosition() may slow down
float onMeshThreshold = 3;

public bool IsAgentOnNavMesh(GameObject agentObject)
{
    Vector3 agentPosition = agentObject.transform.position;
    NavMeshHit hit;

    // Check for nearest point on navmesh to agent, within onMeshThreshold
    if (NavMesh.SamplePosition(agentPosition, out hit, onMeshThreshold, NavMesh.AllAreas))
    {
        // Check if the positions are vertically aligned
        if (Mathf.Approximately(agentPosition.x, hit.position.x)
            && Mathf.Approximately(agentPosition.z, hit.position.z))
        {
            // Lastly, check if object is below navmesh
            return agentPosition.y >= hit.position.y;
        }
    }

    return false;
}

因此,为了在您的示例中使用它,您应该这样写:

if (!IsAgentOnNavMesh(agent.gameObject))
{
    DisableClickSelection();
}

希望对您有所帮助!如果您有任何问题,请告诉我。