您的位置:首页 > 移动开发 > Unity3D

Unity3D 从入门到放弃 ——巡逻兵 观察者模式

2017-04-19 22:56 309 查看

Unity3D 从入门到放弃

——巡逻兵

作业需求

游戏规则:

创建一个地图和若干巡逻兵;

每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址。即每次确定下一个目标位置,用自己当前位置为原点计算;

巡逻兵碰撞到障碍物如树,则会自动选下一个点为目标;

巡逻兵在设定范围内感知到玩家,会自动追击玩家;

失去玩家目标后,继续巡逻;

计分:每次甩掉一个巡逻兵计一分,与巡逻兵碰撞游戏结束;

先上UML图:
4000



做完后的游戏动画:



(这游戏估计可以玩一天)

PS:源码在GitHub上,链接如下:

https://github.com/tpisntgod/learnUnity3d

下面说一下这个的坑点:

游戏制作过程:

实例化部分:

两个预设:



两个实例的动作控制如下:

主角Animator:



Patrol Animator:



其中Speed属性判断动作,toDie触发器触发死亡。

将两个预设加上刚体(虽然没用上物理学),和胶囊触发器, 设置触发器的大小即可。

地板和墙用plane和cube实现即可。

游戏的一些特点:

巡逻兵(Patrol)的行走模式,如何实现循环走动?

动作结束后,在动作结束回调函数里再添加动作。

巡逻兵有3个动作,idle(一段时间内站着不动),walk和run,为什么强行搞walk和run两个动作呢,因为为了改巡逻兵的速度和Animator的某些参数,达到动作状态转移的目标,这样,巡逻兵在没有发现主角到自己区域的时候不会移动的很快,同时是一个走路的动作,而主角到了巡逻兵所在的区域,巡逻兵会加快速度并且换一个动作(其实应该换跑步动作,只不过我下的模型没有跑步动作…所以换了个攻击动作),这样可以体现出发现敌人前后的区别,让游戏更好玩。

当巡逻兵是idle状态的时候,(刚开始游戏或者由于主角离开了一个区域,到了新的区域),我们就会调用idle动作,当站着不动的时间消耗完毕的时候,我们就会调用回调函数,从而让巡逻兵做预先设置好的下一个动作,空闲->往左走->往上走->往右走->往下走->如此循环,就实现了巡逻的功能。



巡逻兵添加动作后,移动过程中碰到墙或者走到区域边界怎么办?

利用巡逻兵Collision碰撞检测方法,检测到碰撞,发送信号,销毁现在的动作,再添加往相反方向走的动作。

巡逻兵动作切换:

巡逻兵动作变换的时候,需要销毁该对象之前的动作,我们可以在每个具体动作结束的时候删除那个动作,保证巡逻兵所有时刻都只有一个动作。

发布与订阅模式(观察者模式)的应用。



当主角身上发生了某些事情(进入某个区域,与patrol碰撞,可以通过各种trigger实现),我们就可以发布相应信息,根据信息中参数的不同,对主角“有兴趣”的订阅者(patrol和SceneController)则做出相应动作(patrol会追击主角(主角进入自己区域),放弃追击(主角离开自己区域),停止动作(主角死亡,游戏结束),SceneController发布死亡信息(主角死亡),加分(到新区域))。

Trigger实现事件的检测:



小技巧:使用Quaternion.LookRotation和Quaternion.Slerp两个函数实现主角的旋转。

下面是一些坑点(不对,貌似就一个特别坑的):

主角的Animator从any state到die的状态转移条件不能仅仅是:



因为die也属于any state,当我们把isAlive设置为false的时候,会不断满足条件,触发这个状态转移,从而一直做死亡动作。

应该是这样:



当我搞完这个之后,我以为动作就没问题了,结果发现还是一直死,终于在3d群的dalao的指导下发现了要关闭动作循环,动作的一个Loop Time属性,不打勾就可以了,不会一直循环做动作了。

总结:上课认真听啊!!(暴露了什么?)方便下课做,做的时候真的是各种bug,但是你写出来了就会觉得能理解各种模式什么的了。

PS:某大佬博客链接,我参考他的做的:

http://blog.csdn.net/mycodecodecodecode/article/details/70209904
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity3d 游戏