Version: 2023.1
Experimental: this API is experimental and might be changed or removed in the future.

NavMeshQuery.Raycast

切换到手册
public Experimental.AI.PathQueryStatus Raycast (out AI.NavMeshHit hit, Experimental.AI.NavMeshLocation start, Vector3 targetPosition, int areaMask, NativeArray<float> costs);

参数

hit 保留射线投射生成位置的属性。
start 射线在 NavMesh 上的起点位置。start.polygon 的类型必须为 NavMeshPolyTypes.Ground
targetPosition 射线在世界坐标中的期望终点。
areaMask 将索引位置与区域类型相关联的位掩码。索引从 0 到 31。在每个相关索引位置中,必须将值设置为 1 或 0。1 表示射线可以通过的区域类型。0 表示会阻止射线的区域类型。该参数为可选。如果省略此参数,则该参数默认为 NavMesh.AllAreas。请参阅区域和成本以了解更多信息。
costs 所有 32 种可能区域类型的自定义成本值数组。射线跨越不同区域时,这些值充当射线报告的距离的乘数。该参数为可选。如果省略该参数,它将默认为您在项目设置中配置的区域成本。请参阅 NavMesh.GetAreaCost 以了解更多信息。

返回

PathQueryStatus 如果可以使用提供的参数来正确跟踪射线,则返回 Success
如果 start 位置在查询的 NavMeshWorld 中无效,如果该位置在 areaMask 参数不允许的区域内,或者该位置在 NavMeshLink/OffMeshLink 上时,返回 Failure

描述

在导航网格上的两点之间找出一条线。

该方法类似于 NavMesh.Raycast,两者共享相同的底层实现。
使之不同的属性是:\ - 可以将它用于并行的作业
- 它返回的状态标志可表明操作成功还是失败;
- 报告的 hit.distance 受到区域成本的影响;
- 没有根据高度网格(如果存在)而在纵轴上调整生成的 hit.position
- 它具有下文描述的变体,该变体也返回射线所通过的多边形的列表。

返回的 hit.distance 代表起点与终点之间的直线。它还考虑提供的区域成本的列表。它是将射线在每个单独区域上经过的全部距离相加,然后乘以相应区域的成本所得的结果。

首先,起始位置经过验证,在 NavMeshWorld 中有效,并在 NavMesh 上映射目标点。然后,从起点到目标,对射线进行跟踪。如果计算成功,将用射线达到的最远点的相关信息来填写 hit 数据。无论从源到目标的路径是否遭到阻塞,都会发生此情况。
如果计算失败,返回的 hit 中会填充无效数据。最值得注意的是,hit.distance 字段获得值 positiveInfinity

如果射线投射在外边缘上终止,则 hit.mask 为 0;否则它包含阻挡多边形部分的区域遮罩。

可以使用此函数来检查代理是否可以在 NavMesh 上的两点之间畅通无阻地行走。例如,如果您的角色存在需要空间的逃避躲闪动作,您可以从角色位置向多个方向发射射线。这样将找到角色可以躲闪到的地方。

NavMeshQuery.Raycast 不同于物理射线投射。NavMeshQuery.Raycast 可以检测各种导航障碍物(例如地上的洞)。它也可以爬上斜坡(如果该区域适合行动)。

// TargetReachable
using Unity.Collections;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Experimental.AI;

public class TargetReachable : MonoBehaviour { public Transform target; NavMeshQuery m_NavQuery; NavMeshHit m_Hit;

void OnEnable() { m_NavQuery = new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), Allocator.Persistent); }

void Update() { var startLocation = m_NavQuery.MapLocation(transform.position, Vector3.one, 0); var status = m_NavQuery.Raycast(out m_Hit, startLocation, target.position, NavMesh.AllAreas, new NativeArray<float>()); if ((status &amp; PathQueryStatus.Success) != 0) { Debug.DrawLine(transform.position, target.position, m_Hit.hit ? Color.red : Color.green);

if (m_Hit.hit) Debug.DrawRay(m_Hit.position, Vector3.up, Color.red); } }

void OnDisable() { m_NavQuery.Dispose(); } }

public Experimental.AI.PathQueryStatus Raycast (out AI.NavMeshHit hit, NativeSlice<PolygonId> path, out int pathCount, Experimental.AI.NavMeshLocation start, Vector3 targetPosition, int areaMask, NativeArray<float> costs);

参数

hit 保留射线投射生成位置的属性。
path 这是一个缓冲区,其中填充射线所通过的一系列多边形。
pathCount 射线所通过的多边形的已报告数量,这些多边形均存储在 path 缓冲区中。它的长度不会超过 path.Length
start 射线在 NavMesh 上的起点位置。start.polygon 的类型必须为 NavMeshPolyTypes.Ground
targetPosition 射线在世界坐标中的期望终点。
areaMask 这是一个位域,用于指定在跟踪射线时可遍历的 NavMesh 区域。该参数为可选。如果没有填写此参数,则其默认为 NavMesh.AllAreas
costs 这是成本乘数,影响射线在不同区域类型上报告的距离。该参数为可选。如果省略该参数,它将默认为您在项目设置中配置的区域成本。

返回

PathQueryStatus 如果可以使用提供的参数来正确跟踪射线,则返回 Success
如果 start 位置在查询的 NavMeshWorld 中无效,如果该位置在 areaMask 参数不允许的区域内,或者该位置在 NavMeshLink/OffMeshLink 上时,返回 Failure
如果提供的 path 缓冲区大小不足以容纳射线通过的所有多边形,则 BufferTooSmall 是返回的标志的一部分。

描述

跟踪 NavMesh 上两点之间的一条线,并返回所通过的多边形的列表。

即使 path 缓冲区过小,它仍然会尽可能容纳多边形(从射线的原点位置开始)。

另请参阅:PolygonId

// StraightPathFromRay
using Unity.Collections;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Experimental.AI;

public class StraightPathFromRay : MonoBehaviour { public Transform target; NavMeshQuery m_NavQuery; NavMeshHit m_Hit; NativeArray<PolygonId> m_Path; int m_PathCount;

void OnEnable() { m_Path = new NativeArray<PolygonId>(3, Allocator.Persistent); m_NavQuery = new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), Allocator.Persistent); }

void Update() { var startLocation = m_NavQuery.MapLocation(transform.position, Vector3.one, 0); PathQueryStatus status = m_NavQuery.Raycast(out m_Hit, m_Path, out m_PathCount, startLocation, target.position, NavMesh.AllAreas, new NativeArray<float>()); if ((status &amp; PathQueryStatus.Success) != 0) { var bufferTooSmall = (status &amp; PathQueryStatus.BufferTooSmall) != 0; Debug.DrawLine(transform.position, m_Hit.position, bufferTooSmall ? Color.black : Color.green);

if (m_Hit.hit) Debug.DrawRay(m_Hit.position, Vector3.up, Color.red); } }

void OnDisable() { m_NavQuery.Dispose(); m_Path.Dispose(); } }