查看: 7937|回复: 8
打印 上一主题 下一主题

[其他] unity3鼠标点击移动以及自动寻路(3)

[复制链接]

25

主题

5

听众

358

积分

设计实习生

Rank: 2

纳金币
300
精华
0

最佳新人

跳转到指定楼层
楼主
发表于 2014-1-20 17:36:45 |只看该作者 |倒序浏览
我们还是接着前面的讲,我们前面已经实现了,如何取得目标地点,看向目标地点,并向其移动。下面还有一点就是绕过障碍物。
   众所周知自动寻路是所有游戏的一个难点,属于AI人工智能的范畴,其算法异常复杂。不过unity3d给我们配备一套非常成熟的组件来解决这一问题。今天一起来看下unity3D自带的自动寻路系统
   unity3D的自动寻路系统包括3个部分
   第一:Navigation:这个是用来 产生NavMesh(导航网格)。因为导航网格决定我们的角色(带有导航网格代理的角色)活        动的范围
   第二:NavMeshAgent :导航网格代理,NavMeshAgent组件需要附着寻路的角色身上
   第三:  NavMeshAgent :这个组件主要是用来构造寻路角色的寻路路径的某个部分,比如我们有时需要怪物在寻路过程中从一个固定的地方移动到另一个固定的地方
    大致了解一下之后我们开始制作,首先创建一个工程文件呢,制作场景如图:
    QQ截图20140120170155.jpg

非常简单的场景:两个Cube,一个作为我们的移动物体一个做为地面,移动物体命名为person,地面命名为floor。
下面在Unity3d编辑器的菜单下:Window->Navigation,这是我们可以发现编辑器的某一部分出现了一个Navigation窗口如图:
QQ截图20140120170624.jpg

在Hierarchy下选中floor (就是那个地面),然后我们在Navigation面板中的Object选项卡下找到Navigation Static复选框,勾选它,然后点击Navigation面板右下角的Bake按钮:
      这时我们发现Scene窗口中的地面 变成如图所示的情况:

QQ截图20140120170855.jpg

并且在Project面板下面多出了一个文件夹,且此文件夹出现了一个子文件NavMesh:
QQ截图20140120171425.jpg

这样我们的NavMesh 就已经制作好了
下面我们开始制作导航网格代理 ,选中我们的person 游戏物体,然后添加NavMeshAgent  组件,添加方式Component->Navigation->NavMeshAgent ,你会发现robot身上出现了一个类似胶囊体碰撞器的绿色线框的包围体 ,在Inspector多了一个NavMeshAgent  组件
QQ截图20140120171906.jpg

看下这些属性的含义:Radius:导航代理的半径,我们可以适当的调节一下这个值

Speed :这个属性代表这个导航网格代理寻路时可以达到的最大速率

Acceleration :加速度,表示代理的速度从0加速到Speed时的最大的加速度

Angular Speed :最高的角速度

Stopping distance : 制动距离,当代理据目的地的距离小于这个值时开始减速

Auto Traverse OffMesh Link :自动移动并关闭OffMeshLinks,这个选项对于我们利用程序来操纵后面我要介绍的OffMeshLink很关键,

Auto Repath   自动重新寻路,如果发现现有路径已失效,那么它将获得新的路径,这个选项我们一般将其勾选上

Height  : 导航代理的高度。

Base Offset : 基本偏移,我们可以通过调整这个变量来调整代理自身的包围盒

Obstacle Avoidace Type  : 代理躲避的水平,一般我们选默认的High Quality就行了

NavMesh Walkable :导航网格代理可以通过的网格层类型
这里只是一个大概意思,具体调节起来还是非常复杂的。想熟练掌握这些参数还需要不停的联系。我们这些都用默认参数,我们的目的是用代码来控制物体移动,unity3D给我们提供了一个NavMeshAgent 导航网格代理组件所对应的类   
我们看NavMeshAgent这个类,Unity菜单:help->Scripting Reference 。我们找到这个类,
QQ截图20140120172535.jpg

参数还是非常多的,我们简单介绍一些常用的变量和方法:
1.destination
我们可以这样对导航网格代理设置目的地:
nma.destination = Vector3类型的值。相当于nma.SetDestination( Vector3类型的值 )

2.stoppingDistance
这个与Inspector面板中的Stopping Distance对应,一下再不涉及与Inspector面板中的属性对应的变量

3.velocity
导航网格代理周游时的实时速度,非常重要

4.nextPosion
顾名思义,也就是下一个位置,在Update函数中打印这个属性,你会发现打印出的结果与这个导航网格代理周游过的路径一致

5.steeringTarget(只读)
这个属性是相当重要的,它指的是导航网格代理在导航网格中周游时所经过的拐点,这对于制作寻路网游同步角色的Transform是相当重要的,因为导航网格的寻路路线是直线,我们只需将其寻路的拐点与旋转角度告诉给服务器端,有服务器端广播出去,然后再写一个执行Transform同步的脚本(是特制的)绑定在非角色玩家身上就可以了。

6.desiredVelocity(只读)
这个属性说实话我用的不多,指的是导航网格代理的期望速度,与其当前速度不是等价的。

7.remainingDistance( 只读 )
导航网格代理离目的地还剩的距离,如果其值为0,那么代理已经到达了目的地了,所以我们可一个这样判断一个导航网格代理是否到达了目的地:
if( nma.remainingDistance == 0 ){
//执行行为

}

8.isOnOffMeshLink
导航网格代理当前的位置是否位于OffMeshLink,因为这个牵扯到了另一个组件,我会在后面说的

重要方法:
1.SetDestination( Vector3 v )
设置目的地,与nma.destination = v一样的,你想怎么用都行,只是这个函数在设置目的地成功后返回***e,否则返回false,就只比调用属性多了一个返回值

2.ActivateCurrentOffMeshLink( bool activated )
返回值为空
与OffMeshLink有关,当activated为***e激活OffMeshLink,后面会讲到的

3.CompleteOffMeshLink ()
让导航网格代理完成在OffMeshLink上的周游,后面会讲的

4.Move( Vector3 v )
让导航网格代理朝向量v的世界坐标系方向平移v的长度

5.Stop()
让导航网格代理停止寻路,但此寻路状态可以靠下面一个函数恢复到寻路状态,并且目的地也与上次一样

6.Resume()
恢复寻路状态,此时角色会在上一次执行了Stop函数停下来后恢复当时的状态,目的地为上一次的目的地
这些了解以后,就可以开始动手写代码了,
新建一个c#文件命名为My_Navigation,输入一下代码
using UnityEngine;
using System.Collections;

public class My_Navigation : MonoBehaviour {
    private RaycastHit hit ;
    private NavMeshAgent nma;
        void Start()
        {
                nma = gameObject.GetComponent<NavMeshAgent>();
        }
    void Update ()
        {
        if(Input.GetMouseButtonDown(0))
                {

                        //得到射线碰撞点
                        Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);               
                        if (Physics.Raycast(ray, out hit, 100))
                        {
                                
                                if(hit.collider.gameObject.name=="floor")
                                {

                                        //如果碰撞物体为floor,讲物体运行的目的地设置为碰撞点
                                        nma.SetDestination(hit.point);
                                }
                        }
     }
        }
}
代码非常简单,获取碰撞点之后将碰撞点做我物体运行的目的地。即可。
将代码附加到person  物体上,运行游戏,鼠标点击地面,效果还不做吧!
下面我们将地面做成入图
QQ截图20140120174021.jpg

运行游戏,点击地面。发现物体只在我们生成NavMesh 的地方运动,利用这一点我们可以方便的绕过障碍物。哈哈,就写到这里了。










已有 1 人评分纳金币 收起 理由
艾西格亚 + 5

总评分: 纳金币 + 5   查看全部评分

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

2317

主题

54

听众

2万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
20645
精华
62

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2014-1-20 17:49:24 |只看该作者
不错的分享,谢谢!
回复

使用道具 举报

74

主题

2

听众

3549

积分

中级设计师

Rank: 5Rank: 5

纳金币
-100
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2014-1-20 20:22:33 |只看该作者
不错的教程,unity 4.3.3版本好象有变化了
回复

使用道具 举报

74

主题

2

听众

3549

积分

中级设计师

Rank: 5Rank: 5

纳金币
-100
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

地板
发表于 2014-1-21 19:52:26 |只看该作者
真的有点一点不一样了
回复

使用道具 举报

74

主题

2

听众

3549

积分

中级设计师

Rank: 5Rank: 5

纳金币
-100
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

5#
发表于 2014-2-7 14:48:34 |只看该作者
不错的教程哦谢谢
回复

使用道具 举报

10

主题

8

听众

1872

积分

助理设计师

Rank: 4

纳金币
188
精华
0

活跃会员

6#
发表于 2014-2-7 16:13:30 |只看该作者
期待后续教程啊。。
回复

使用道具 举报

0

主题

1

听众

287

积分

设计实习生

Rank: 2

纳金币
1
精华
0

最佳新人

7#
发表于 2014-2-12 08:43:16 |只看该作者
不错的教程,很详细
回复

使用道具 举报

0

主题

1

听众

1198

积分

助理设计师

Rank: 4

纳金币
261
精华
0
8#
发表于 2014-2-12 15:45:13 |只看该作者
感谢楼主分享
回复

使用道具 举报

0

主题

1

听众

2458

积分

中级设计师

Rank: 5Rank: 5

纳金币
0
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

9#
发表于 2014-2-22 21:06:54 |只看该作者
谢谢楼主
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-23 20:35 , Processed in 0.152193 second(s), 35 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部