【VR案例】虚拟现实项目实战纪实
【虚拟现实项目:1.项目介绍】
第一章节的内容通常都是比较肤浅的,当然,这个项目目前已经进行到AI设计的部分了,一如既往,给出所有目前的进度,Github见。
首先,简单介绍一下这个项目。
这个项目的主要目的就是将我们学校数字化,然后玩家可以通过虚拟现实装备畅游整个校园,例如去各个部门,可以获得相关的专业课程的信息等。然后还会加入类似看门狗那种虚拟现实的小游戏丰富一下。
这将是一个伟大而漫长的项目,在我有生之年都未必会完成,所以,我们的任务就是为这个项目搭建出一个前期的系统,实现基本的功能。
这个一个小组项目,下面就先介绍一个这个项目的成员:
组长:茶水
成员:2个中国人和3个印度人,没错,是印度人。
那么现在就来说明一下这个项目的一些文件结构吧,图1
两个大文件夹,
_CS410,存放正式的项目资源。
_For Test_, 存放用与测试用的资源而已。
每个大文件夹下面都有6个一样文件夹,分别用于各人自己的成果。
我的文件夹是Haikun,用拼音读得出的就是中国人的,读不出的就是印度人的。
其他的文件夹就是一些插件资源了,图2
其中Easy Save 2这个著名的插件大家都很熟悉的。
FX Mega Pack,丰富粒子系统。
GameTemplate,类似与lego之类的模型模板,方便建模。
OVR,Oculus 的插件,就是那个虚拟显示的作品。
Pro Core 3D 开发套件。全套。
Tuscany,oculus的官方demo。
那么现在先介绍一下目前的AI进度吧,图3
这个demo位于,_For Test_/Haikun/Scenes/HHK_Test_4
我们想要模拟一些校园的正常生活,如上图,例如会跑去某些地点,使用一些东西,例如吃饭,聊天,打电脑等,如果这些设施正在使用,AI则会排队等候,直到有空位。目前这个AI的模型已经初步建立起来了,下一步将会移到Play Maker里面,实现更丰富的AI行为。
【虚拟现实项目:2.路点系统】
电脑,其实并没有我们想象中那么聪明,所以不能指望他们能按套路的在地图上行走和互动,他们需要一些适当的指引,而这个指引,就是路点系统了。
下图是茶水设计的一个简易的路点系统,1,(暂定)
能称之为一个系统,当然不能只是几个散点随便分布在地图上而已。我们需要将他们组织起来,使之成为一个有组织的系统。
一级路点:大地点,场地。这是一个比较抽象的东西,通常用来表示一个区域,例如一个大厅,一个房间等。
二级路点:小地点,坑。这是一个比较实在的东西,通常用来表示一个位置,或且设施,例如一张桌子,一个电脑,一个电话等。
排队线:就是排队嘛。
以下一张图告诉你,这个路点系统的基本结构,2
如图所示,区域真的只是一个抽象概念而已,就是一个Trigger而已,坑则是具体可以使用的一些设施,例如电脑,桌子,椅子等。至于排队线,则是一个看不见摸不着的transform而已。
路点三剑侠的脚本位于,3
========================================================
如何配置这些路点呢?
首先,创建一个空的对象,然后添加组件,4,然后他就是区域路点了。
然后根据实际情况,设置好这个trigger的大小,通常和一个房间,或且一个大厅之类的区域相等吧。
然后又创建一个空对象,然后添加组件,5,然后他就是坑路点了。
同样,根据实际情况,设置好trigger的大小,通常就是这个设施的使用范围的大小吧。
目前这两个对象都是没有render的,因为他们都是抽象的东西,好了,至于具体的设施的模型,可以作为坑spot的孩子挂在spot之下,如图,6
最后,继续创建一个空的对象,然后添加组件,7,然后他就是排队线了。
然后,排在适当的位置,他就是排队线了,注意Z轴的方向,这个是排队线的正方向。
========================================================
如何组织起来呢?
在适当的位置,配置好适当的东西,例如,一个区域内有若干个坑,和一个排队线。8
然后我们开始配置区域的一些参数,9
Place_name,就是这个区域的名字啦。个人喜好,随便起。
然后就是配置好属下的坑对象和排队线了。
然后就是坑的参数配置,10
Place_name, 坑名,个人喜好。
mix,max time,最小个最大时间,这个是一个随机的范围,表示这个坑的使用时间而已,如果NPC超过使用时间,则会离开。
Force_to_leave_time_scale,强制离开时间缩放,用于防止bug而设计的参数,实际操作中,会发生坑的状态被锁死的情况,即明明NPC离开了,本设施应该为未使用状态,但是却会被锁定在正在使用状态,应该是因为NPC数量太多,导致物理引擎处理不过来,引发的锁死bug。所以这里用过硬编码手段,假装修复这个bug。其实bug还是bug,只是没有那个bug而已了。
Next_place, 下一个指定/必须去的区域,可为空。
好了,基本上,一个简单的路点系统就配置好了,测试场景位于,11
至于NPC是如何和路点系统交互的,则留待下章节。12
【虚拟现实项目:3.NPC设计】
首先,我们对路点系统做出了一些小的更新,
修改1,1
在WP1中,我们添加了一个Secreted的选项,这个选项的作用是指明本地点是隐藏地点,(感觉好似没解释- -!),嗯,简单来说就是,这个地点不是一个活动链中的首发地点,这个地点并不可以在全局查询中得到,所以不可能成为首发地点。或且这样理解吧,NPC首先会在全局查询所有非隐藏的地点,然后选择一个前往。所以这个隐藏地点就不可能被查询得到。那怎么才能去到这个地方呢?只能是通过Spot中的指定后续了。
举个实际例子,例如一个超市,有很多货架,和收银处,或其他设施。如果一个NPC进入到一个超市,他不会直接去收银处的,因为他没有东西需要结账,所以他会先去货架,然后拿了东西后,才会去收银处结账。
修改2,2
为Spot添加了两个动作名,一个是使用时的动作,一个是退出时的动作,所以我们现在可以通过Spot来定义,NPC应该使用哪个Animation来播放正确的动作了。
**************************************** 咸湿分割线 ***************************************
好了,当我们摆设我们的路点系统后,我们需要设计一些NPC来测试路点的效果。所以本次我们就使用PlayMaker来设计NPC的状态机。
本章节,我们先设计出一个简单的NPC状态机,使其能自由地在地图中的各各区域自由行走或者使用设施。
先看看状态机的截图吧,3
直观,明了。
那这里先简单介绍一下他的流程吧,(明显在凑字数,明知道虽然很难通过3000字把状态机说明白。)
首先,我们【START】设在了Walking to place 是有目的,这个目的目前还没有用到,就不管了先。
首先,我们进入到【Walking to place】,如果没有目的地,那么就跳转到【Looking place】去查找一个,如果到了目的地,那么就转到【Looking spot】,然后查到spot,或者排队,如果排队人数超过限制的话,就跳回【Looking place】查找别的地点了,如果spot满了,跳去排队的路上【Walking to waiting line】,到达指定排队地点,跳去【In waiting line】,同时,期间或拍一些无聊的pose之类的,然后跟随排队线,不断往前移动,直到有新的spot可用,然后跳到【Walking to spot】,到达指定地点后,跳到【In spot】,时间结束后,跳到【After spot】处理一些后续的事情,例如播放离开动画之类的,然后如果有后续地点,则直接前往【Walking to place】,如果没有,则重新查找一个【Looking place】。然后循环。
是不是很简单呢,:P.
那么我们来快速一览角色的Animator的设计吧。就这么简单直接。4
其实本章节要说的东西也不多,但是思路比较多,虽然思路就是以上所说的,但是一图足以说明状态机的复杂性,这个状态机只是属于简单的而已,后续还需要加入更到的状态节点。
本次更新迟的原因是因为代码部分的原因,当然,代码有了,组件有了,大家要使用的时候,还是需要知道如何调用的,所以下章节则会说明一下路点系统的API,这样大家也可以在自己的项目中直接使用茶水的路点系统了,也可以和大家分享一下API的一些设计心得。
本章节测试场景放在 Asset/_For Test_/Haikun/Scenes/HHK_Test_5.unity
【虚拟现实项目:4.路点系统的API】
如上次所说,我们有了组件,也说明了如何配置组件,那么这次先来个API说明,也好让大家能在自己项目中直接使用茶水的组件,如果有帮助的话。(貌似是英文倒装句)。
好了,既然是纯API说明,那么贴图也是比较无力的,但是也贴点吧,
路点系统的代码在这里,1
哈哈,这样就有一个贴图了。
那么首先出场的是,1级路点,又叫区域路点,2
如红线所标示的那几个函数。
HHK_Way_Point_Level_1[] FindAllPlace(bool include_secreted = false)
是一个静态函数,用于返回一个包含所有1级路店的数轴,参数1标示是否包含隐藏地点。
bool Is_In_This_Place(HHK_Role_Tags role)
查询当前角色是否在这个区域,参数1是角色的标签组件,(PS:每个角色都应该包含一个角色标签组件)
HHK_Way_Point_Level_2 Any_Available_Spot()
随机返回一个可用的2级路点,如果没有则返回NULL。
然后出场的是,2级路点,又叫坑,如果你喜欢的话(有一个英文倒装句),3
bool Is_In_This_Place(HHK_Role_Tags role)
查询当前角色是否在这个坑上,或是否正在前往这个坑,简单来说,就是查询当前角色是否霸占这个坑。
bool Join_From_The_Waiting_Line(HHK_Role_Tags role)
是否成功从排队线上获得这个坑的使用权,如果有空的坑可用,则返回ture并且霸占这个坑,否则返回false。
bool Leave_From_This_Place(HHK_Role_Tags role)
离开这个坑。返回ture则成功离开,返回false则查无此人,应该不会出现这种情况的吧。。。
bool Is_Ready()
此坑是否可用。
最后出场的选手是排队线,4
bool Is_In_This_Place(HHK_Role_Tags role)
这个函数应该是老朋友,查询当前角色是否在这个排队线上。
bool Join_To_This_Place(HHK_Role_Tags role)
当前角色加入排队线,如果排队线过长,则返回false,拒绝加入。
void Leave_From_This_Place(HHK_Role_Tags role)
当前角色离开排队线。
HHK_Role_Tags At_Index(int index)
查询排队线上的指定位置的角色,返回此角色标签。
HHK_Role_Tags[] Get_Who_In_This_Place()
查询所有在排队的角色,返回一个角色标签数组。
Vector3 Get_My_Position(HHK_Role_Tags role)
返回当前角色在排队时候的位置。其实这个函数用于获得角色排队的时候,应该站在那里,避免一堆人站一个点上。
int Get_My_Index(HHK_Role_Tags role)
返回当前角色在排队线上的位置。
=================================== Done!!!===================================
基本上,有了以上的API,就可以玩转茶水的这个低级路点系统了。
具体的demo在这里,5
有兴趣的同学可以查看一个那个叫《Michael FSM》的NPC的状态机,用playmaker做的,自定义的状态机代码在这里,6
好了,迟更新的原因肯定是有的,因为在弄模型,所以现在现阶段的主要目标都是放在建模上面,至于代码部分,基本的需求已经满足了,所以第一阶段的代码已经差不多完了,建好这个模型之后,就会进入第二阶段了。
大家可以看看我们目前的模型,位于这里,7
粗略模型,不过大致上的就这个结构了,目前门能动,当角色靠近时,会自动开关。
没有灯,目前有点小恐怖,哈哈。之后会安装一些灯和摆放一些家私吧。
项目地址:Github
【小啦啦(茶水)原创作品,首发蛮牛论坛 http://www.unitymanual.com,转载请保留此行。】
——小啦啦(茶水)——