案例分享 | 制作跨平台3D军事动作游戏所面临的挑战
文章来源:
作者:<a href="http://taovr.com/home.php?mod=space&uid=5">vrman</a>
发布时间:2015年05月07日
点击数:
次
字号:小 大
UNITE 2015 BEIJING 于2015年4月18-20日在北京国家会议中心圆满举行。在这三天中来自全球20多个国家和城市的1万2千多位与会者,参与了全程12个专场118个议题的演讲日程,现场总共设立了71个展台近百个展商,更有218位媒体朋友与会并发布报道。
这是在案例分享专场中的一场课程,转载自CSDN.NET
UNITE 2015 BEIJING 案例分享专场:
申远 成都动鱼技术总监 所谓3D军事动作游戏并非只是简单的拥有回合式动作系统的卡牌,而是能够实时模拟、同步的3D动作游戏。在使用Unity引擎开发3D动作游戏的过程中,通常会遇到如何组织和实现所有关卡、优化性能等问题,在此,我想分享一下我们团队在《血战长空》开发过程中探索出的经验之法。 如何在Unity中组织并建立所有关卡? 找同类型游戏做参考 首先,如何在Unity中组织和建立关卡?第一件事就是找同类型游戏做参考,将它们的共性提炼出来,以此来避免浪费精力做出一些似是而非的东西。尤其对于小团队来说,有效的学习和模仿可以少走许多弯路。在开发《血战长空》游戏时,我们参考了IL2、War Thunder和Armed Assault等诸多飞行射击类游戏。 它们的关卡编辑器都有一些共性,比如Unit Spawner(单位生成和初始设定)决定生成的是什么,即对应游戏过程中的哪个部分,开发者可以用它写一个下达框;Unit Waypoint(单位之后的去向和动作)是在过程中干什么,选择作战还是不开火?一定要作战怎么撤退?最后一个是Trigger(条件和触发),定一个条件,用于脚本交互。 即使是编写三维场景,也需要契合逻辑。拿Trigger来讲,一种是单位的Trigger,还有一种比较特殊的是炸弹Trigger,炸弹掉落到这一区域,会让单位掉血,开发者需要确保在有限的时间内它不会被炸毁。这些设计方式通过组件非常容易实现,开发者可以直接把一个关卡存储成Prefab。 在设计好初始单位、下一步动作路线以及触发条件反应后,又该如何定义一些比较特殊的关卡?来指引玩家按照既定顺序进行。比如有三个关卡,应该是先轰炸A后打B最后再打C,而不是倒过来。每一个单机游戏的Model都有不同的解决方案,要根据团队的实际开发能力、个人习惯以及项目类型来选择。 数据驱动还是代码驱动? 在关卡流程设计中,该选择数据驱动还是代码驱动?这个问题既简单又复杂,如果投资人或公司老板能够懂一些这方面的知识,那么游戏开发人员或许会少点心酸。数据驱动就是常说的可视化编程,优点是解放工程师,设计师可以消化掉所有流程部门的工作,不用添加程序就可以设置关卡,这对国内手游来讲是至关重要的功能。但同时存在诸多缺点,首先,开发者自创一套系统方案需要大量成本,每新入一个关卡设计师就需要重复教学。 最关键的问题是,团队花费大量时间来实现这么一大套系统,就意味着最快展现给投资人或给团队自身反馈的时间也会变长。有时候团队两三周没拿出什么对外的feature,并不是真的没有成果,只是可能是在实现底层、优化内层、搭建基础架构,这些繁芜系统的工作,在数据驱动的前期,尤为明显。 在对比数据驱动和代码驱动优劣之后,动鱼首先采用了纯代码驱动,使用Unity中的Coroutine功能对关卡流程进行快速设计并创建。通过代码驱动简单快捷的Hack属性,开发者可以先将关卡设计出来做成Demo交给投资人,然后再用数据驱动构建。这样,即使整个后续程序都没有开发完甚至没有开始,却可以很好地展示游戏性能。 而这种先代码后数据驱动的方式,对于关卡设计师来说,最High的事莫过于他们不用再求着程序员了,而程序员也不用特别费劲地折腾其他工程师。尽管结构是关卡里最重要的东西,但程序员一般不关心结构,这个权利要交给关卡设计师。 uScript还是playMaker? 确定驱动以后需要考虑的就是用uScript还是playMaker?uScript非常强大,类似于预代码生成器,支持预编一层代码,这样的好处就是速度非常快,但其预编译功能,既是优势也是劣势,每加一个关卡,就需要更新客户端。而playMaker则可以看做是一个状态机管理器,基本上想到的状态机功能都有,但最大的缺点是传值非常难,我们的解决方法是在action上留可编辑的variable,拖拽需要考虑的参数。 如果用来做线性游戏的话,则尽量一个state放一个action,在策划看来就非常可视化,每一个阶段都清晰地表明了动作,哪怕是瞬时的,如图1所示。多数关卡可以单纯通过已有的action组织出来,特殊的关卡可以专门写脚本,使用特殊的state和action。 在真刀真枪环境中如何进行性能优化? “过早的优化是万恶之源”——这句话几乎所有的程序员都耳熟能详。在早期,优化并没有什么实际意义,很多人在用某些引擎时第一件事就是自己封装一套STR,却没有思量STR外壳、内部好不好使。验证优化的唯一标准就是去测试它,而不是凭感觉在一开始就否定它。我们在测试葡萄GameObject时,发现在Android 4.0系统中飞行耗时0.54ms,这显然是不能接受的。 为什么将GameObject称之为“葡萄”?GameObject下包含了Renderobj、AI、Gun等非常多的子项,每个子项下又有很多子项,由此形成了一个极为庞大的葡萄串。许多开发者习惯于此的原因就是这样的葡萄看起来清晰明了,使用方便。但同时,葡萄无形中增加的计算量也是巨大的,因为每一次修改Plane的Transform.position、localPosition、rotation、localRotation意味着要更新所有子GameObject的变换信息。我们采取的做法是: 第一步:运行时移除掉不需要的GameObject子项,需要时再装回来。
第二步:降低葡萄根的调用频率,同时一帧之内不对transform.position赋两次值。但Unity并没有提供一个同时修改position和rotation的方法,导致动鱼目前一帧内仍然至少更新两次葡萄。
更进一步:LOD。很多经典的3A游戏都采用了这个技术,降低视野外和距离远的单位位移更新频率,以此来获得高效率的渲染运算。
如果您觉得内容精彩,请记得点赞并转发给您的朋友哦!
申远 成都动鱼技术总监 所谓3D军事动作游戏并非只是简单的拥有回合式动作系统的卡牌,而是能够实时模拟、同步的3D动作游戏。在使用Unity引擎开发3D动作游戏的过程中,通常会遇到如何组织和实现所有关卡、优化性能等问题,在此,我想分享一下我们团队在《血战长空》开发过程中探索出的经验之法。 如何在Unity中组织并建立所有关卡? 找同类型游戏做参考 首先,如何在Unity中组织和建立关卡?第一件事就是找同类型游戏做参考,将它们的共性提炼出来,以此来避免浪费精力做出一些似是而非的东西。尤其对于小团队来说,有效的学习和模仿可以少走许多弯路。在开发《血战长空》游戏时,我们参考了IL2、War Thunder和Armed Assault等诸多飞行射击类游戏。 它们的关卡编辑器都有一些共性,比如Unit Spawner(单位生成和初始设定)决定生成的是什么,即对应游戏过程中的哪个部分,开发者可以用它写一个下达框;Unit Waypoint(单位之后的去向和动作)是在过程中干什么,选择作战还是不开火?一定要作战怎么撤退?最后一个是Trigger(条件和触发),定一个条件,用于脚本交互。 即使是编写三维场景,也需要契合逻辑。拿Trigger来讲,一种是单位的Trigger,还有一种比较特殊的是炸弹Trigger,炸弹掉落到这一区域,会让单位掉血,开发者需要确保在有限的时间内它不会被炸毁。这些设计方式通过组件非常容易实现,开发者可以直接把一个关卡存储成Prefab。 在设计好初始单位、下一步动作路线以及触发条件反应后,又该如何定义一些比较特殊的关卡?来指引玩家按照既定顺序进行。比如有三个关卡,应该是先轰炸A后打B最后再打C,而不是倒过来。每一个单机游戏的Model都有不同的解决方案,要根据团队的实际开发能力、个人习惯以及项目类型来选择。 数据驱动还是代码驱动? 在关卡流程设计中,该选择数据驱动还是代码驱动?这个问题既简单又复杂,如果投资人或公司老板能够懂一些这方面的知识,那么游戏开发人员或许会少点心酸。数据驱动就是常说的可视化编程,优点是解放工程师,设计师可以消化掉所有流程部门的工作,不用添加程序就可以设置关卡,这对国内手游来讲是至关重要的功能。但同时存在诸多缺点,首先,开发者自创一套系统方案需要大量成本,每新入一个关卡设计师就需要重复教学。 最关键的问题是,团队花费大量时间来实现这么一大套系统,就意味着最快展现给投资人或给团队自身反馈的时间也会变长。有时候团队两三周没拿出什么对外的feature,并不是真的没有成果,只是可能是在实现底层、优化内层、搭建基础架构,这些繁芜系统的工作,在数据驱动的前期,尤为明显。 在对比数据驱动和代码驱动优劣之后,动鱼首先采用了纯代码驱动,使用Unity中的Coroutine功能对关卡流程进行快速设计并创建。通过代码驱动简单快捷的Hack属性,开发者可以先将关卡设计出来做成Demo交给投资人,然后再用数据驱动构建。这样,即使整个后续程序都没有开发完甚至没有开始,却可以很好地展示游戏性能。 而这种先代码后数据驱动的方式,对于关卡设计师来说,最High的事莫过于他们不用再求着程序员了,而程序员也不用特别费劲地折腾其他工程师。尽管结构是关卡里最重要的东西,但程序员一般不关心结构,这个权利要交给关卡设计师。 uScript还是playMaker? 确定驱动以后需要考虑的就是用uScript还是playMaker?uScript非常强大,类似于预代码生成器,支持预编一层代码,这样的好处就是速度非常快,但其预编译功能,既是优势也是劣势,每加一个关卡,就需要更新客户端。而playMaker则可以看做是一个状态机管理器,基本上想到的状态机功能都有,但最大的缺点是传值非常难,我们的解决方法是在action上留可编辑的variable,拖拽需要考虑的参数。 如果用来做线性游戏的话,则尽量一个state放一个action,在策划看来就非常可视化,每一个阶段都清晰地表明了动作,哪怕是瞬时的,如图1所示。多数关卡可以单纯通过已有的action组织出来,特殊的关卡可以专门写脚本,使用特殊的state和action。 在真刀真枪环境中如何进行性能优化? “过早的优化是万恶之源”——这句话几乎所有的程序员都耳熟能详。在早期,优化并没有什么实际意义,很多人在用某些引擎时第一件事就是自己封装一套STR,却没有思量STR外壳、内部好不好使。验证优化的唯一标准就是去测试它,而不是凭感觉在一开始就否定它。我们在测试葡萄GameObject时,发现在Android 4.0系统中飞行耗时0.54ms,这显然是不能接受的。 为什么将GameObject称之为“葡萄”?GameObject下包含了Renderobj、AI、Gun等非常多的子项,每个子项下又有很多子项,由此形成了一个极为庞大的葡萄串。许多开发者习惯于此的原因就是这样的葡萄看起来清晰明了,使用方便。但同时,葡萄无形中增加的计算量也是巨大的,因为每一次修改Plane的Transform.position、localPosition、rotation、localRotation意味着要更新所有子GameObject的变换信息。我们采取的做法是: 第一步:运行时移除掉不需要的GameObject子项,需要时再装回来。
第二步:降低葡萄根的调用频率,同时一帧之内不对transform.position赋两次值。但Unity并没有提供一个同时修改position和rotation的方法,导致动鱼目前一帧内仍然至少更新两次葡萄。
更进一步:LOD。很多经典的3A游戏都采用了这个技术,降低视野外和距离远的单位位移更新频率,以此来获得高效率的渲染运算。
如果您觉得内容精彩,请记得点赞并转发给您的朋友哦!
上一篇:UNITE 2015 TAIPEI 游戏开发深度干货分享![ 05-07 ]
下一篇:虚拟现实与二次元的完美邂逅[ 05-07 ]