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



我正在使用播放器上的导航网格/代理作为辅助自动路径功能,除非用户单击地板上的某个点以步行,否则代理始终处于禁用状态。然后,到达目的地后,代理将再次禁用。

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

我想在伪代码中,这就是我试图在禁用 navmeshagent 的情况下完成的:

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

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

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

下面是有关如何在代码中应用它的想法:

// 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();
}

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

最新更新