在做一个FPS游戏时,需要敌方自动找到玩家方位并向玩家移动,在查找资料(并走了不少坑)后,我试了三个方法,经测试,这三个方法都能实现自动寻路功能。

方法一:使用Mathf.Lerp()方法


代码很简单:

//在enemy.cs(即敌方的脚本)中更新如下代码:
Transmform m_transform; //获得敌人组件 //在Update()函数中插入如下代码
m_transform.position =
new Vector3(Mathf.Lerp(m_transform.position.x,m_layer.m_transform.position.x,m_speed * Time.delta)),
0,
Mathf.Lerp(m_transform.position.z,m_layer.m_transform.position.z,m_speed * Time.delta))); //Mathf.Lerp(float a,float b,float t)函数表示:从点a以速度t移动至点b

这个方法似乎不需要自动寻路组件NavMeshAgent,不过NavMeshAgent用得更多一些,以下的两个方法都是基于NavMeshAgent的。


设置网格自动寻路的步骤:

1.将要进行Bake(烘焙)的场景设置为static(一定要保证Navigation Static是被勾选的):

2.通过Window -> Navgaition打开Navigation界面进行烘焙:

点击右下方的Bake(我第一次打开这个的时候一直没注意到这个Bake选项,还以为是这个选项没了!!!),等待它烘焙完成。还有另外一种烘焙方式,参见另一篇文章:http://blog.csdn.net/larry233/article/details/52022735

3.烘焙前:

烘焙后:

方法二:

简单到不知道怎么形容这个方法…
代码如下:

//先在Start()函数中获得玩家的组件:
m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>(); //将自动寻路的目标设置为玩家所在位置
GetComponent<NavMeshAgent>().destination = m_player.m_transform.position;

方法三:使用NavMeshAgent.Move()方法

这个方法是我最初使用的,但是出了很多意想不到的问题,我在正确烘焙场景后解决了这个问题,并使该方法正确执行了。代码如下:

NavMeshAgent m_agent;   //寻路组件

...   //省略中间代码

//在Start()函数中获得NavMeshAgent组件
void Start(){
... m_agent = GetComponent<NavMeshAgent>();
} //将敌方的速度转化为以s为单位
float speed = m_speed * Time.delta * 0.1f; m_agent.Move(m_transform.TransformDirection(new Vector3(0,0,speed)));

注1:不管哪种方法,都要将这些代码文件和enemy绑定在一起。

注2:虽然这三种方法都可行,但由于我初学unity,对它们的性能优劣以及差别并不了解,因此这些还有待研究。

Unity中使物体自动寻路的方法的更多相关文章

  1. unity中实现物体在一定角度范围内来回旋转

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class Rotate : ...

  2. Unity中Instantiate物体失效问题

    才开始学Unity,开始总是这样用Instantiate函数: GameObject temp = (GameObject)Instantiate(bulletSource, transform.po ...

  3. Unity中的各种寻找GameObject方法

    1.GameObject.Find():寻找Hierarchy面板中的activie 不为false的游戏对象: 路径如官方事例写法: public class ExampleClass : Mono ...

  4. Unity中的各种寻找GameObject方法归纳

    1.GameObject.Find():寻找Hierarchy面板中的activie 不为false的游戏对象: 路径如官方事例写法: public class ExampleClass : Mono ...

  5. Unity中获取物体的子物体

    如果想获取一级子节点 foreach (Transform child in this.transform) { Debug.Log(child.name); } 如果想获取所有子节点 foreach ...

  6. Unity中UI界面颤抖解决方法

    将Render Mode中属性改为Screen Space - Camera 摄像机挂在Canvas属性下会出现UI界面颤抖的效果. UI界面颤抖解决方式:将Render Mode中属性改为Scree ...

  7. 关于unity中C#使用WaitForSeconds的方法

    //我有一段这样的代码,我要实现3秒后执行内容,JS是这样写的 function Update () { load (); } function load (){ //等待3秒执行语句 yield W ...

  8. unity中让物体移动到鼠标点击地面任一点的位置(单击移动和双击暂停移动)并生成图标

    using UnityEngine; using System.Collections.Generic; using UnityEngine.EventSystems; using UnityEngi ...

  9. Unity中激活子物体

    void GetChildrenAndSetActive() { Transform[] imageTargetObjects = GetComponentsInChildren<Transfo ...

随机推荐

  1. 【Stage3D学习笔记续】真正的3D世界(三):纹理效果

    混合模式: 代码 示例是<Stage3D指南>中的直接弄出来的,可以通过点击键盘上的Q.W.E这3个按键,更换混合模式.模型和纹理,可以直观的查看不同混合模式的效果,住:下方的地形使用&q ...

  2. C#中反射的使用(How to use reflect in CSharp)(1)

    最近想做一个插件式的软件给公司的监控用,初步的想法是使用C#去反射Dll,Invoke其中的方法.此文仅供开发参考,不涉及原理,98%的代码以及2%的废话. 测试Solution是这么建的(.NET ...

  3. 实战:ORACLE SQL Performance Analyzer

    通过 SPA,您能够依据各种更改类型(如初始化參数更改.优化器统计刷新和数据库升级)播放特定的 SQL 或整个 SQL 负载,然后生成比較报告,帮助您评估它们的影响. 在 Oracle Databas ...

  4. shell修改文件名(一)

    假如文件名是:time_filename.txt 改成filename_time.txt.例如20111111_me.txt改成me_201111111.txt要如何修改? #! /bin/sh fo ...

  5. 如何选择一个 Linux Tracer (2015)

    http://www.oschina.net/translate/choosing-a-linux-tracer

  6. javascript——touch事件

    前言 诸如智能手机和平板电脑一类的移动设备通常会有一(capacitive touch-sensitivescreen),以捕捉用户的手指所做的交互.随着移动网络的发展,其能够支持越来越复杂的应用,w ...

  7. 简单改写SQL达到优化目的

    select * from (select t.row_id, t.supplier_name, t.tel, address, t.contact, t.contact_post, t.contac ...

  8. JAVA_Reflection

    package com.qf.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; imp ...

  9. ambassador docker container linking

    http://docs.docker.com/articles/ambassador_pattern_linking/

  10. [转]ORACLE日期时间函数大全

    本文转自:http://www.cnblogs.com/chuncn/archive/2009/04/29/1381282.html ORACLE日期时间函数大全 TO_DATE格式(以时间: ::2 ...