NavMeshAgent 接口说明

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()

停止代理沿着当前路径移动。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容