开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:1963

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 5380|回复: 34

[伊利丹·怒风] Unity A星寻路实现之巡逻篇

[复制链接]  [移动端链接]
排名
1254
昨日变化
3

62

主题

357

帖子

2435

积分

Rank: 9Rank: 9Rank: 9

UID
35466
好友
21
蛮牛币
3868
威望
0
注册时间
2014-7-21
在线时间
820 小时
最后登录
2017-11-17

专栏作家

发表于 2017-4-11 08:30:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 wind2006 于 2017-4-11 08:30 编辑

背景

     上一篇完成的内容是 Unity A星寻路实现之动态障碍物篇。本篇的背景完全源自上一篇的调试和验证的需求,为此需要构建怪物精灵的随机移动功能。实际上我只是让精灵具有具有巡逻的功能,也就是我给它提供几个固定的位置点,它就按照顺序在这几个点的位置,循环移动。看起来这个需求并不是特别复杂,实现序列点的移动即可,我曾经也写了系列的文章

时光煮雨 Unity3d 序列目标点的移动①

时光煮雨 Unity3d 序列目标点的移动② 总结篇

实际情况并没变想象的那么简单了,如果在A星寻路的基础上添加序列点的移动就没有那么简单了,原因是这样,首先Astar算法获得寻路路径就是序列点集合,而改进型Astar算法又是先直线移动遇到障碍物切换到Astar寻路移动。所以巡逻算法是在Astar改进型寻路算法之上再做一次序列点移动,没有一步步坚实的基础和积累是不能做到的。

最终实现效果如下图所示:

main

实现

       需求明确了,下面说下我的想法,首先寻路是有持续时间的,也就是有开始时间有结束时间,实现序列点的移动最简单的办法就是结束了一个点移动,开始进行下一点的移动,周而复始来循环移动。所以我们就需要解决两个技术问题即可:

1、如何实现基于Astar寻路算法移动基础上的逐个巡逻点的移动?

2、如何周而复始的在巡逻点进行移动?

先来回答问题1

如何实现基于Astar寻路算法移动基础上的逐个巡逻点的移动?

      我们最先想到的,也是最简单的办法是使用循环,但是我们知道Astar寻路是有持续时间的,循环如果不考虑时间的问题是无法确定是否Astar已经移动到了巡逻点(前面也介绍过如果使用时间还需要加上几何位置两个条件来确定是否Astar移动结束,程序复杂性很高),再说我也没有采用基于时间线的移动,而是采用几何位置的达到判断,所以采用循环的方式是不可取了。

     实际上循环本身也是种序列,这里我们采用的是序列通知的方式,也就是如果到了巡逻点1,那么发出通知,告诉控制逻辑,可以向寻路点2出发了,开始移动,到达了巡逻点2,再发出通知。。。这样就完成了逐个寻路点的移动了。这个是比较通俗的语言,换成程序语言通知是什么呢?对了聪明的读者一定也想到了,那就是事件或者叫做回调。实际上我也是用事件来做的(不懂得自己去恶补C#基础知识事件,委托)

首先定义委托和事件

[C#] 纯文本查看 复制代码
delegate void ArriveTargetSubjectHander(Vector3 vector3);

private event ArriveTargetSubjectHander OnArriveTarget = null;

  

在Astar寻路算法的到达目标点判断后面添加到达事件的调用

[C#] 纯文本查看 复制代码
if (Vector3.Distance(curenPosition, targetPoint) < 0.01f)
{
    Sprite2DPosition = targetPoint;
    StopAStarMove();

    OnArriveTarget(targetPoint);    
}

  


我们再看下OnArriveTarget的回调函数,事件回调函数的绑定在Start函数中完成的

[C#] 纯文本查看 复制代码
void Start()
{
    OnArriveTarget+=(
    //_arriveTargetSubject.Subscribe(
    t =>
    {
        if (_patrolQueue.Count > 1)
        {
            Vector3 target = _patrolQueue.Dequeue();
            _patrolQueue.Enqueue(target);

            StopAStarMove();
            Debug.Log(\"MixMoveTo:\" + target + \" t:\" + Time.realtimeSinceStartup);
            MixMoveTo(target);            
        }
    });
}

  

我们看到回调函数是用Lambda表达式绑定的,会从一个队列中Dequeue下一个巡逻点,然后启动MixMoveTo(target); 进行下一次AStar寻路移动。至此第一个问题解答完毕。

让我们再来回答问题2

如何周而复始的在巡逻点进行移动?

实际上在1中的最后一段代码,我也已经贴出来了,主要就是使用一个循环队列来实现,记住队列是“先进先出”将一个队列收尾相连就是一个循环队列

[C#] 纯文本查看 复制代码
Vector3 target = _patrolQueue.Dequeue();
            _patrolQueue.Enqueue(target);

  

关键就是这两行了队列弹出一个值,然后加入队列的中,就是这么简单

下面我们看下巡逻的初始值构造

初始化精灵位置,添加两个巡逻点

[C#] 纯文本查看 复制代码
scriptQXPlayerController.Sprite2DPosition = new Vector3(mixSpriteSetting.X, mixSpriteSetting.Y + 300);
scriptQXPlayerController.AddPatrolPosition(new Vector3(800, 600, 0));
scriptQXPlayerController.AddPatrolPosition(new Vector3(800, 1100, 0));

  

这个是精灵类中的 AddPatrolPosition函数就是往队列中加入值即可

[C#] 纯文本查看 复制代码
/// <summary>
/// 向巡逻队列中添加位置坐标
/// </summary>
/// <param name=\"vector3\"></param>
public void AddPatrolPosition(Vector3 vector3)
{
    _patrolQueue.Enqueue(vector3);
}

  

至此问题2也解答完毕了。

总结

       本篇也是Astar寻路算法的高级衍生篇,希望对各位读者的学习和开发有所帮助。

main.png

本帖被以下淘专辑推荐:


回复

使用道具 举报

5熟悉之中
680/1000
排名
4032
昨日变化
25

4

主题

216

帖子

680

积分

Rank: 5Rank: 5

UID
211167
好友
2
蛮牛币
2119
威望
0
注册时间
2017-3-10
在线时间
174 小时
最后登录
2017-11-18
发表于 2017-4-11 09:52:08 | 显示全部楼层
不错,虽然不怎么看得懂

回复 支持 反对

使用道具 举报

3偶尔光临
193/300
排名
10351
昨日变化
3

0

主题

43

帖子

193

积分

Rank: 3Rank: 3Rank: 3

UID
155943
好友
0
蛮牛币
240
威望
0
注册时间
2016-7-8
在线时间
76 小时
最后登录
2017-9-14
发表于 2017-4-11 11:04:50 | 显示全部楼层
确定对新手来说有点看不懂···

回复 支持 反对

使用道具 举报

5熟悉之中
610/1000
排名
2934
昨日变化
3

3

主题

48

帖子

610

积分

Rank: 5Rank: 5

UID
131585
好友
0
蛮牛币
1383
威望
0
注册时间
2015-12-13
在线时间
165 小时
最后登录
2017-11-1
发表于 2017-4-11 12:53:50 | 显示全部楼层
就是看不懂,也要先收藏

回复 支持 反对

使用道具 举报

7日久生情
2017/5000
排名
606
昨日变化

1

主题

531

帖子

2017

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
111260
好友
0
蛮牛币
7310
威望
0
注册时间
2015-6-30
在线时间
343 小时
最后登录
2017-10-17
发表于 2017-4-11 13:02:48 | 显示全部楼层
不错,虽然不怎么看得懂
[发帖际遇]: 一个袋子砸在了 漫无边际 头上,漫无边际 赚了 1 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

5熟悉之中
574/1000
排名
3884
昨日变化
2

0

主题

67

帖子

574

积分

Rank: 5Rank: 5

UID
55444
好友
2
蛮牛币
955
威望
0
注册时间
2014-11-14
在线时间
211 小时
最后登录
2017-11-16
发表于 2017-4-11 15:44:51 | 显示全部楼层
巡逻点设置成随机的坐标会效果更好,不过带来的问题就是要保证巡逻点不能过于集中。
[发帖际遇]: yaoziooxx 乐于助人,奖励 3 蛮牛币. 幸运榜 / 衰神榜

回复 支持 1 反对 0

使用道具 举报

6蛮牛粉丝
1314/1500
排名
4734
昨日变化
5

0

主题

858

帖子

1314

积分

Rank: 6Rank: 6Rank: 6

UID
189581
好友
0
蛮牛币
1620
威望
0
注册时间
2016-12-5
在线时间
220 小时
最后登录
2017-9-15
发表于 2017-4-12 10:03:41 | 显示全部楼层
很赞  给力啊 强大啊

回复 支持 反对

使用道具 举报

排名
17647
昨日变化
10

0

主题

43

帖子

86

积分

Rank: 2Rank: 2

UID
214759
好友
0
蛮牛币
35
威望
0
注册时间
2017-3-27
在线时间
19 小时
最后登录
2017-5-14
发表于 2017-4-16 09:12:24 | 显示全部楼层
不错,虽然不怎么看得懂

回复 支持 反对

使用道具 举报

7日久生情
2034/5000
排名
970
昨日变化
1

3

主题

414

帖子

2034

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
46577
好友
1
蛮牛币
2445
威望
0
注册时间
2014-9-24
在线时间
715 小时
最后登录
2017-11-16
发表于 2017-4-17 16:11:06 | 显示全部楼层
额,楼主最近是在做页游么

回复 支持 反对

使用道具 举报

排名
1254
昨日变化
3

62

主题

357

帖子

2435

积分

Rank: 9Rank: 9Rank: 9

UID
35466
好友
21
蛮牛币
3868
威望
0
注册时间
2014-7-21
在线时间
820 小时
最后登录
2017-11-17

专栏作家

 楼主| 发表于 2017-4-19 08:24:12 | 显示全部楼层
llupll 发表于 2017-4-17 16:11
额,楼主最近是在做页游么

没有,就是把深蓝的教程深度学习下,然后用Unity2d实现一遍

回复 支持 反对

使用道具 举报

3偶尔光临
154/300
排名
15597
昨日变化
15

0

主题

102

帖子

154

积分

Rank: 3Rank: 3Rank: 3

UID
137557
好友
1
蛮牛币
150
威望
0
注册时间
2016-2-25
在线时间
20 小时
最后登录
2017-4-20
发表于 2017-4-19 20:39:15 | 显示全部楼层
确定对新手来说有点看不懂·

回复 支持 反对

使用道具 举报

排名
1254
昨日变化
3

62

主题

357

帖子

2435

积分

Rank: 9Rank: 9Rank: 9

UID
35466
好友
21
蛮牛币
3868
威望
0
注册时间
2014-7-21
在线时间
820 小时
最后登录
2017-11-17

专栏作家

 楼主| 发表于 2017-4-20 08:25:38 | 显示全部楼层
Airo 发表于 2017-4-19 20:39
确定对新手来说有点看不懂·

谢谢支持,说白了就是队列+事件

回复 支持 反对

使用道具 举报

7日久生情
2206/5000
排名
823
昨日变化
6

16

主题

431

帖子

2206

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
7831
好友
2
蛮牛币
4513
威望
0
注册时间
2013-11-12
在线时间
769 小时
最后登录
2017-11-18
发表于 2017-4-20 18:40:58 | 显示全部楼层
风神。有时间看一下私聊消息。

回复 支持 反对

使用道具 举报

排名
1254
昨日变化
3

62

主题

357

帖子

2435

积分

Rank: 9Rank: 9Rank: 9

UID
35466
好友
21
蛮牛币
3868
威望
0
注册时间
2014-7-21
在线时间
820 小时
最后登录
2017-11-17

专栏作家

 楼主| 发表于 2017-4-21 08:30:54 | 显示全部楼层
370688535 发表于 2017-4-20 18:40
风神。有时间看一下私聊消息。

已回复你了

回复 支持 反对

使用道具 举报

排名
18326
昨日变化
15

0

主题

21

帖子

65

积分

Rank: 2Rank: 2

UID
207440
好友
0
蛮牛币
48
威望
0
注册时间
2017-2-20
在线时间
22 小时
最后登录
2017-10-13
发表于 2017-4-23 17:39:02 | 显示全部楼层
好东西。。。感谢楼主

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表