Variables
acceleration
类型:float。
代理的最大加速度。代理并不是精确的按照被navigation system计算出来的直线片段行走,而是使用路点作为中间目的地。这个值是代理在向下一个路点移动时的最大加速的值。(跟现实世界一样,代理按照这个加速度增加自己的速度,直到最大速度)。
angularSpeed
类型:float。
代理的最高旋转速度。这是当代理绕着路点定义的"corner"旋转时的最大速率。真正旋转时的弧度(circle)也受到代理的速度和最大加速度影响。
areaMask
类型:int
指定哪一个NavMesh区域(areas)是可用的。改变areaMask将会使路径陈旧。
这是一个位域。
(这个值可以在游戏中被修改,立即生效)
autoBraking
类型:bool
代理是否自动停止从而避免越过目的地?
如果代理需要在目的点附近着陆(land close),那么他必须及时停止避免越过或者无限的围着目标区域按轨道运行。如果这个属性被设置为true,当代理到达目的地附近时就会自动停止。
autoRepath
类型:bool
如果当前的路径变成无效时,代理是否重新获得一个路径?
当代理到达一个路径片段的结尾和路径陈旧时,一个新的路径需要被计算。
(这个值还不知道到底有什么效果,在游戏中,当areaMask改变,路径陈旧时,路径会被重新计算,立即发生)
autoTraverseOffMeshLink
类型:bool
Off-mesh links被用来链接不连续的NavMesh区域。通常情况下,一个角色应该可以自动的通过或穿过一个环节(link),而这时这个属性被设置为true。然而他也可以被设置为false当需要一些特定的控制的时候。
avoidancePriority
类型:int
躲避优先级
当代理是一个障碍物时,级别低的代理被忽视。有效的范围是从0到99:最终要=0,最不重要=99,默认=50
(注意:以下都是基于没有刚体的情况下
1、如果障碍物是不会移动的,那么请在bake时候连同地形一起bake,这样就会生成较好的navmesh
2、如果障碍物需要移动,那么请在障碍物上添加agent,并设置其大小,然后设置avoidancePriority,低优先级的将被高优先级的agent强行推开)
baseOffset
类型:float
相对于所拥有的游戏对象的垂直位移。
(正值则代理在游戏对象的下方,负值在上方)
currentOffMeshLinkData
类型:OffMeshLinkData
当前的OffMeshLinkData.。(结构体)
如果代理没有在一个OffMeshLink上,OffMeshLinkData被标记为无效。
desiredVelocity
类型:Vector3
期望速度 只读。
Destination
类型:Vector3
设置或者获得代理的目的点,世界坐标系。
获得:
返回设置给代理的目的点。
•如果一个目的点被设置了并且寻路过程还没结束,将会返回一个有效的,离预先设置的位置(position)最近的navmesh位置。
•如果代理没有路径或被请求的路径,返回代理自己的位置。
•如果代理没有映射到navmesh,返回infinity。
设置:
请求代理移动到离目的点最近的有效的位置。
• 路径结果可能是无效的直到几帧之后。使用pathPending获取结果。
• 如果找不到一个有效的最近的位置,将不会请求路径。使用SetDestination并且检查返回值,如果你需要明确的掌握这些情况。
using UnityEngine;
[RequireComponent(typeof(NavMeshAgent))]
public class FollowTarget : MonoBehaviour
{
public Transform target; Vector3 destination; NavMeshAgent agent;
void Start()
{
// Cache agent component and destination
agent = GetComponent<NavMeshAgent>();
destination = agent.destination;
}
void Update()
{
// Update destination if the target moves one unit
if (Vector3.Distance(destination, target.position) > 1.0f)
{
destination = target.position;
agent.destination = destination;
}
}
}
hasPath
类型:bool
当前代理是否有路径?(只读)
height
类型:float
代理在障碍物下可以通过的高度。
isOnNavMesh
类型:bool
代理最近一定会在navmesh上吗?(只读)
这个属性将被设置为true,如果代理因为某些原因不能绑定到navmesh。
(这里文档说反了,这个属性值应该是false)
isOnOffMeshLink
类型:bool
代理当前的位置在一个OffMeshLink上吗?(只读)
当穿过link时客户的运动需要被知道而autoTraverseOffMeshLink是false的时候这个值很有用。
isPathStale
类型:bool
当前路径是否陈旧(只读)
当为true,路径可能不再有效或者最优。这个标签会被设置,如果:areaMask有任意的改变,任意一个OffMeshLink设为可用或不可用,或者NavMeshAreas的消耗(costs)被改变。
nextOffMeshLinkData
类型:OffMeshLinkData
当前路径的下一个OffMeshLinkData。
如果当前路径不包含一个OffMeshLink,OffMeshLinkData被标记为无效的
nextPosition
类型:Vector3
获取或者设置网格代理的仿真位置(position)。
位置向量使用世界坐标系的坐标和单位。
nextPosition是与Transform.position相结合的。在默认情况下,当脚本函数Update被调用的时候,网格代理的Transform position将会与内部的仿真位置相匹配。这种结合可以通过设置updatePosition打开或者关闭。
当updatePosition为true,Transfom.position反映为仿真位置,为false的时候Transfom.position和网格代理是不同步的并且一般情况下你将会看到他们两个是不同的。当updatePosition被设置回为打开,Transform,position将会立即移动并匹配为nextPosition。
通过设置nextPosition你可以立即控制内部代理位置(position)应该在哪。代理会被移动到那个位置,在navmesh的范围内。只有当位置是连续的更新和计算的时候才是有用的。
(从名字来看,下一个位置,好像应该是下一步应该走的位置,然而文档看起来又没有这么解释,然而好像又可以这么理解。如果在update中打印nextPosition和代理当前的位置,会发现他们是一样的。如果将updatePosition设为false在打印,会发现nextPosition在持续变化,最终会非常接近目标点,而代理却一动不动,位置保持不变。如果设置nextPosition代理会理解移动到设置的位置。)
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
void Start()
{
// Update the transform position explicitly in the OnAnimatorMove callback
GetComponent<NavMeshAgent>().updatePosition = false;
}
void OnAnimatorMove()
{
transform.position = GetComponent<NavMeshAgent>().nextPosition;
}
}
此外他可以被用来立即改变代理的位置——特别是代理的移动是通过其他什么来控制的时候。
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
public bool agentIsControlledByOther;
void Update()
{
var agent = GetComponent<NavMeshAgent>();
agent.updatePosition = !agentIsControlledByOther;
if (agentIsControlledByOther)
{
GetComponent<NavMeshAgent>().nextPosition = transform.position;
}
}
}
obstacleAvoidanceType
类型:
Path
类型:NavMeshPath
设置或者获取当前路径。
对GUI,调试,以及其他想要获得经过导航系统计算的路径的点的目的,这个属性会非常有用。此外,通常也可以给代理设置一个由用户代码创建的路径让代理去走。例如,当为警卫设置巡逻路线的的时候与其两点之间不如设置当前路径。
pathPending
类型:bool
进程中的路径正在被计算但是还没转备好?(只读)
pathStatus
类型:NavMeshPathStatus
当前路径的状态(完成,局部或无效)
radius
类型:float
代理的避让半径。
这是代理的“私人空间”,当代理作为障碍物时,其他代理不能从中穿过。
remainingDistance
类型:float
在当前路径中,代理的位置和目标位置的距离(只读)
如果剩下的距离是未知的那么这个值是infinity
speed
类型:float
在一条路径上行走时的最大移动速率。
很典型的,沿路径行走时,代理需要加速或减速。速率受限于路段的长度和加速的时间和刹车(brake),但是速率不会超过这个属性被设置的值即使在一段又长又直的路径上。
steeringTarget
类型:Vector3
获得路径上的当前转向点。(只读)
他是沿路的下一个转角或寻路的终点。
除非代理在一个OffMeshLink上移动,否则在代理和steeringTarget之间是笔直的路径。
当接近一个OffMeshLink时,他的值是代理将要进入link的位置。当代理环游一个OffMeshLink时,他的值是代理将要离开link的位置。
stoppingDistance
类型:float
当距离目标位置这个距离的时候停止。
几乎不可能很精确的着陆到目标点,所以这个属性被用来设置一个可接受的半径,在这个半径内代理会停止。一个较大的stoppingDistance可以使代理在路径末端有更多的策略空间,以避免突然的停止,转弯或其他不正常的AI行为。
updatePosition
类型:bool
获取或设置transform position是否与模拟的代理位置同步。默认为true。
当为true:改变transform position将影响模拟位置,反之亦然。
当为false:模拟位置将不再被用于transform position,反之亦然。
如果想通过脚本直接控制transform position,设置updatePosition为false。
当为真,transform将被移动到模拟位置。这种情况下,代理将被迫停留在navmesh表面。
updateRotation
类型:bool
代理是否更新方向。
velocity
类型:Vector3
获取NavMeshAgent组件的当前速度,或者手动为代理设置一个速度。
读取这个变量将会返回基于群体仿真的代理的当前速度速度。
设置这个变量将会重写仿真(simulation),并且命令代理立即使用指定的速度移动。当代理使用速度来控制时,他的运动仍然受限于NavMesh。
Setting the velocity directly can be used for implementing player characters which are moving on NavMesh and affecting the rest of the simulated crowd。此外,设置优先级太高(值越小优先级越高),会使其他模拟代理更早的避开受控的代理。
当手动控制代理的时候我们建议每一帧都设置速度。如果释放控制权给模拟器,设置速度为0。如果速度被设置为某个值,然后停止了更新,模拟器将会捡起控制权然后缓慢的减速。
注意读取速度将会返回来自模拟器的值。如果你设置了一个值,下一帧才会生效。因为返回的速度来自模拟器,他可能跟你设置的不一样。
Units/s,世界坐标系。
Public Functions
ActivateCurrentOffMeshLink
类型:void ActivateCurrentOffMeshLink(bool activated);
参数:
activated link是否被激活?
使当前的off-mesh link可用或者不可用。
这个函数激活或撤销代理当前正在等待的off-mesh link。这被用来准许通过一个新开发的游戏世界的区域或者模拟创造或移除一个通往一个区域的障碍。
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
private NavMeshAgent agent;
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
void OpenDiscoveredArea(Hashtable areasDiscovered)
{
if (agent.isOnOffMeshLink)
if (areasDiscovered.ContainsKey(agent.currentOffMeshLinkData.offMeshLink.name))
agent.ActivateCurrentOffMeshLink(true);
}
}
CalculatePath
类型:bool CalculatePath(Vector3 targetPosition, NavMeshPath path)
参数:
targetPositon 路径要求的重点位置。
path 作为结果的路径
返回true如果路径被找到。
计算一段路径直到指定的点然后保存路径结果。
这个函数被用来提前计划一段路径以避免在游戏中当需要寻路时发生延迟。另外一个用处是在代理移动之前检查目标位置是否可达。
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
public Transform target;
private NavMeshAgent agent;
void Start()
{
agent = GetComponent<NavMeshAgent>(); NavMeshPath path = new NavMeshPath();
agent.CalculatePath(target.position, path);
if (path.status == NavMeshPathStatus.PathPartial)
{
}
}
}
CompleteOffMeshLink
类型:void CompleteOffMeshLink()
结束当前OffMeshLink上的移动。
代理会移动到离当前OffMeshLink另一端最近的有效的位置。
如果代理不在一个OffMeshLink上,CompleteOffMeshLink()没有任何效果。
当autoTraverseOffMeshLink不可用时,代理会暂停在一个off-mesh link上直到这个函数被调用。当用户自己控制通过OffMeshLinks时会用到它。
using UnityEngine;
using System.Collections;
public enum OffMeshLinkMoveMethod
{
Teleport,
NormalSpeed,
Parabola
}
[RequireComponent(typeof(NavMeshAgent))]
public class AgentLinkMover : MonoBehaviour
{
public OffMeshLinkMoveMethod method = OffMeshLinkMoveMethod.Parabola;
IEnumerator Start()
{
NavMeshAgent agent = GetComponent<NavMeshAgent>();
agent.autoTraverseOffMeshLink = false;
while (true)
{
if (agent.isOnOffMeshLink)
{
if (method == OffMeshLinkMoveMethod.NormalSpeed)
yield return StartCoroutine(NormalSpeed(agent));
else if (method == OffMeshLinkMoveMethod.Parabola)
yield return StartCoroutine(Parabola(agent, 2.0f, 0.5f));
agent.CompleteOffMeshLink();
}
yield return null;
}
}
IEnumerator NormalSpeed(NavMeshAgent agent)
{
OffMeshLinkData data = agent.currentOffMeshLinkData; Vector3 endPos = data.endPos Vector3.up* agent.baseOffset;
while (agent.transform.position != endPos)
{
agent.transform.position = Vector3.MoveTowards(agent.transform.position, endPos, agent.speed * Time.deltaTime);
yield return null;
}
}
IEnumerator Parabola(NavMeshAgent agent, float height, float duration)
{
OffMeshLinkData data = agent.currentOffMeshLinkData; Vector3 startPos = agent.transform.position; Vector3 endPos = data.endPos Vector3.up* agent.baseOffset;
float normalizedTime = 0.0f;
while (normalizedTime < 1.0f)
{
float yOffset = height * 4.0f * (normalizedTime - normalizedTime * normalizedTime);
agent.transform.position = Vector3.Lerp(startPos, endPos, normalizedTime) yOffset* Vector3.up;
normalizedTime = Time.deltaTime / duration;
yield return null;
}
}
}
FindClosestEdge
类型:bool FindClosestEdge(out NavMeshHit hit);
参数:
hit 掌握定位结果的性能。
返回:
True,如果最近的边缘被找到。
定位最近的navmesh边缘。
返回的NavMeshHit 包含最近的边缘上的最近的点的位置和细节。
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
private NavMeshAgent agent;
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
TakeCover();
}
void TakeCover()
{
NavMeshHit hit;
if (agent.FindClosestEdge(out hit))
agent.SetDestination(hit.position);
}
}
GetAreaCost
类型:float GetAreaCost(int areaIndex)
参数:
areaIndex 区域索引
返回:
指定的区域索引当前的消耗。
当通过特定区域的时候获得消耗以方便路径计算。
路径的消耗就是当涉及计算的时候的“困难”数量--最短的路径未必就是最优选如果需要穿过困难地形,比如泥潭、雪地等。在Unity中区域的不同类型用navmesh areas来表示。注意路径消耗只适用于选择路径,在代理沿路行走时并不会自动的改变其移动速度。确实,路径消耗能够指出其他因素,例如危险或能见度。
Move
类型:void Move(Vector3 offset)
参数:
offset 相对的移动向量。
申请一个相对当前位置的移动。
如果代理有一个路径他将被校正。
Raycast
类型:bool Raycast(Vector3 targetPosition, out NavMeshHit hit)
参数:
targetPosition 将要移动到的终点
hit 被射线发现的障碍物的属性(如果有)
返回:
True如果代理和目标位置之间有障碍物,否则false。
在不移动代理的前提下,在navmesh中向着目标位置追踪一条笔直的路径。如果沿路遇到一个障碍物,那么将返回true并且障碍物的位置信息和其他细节将会保存在hit参数中。这个函数可以用来检查角色是否一眼就能看到目标。这个函数和Physics.Raycast非常接近
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
public Transform target;
private NavMeshAgent agent;
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
void Update()
{
NavMeshHit hit;
if (!agent.Raycast(target.position, out hit))
{
}
}
}
ResetPath
类型:void ResetPath()
清除当前路径。
路径清除之后代理不会寻找一个新的路径直到SetDestination 被调用。
注意当调用这个函数时代理在OffMeshLink上,则link会立即被完成。
Resume()
类型:void Resume()
当一段暂停之后重新开始沿着当前路径移动。
SamplePathPosition
类型:bool SamplePathPosition(int areaMask, float maxDistance, out NavMeshHit hit)
参数:
areaMask 一个位域标志,指定了寻路是哪个区域可以通过。
maxDistance 超出这段距离则终止搜索路径。
hit 保存结果地理位置的属性。
返回:
True如果在maxDistance之前结束,否则false。
沿着当前路径取样一个位置。
这个函数朝着当前路径向前看一段指定的距离。那个位置的网格的细节将会返回到一个NavMeshHit对象中。这个函数可以被用来,例如,在角色即将到达之前检查地表类型--一个角色想要通过有水的地方的时候可能要举起枪仰起头。
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
public Transform target;
public NavMesh mesh;
private NavMeshAgent agent;
private int waterMask;
void Start()
{
agent = GetComponent<NavMeshAgent>();
waterMask = 1 << NavMesh.GetAreaFromName("Water");
agent.SetDestination(target.position);
}
void Update()
{
NavMeshHit hit;
// Check all areas one length unit ahead.
if (!agent.SamplePathPosition(NavMesh.AllAreas, 1.0F, out hit))
if ((hit.mask & waterMask) != 0)
{
// Water detected along the path...
}
}
}
SetAreaCost
类型:void SetAreaCost(int areaIndex, float areaCost)
参数:
areaIndex 区域索引
areaCost 指定的区域的新的消耗
设置穿过某种类型的区域时的消耗。
如果你启用或废除代理,那么消耗将会被重置为默认值。
SetDestination
类型:bool SetDestination(Vector3 target)
参数:
target 导航到的目标点。
返回:
True如果目标地址请求成功,否则false。
设置或更新目的地,因此可以出发一个新路径的计算。
注意新路径可能不会立即生效直到几帧之后。当路径计算完成之后,pathPending将会是true。如果一段有效的路径变为available 代理将重新开始移动。
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
private NavMeshAgent agent;
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
void Update()
{
RaycastHit hit;
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
agent.SetDestination(hit.point);
}
}
}
SetPath
类型:bool SetPath(NavMeshPath path)
参数:
path 新的寻路路径
返回:
true如果指定路径成功
指定一段新路径给代理。
如果指定路径成功代理会重新朝着新目标移动。如果指定失败路径被清空。
Stop
类型:void Stop()
停止代理沿着当前路径移动。