Unity3D游戏开发之从"复活"和"暂停/恢复"谈游戏数据配置管理

随着游戏制作技术的不断发展,在经历了从2D到3D、从单机到网游、从PC游戏到移动游戏的种种演变后,玩家对于游戏质量的要求越来越高,游戏制作的难度相应地增加,整个游戏研发的体系开始变得庞大而复杂,由此就产生了游戏数据配置和管理的相关问题。本文将从游戏中的”复活”和”暂停/恢复”这两个应用场景的角度来谈谈在游戏开发中如何对游戏中的数据进行管理和配置。

为什么要谈游戏数据的配置和管理

不知道大家是不是会和博主有一样的想法,就是当你回头来思考游戏开发的时候,你常常会发现,如果忽略游戏的画面、情节、特效等等这些游戏中的可视化的东西,那么其实游戏从本质上来说就是一个大型的有限状态机(FSM),而我们通常所做的事情基本就是在维护这个有限状态机里面的各种状态,从游戏加载到游戏开始、从游戏开始到游戏中各种事件的发生再到各种事件影响到整个有限状态机的状态,我们通常所做的事情无外乎是在维护各种状态。这种感觉在RPG游戏中可能会更明显些,因为在RPG中玩家可能是在场景中行走或者奔跑、可能是在和场景中的某个NPC进行对话、可能是在和面前的敌人进行战斗、可能是在和杂货店的老板讨价还价……可以说在整个游戏当中无时无刻不在进行游戏状态的切换,那么在不同的状态间切换的时候,什么最为重要呢?答案是数据。什么是数据呢?玩家的生命值、魔法值、战斗力、防御力,物品的用途、价格、数量,游戏的剧情、对话、音乐等等这些都是数据。当我们在状态间进行切换的时候,其实真正改变的就是这些数据。由此可见,面对复杂而庞大的游戏体系,如何对游戏中的数据进行配置和管理是一件值得我们去思考的问题。

从应用场景来看游戏数据的配置与管理

首先我们来从游戏当中的两个常见的应用场景:”复活”和”暂停/恢复”来看看游戏数据配置和管理的重要性。

这里以博主的一款跑酷游戏为例:

应用场景——“复活”

“复活”是一个在游戏中特别常见的功能,复活这一设定的好处在于无需重新开始游戏就能再次回到游戏当中,当然这只是我们最为直观的一个感受,更为深刻的原因是,游戏者巧妙地利用了玩家在游戏任务失败那一刻的心理。现在生活中每一个人都喜欢胜利,这种心理到了游戏世界中同样是适用的,因为游戏的目的无非就是让玩家有种成就感以获得快乐。可是当游戏任务失败的时候,玩家会竭尽全力不断尝试去打败Boss以获得游戏的胜利,因此在游戏中有这样一个设定,可以引导玩家在游戏中形成消费的习惯,这样游戏就能从玩家身上盈利。好了,我们来看看一个基本的”复活”的逻辑吧!

private void Update()
{
    //如果玩家的生命值大于0则游戏正常进行
    if(Player.Hp>0)
    {
       //游戏状态为Normal
       GameManager.Instance.GameState=GameStateEnum.Normal;
       //执行正常的游戏逻辑
       DoNormalEvent();
    }else
    {
       //游戏状态为Over
       GameManager.Instance.GameState=GameStateEnum.Over;
       //显示GameOver
       ShowGameOver();
       //玩家复活
       ReLive()
    }
}

玩家复活需要做两件事情:

1、将游戏的状态从Over调整到Normal

2、将玩家的状态从死亡调整到正常

调整游戏的状态特别容易,因为GameManager是一个典型的单例模式,因此我们可以直接将GameState从Over变成Noral。可是对于玩家状态的调整,我们却遇到了困难。问题出在什么地方呢?问题出在我们将玩家的生命值等一系列属性都写在了PlayerController这个类中,如果我们将玩家的属性全部都设为Private,那么我们将无法从外部来调整这些属性。比如我们想让玩家满血复活,可是因为这些属性都是私有的,我们无法从外部访问,所以我们在给玩家恢复生命值的时候,无法获得玩家当前的生命值以及最大生命值。可是如果我们将玩家的属性全部都设为Public,我们可能不得不去面对在编辑器窗口中为每一个属性去赋值,因为一旦我们试图调整游戏双方力量的平衡时,这将是我们不得不去面对的问题,更为致命的玩家的属性并不是永远不变的,比如在RPG游戏中玩家的生命值等属性会随着角色等级的提升而不断增加。因此不管我们将这些属性设为Public还是Private,我们都无法保证每次访问到的这些数据都是最新的数据。换句话说,我们不能想当然地在脚本中将玩家的属性写成一个不变的值,因为这些数据随时都在发生着变化,当然如果像敌人和Boss这种数值相对稳定的情况,我们可以直接在脚本中将其写成一个固定值,不过我并不推荐大家这样做。由此可见,游戏中数据配置和管理的一个重要作用是维持各个状态间的正常切换。如图是雨血前传.蜃楼中的复活界面,每次复活需要消耗一个复活玉:

那么博主在这款跑酷游戏里面是怎样做这个复活的呢?因为博主当时在设计这个游戏的时候考虑不周,直接将玩家的生命值写成了100,所以在复活玩家时候,同样是先将游戏的状态调整过来,然后再将相关的GUI窗口隐藏,然后将玩家的生命值重新设置为100,重新生成玩家就好了。正是因为感觉这段时间做游戏缺乏一种良好的游戏架构,所以每次游戏做到最后都是自己把逼到了绝路上,留给了自己一个自己都不想再去维护的烂摊子,这样显然是不好的,所以以后需要在正式动手写代码前做好规划,相信这样就能够保证游戏的质量了吧!任何东西学习到一定阶段都会遭遇瓶颈,尽管打破这种瓶颈的过程是痛苦的,可是如果不去打破它,那么你永远都只能停留在这个位置。

应用场景——“暂停/恢复”

和”复活”一样,”暂停/恢复”同样是一个在游戏中常见的功能,该功能是给了玩家暂时离开游戏的一种选择,可以保证玩家在做其它事情的时候不会影响到游戏的进程。比如在仙剑奇侠传、古剑奇谭等游戏中,玩家可以按下ESC键调出游戏设置界面,在玩家进入游戏设置界面的这段时间,游戏世界里的时间似乎是静止的,场景中的敌人不会因为玩家在查看系统设置界面就去主动偷袭玩家,因为这种情况下游戏是暂停的。而当玩家退出系统设置界面后,游戏恢复为正常状态。到了移动互联网时代,游戏中出现”暂停/恢复”的情况更为普遍,这是由移动互联网时代人们玩游戏更注重休闲和娱乐这样的性质来决定的。记得天天酷跑刚刚在微信上线的那段时间,我身边好多同学都在上课的时候玩,可是因为这游戏一跑起来就根本停不下来,所以经常是一次游戏玩下来一节课就结束了。博主不提倡这样啊,玩游戏归玩游戏,可是什么事情都要有个度啊,不然就会变成玩物丧志。好了,我们分析这个案例的目的无非就是想告诉大家在游戏里增加这样一个”暂停/恢复”的功能还是十分必要的。好了,现在我们来分析下在这个应用场景中发生状态转换的时候都会牵扯到那些数据吧!

首先游戏暂停后,场景内所有的物体都会停止运动,此时游戏中每个物体的状态都发生了变化,不过因为在Unity3D中控制游戏暂停/的恢复主要是通过调整Time.timeScale的值来实现的。当Time.timeScale取值为0时,游戏暂停;当Time.timeScale取值为1时,游戏恢复正常。不过需要注意的是Time.timeScale会对Unity3D中所有的时间产生影响如FixedUpdate()、协程、Destroy()、动画组件等等,所以如果对暂停后的游戏状态有特殊要求的话,建议还是通过其它的方法来实现吧!这里没有提到Update()和LaterUpdate()这是因为这两个方法不会受到影响。我们来看这样一段代码:

//游戏是否暂停
private bool isPause=false;
//暂停/恢复游戏的方法
private void Resume()
{
    if(!isPause){
       Time.timeScale=0;
       isPause=true;
    }else{
       Time.timeScale=1;
       isPause=false;
    }
}

通过这段代码我们就能够实现一个基本的游戏”暂停/恢复”的功能。在游戏管理类GameManager中我们定义了一个玩家的得分。正常情况下,当玩家没有死亡的时候会在GUI中更新玩家的得分,而玩家的得分是直接采用在Update()中累加的方式实现的,因此玩家的得分会在游戏暂停后继续更新,这当然是不符合实际情况的,因此可以在这个增量前乘上一个Time.deltaTime就可以解决这个问题了。博主举这个例子无非就是想告诉大家使用这种方法来暂停游戏会存在这样的问题,希望大家以后注意啊!

游戏数据配置和管理的思路和方法

既然我们在今天的的文章中主要阐述的就是游戏数据配置和管理,那么下面我们就来说说游戏数据配置和管理的常见的思路和方法。根据游戏中数据变动的相对大小,我们将游戏中的数据分为静态数据和动态数据两类。

静态数据

静态数据是指在游戏中基本不变或者不需要变动的数据。比如游戏中Boss的等级和生命值一般都是确定的,因此这种类型的数据可以称为静态数据。同样地,游戏中NPC对话的内容是一种静态数据,因为NPC的对话内容是在设计剧情的时候就设计好的无需再对它进行修改。那么对于静态数据,我们可以考虑下列方法:

将静态数据作为常量定义在一个类中,这样做的好处是无需对每一个脚本进行修改。

将静态数据存储在文件当中,这样做的好处是可以对数据进行管理,缺点是需要针对不同的文件编写解析接口,游戏开发中常用的数据存储形式有:Json、Xml、Excel、CSV等。

将静态数据存储在数据库当中,如SQLIite等,可是这样做的缺点同样很明显,从本地读取数据库会消耗大量的资源,而且数据库文件一旦丢失,整个游戏都将无法运行。

动态数据

动态数据是指在游戏中会不断变化的数据,比如玩家的得分、玩家的生命值、玩家的经验值等等。动态数据的处理方式除作为常量写在类中以外,其它的都和静态数据是一样的,在此就不再多说了。

总结

可能今天这篇文章显得唠叨些,甚至从技术的角度来看,这篇文章都没有讲到什么有价值的技术要点。可是在博主看来,不管一项技术有多么伟大,如果没有良好的架构或者说结构,那么当这个项目的规模到了一定程度以后,这个项目就会出现问题。因为根据破窗户理论,当你看到窗户破了而不去及时修补的话,那么时间一长你破掉的就是整个房子了。回顾博主这么长时间的游戏开发,其实做过的好多游戏到最后之所以没有做完,都是因为到最后项目基本失控、变成了一个连自己都不愿意去维护的项目,这样的情况是可怕的。平时是你一个人做项目,可能你觉得这些都没有什么,可是当你和别人一起去完成这样一个项目的时候,你的这些问题都会成为整个团队的问题。博主一直想知道自己做游戏和团队在一起做游戏会有什么不同,因为博主感觉自己在这一块确实不是掌握得很好。虽然说架构这种事情你做多了才会有经验,可是你现在发现了问题,为什么不在现在改掉呢?架构真的很重要,致那些因为架构死去的项目,真正的项目应该死在实践中,因为架构的问题最终变得不可收拾的,这件事情本身就是可耻的。好了,今天就说这么多了。

欢迎大家关注博主的独立博客,我的博客地址是http://www.qinyuanpei.com,及时获得最新的技术博客,就看你的了,哈哈!

每日箴言

毋庸置疑,好的事情总会到来。而当它来晚时,也不失为一种惊喜。

——《托斯卡纳艳阳下》

时间: 2024-10-06 20:50:38

Unity3D游戏开发之从"复活"和"暂停/恢复"谈游戏数据配置管理的相关文章

Unity3D游戏开发从零单排(四) - 制作一个iOS游戏

提要 此篇是一个国外教程的翻译,虽然有点老,但是适合新手入门.自己去写代码,debug,布置场景,可以收获到很多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一篇中,我们学会了怎么在Unity中搭建游戏的场景,并且设置模型的物理属性. 在第二篇中,我们学会了怎么在unity中使用脚本,并且创建了大部分的游戏逻辑,包括投球和得分! 在这最后一节中,我们将会为用户创建一个菜单系统,并且和GameController进行交互,我们开始吧. 在设备上测试 到目前为止,

【COCOS2DX-LUA 脚本开发之一】在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!

[COCOS2DX-LUA 脚本开发之一]在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途! 分类: [Cocos2dx Lua 脚本开发 ] 2012-04-16 10:08 30803人阅读 评论(18) 收藏 举报 游戏脚本luaanimationpython 本站文章均为李华明Himi原创,转载务必在明显处注明:转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2dx/681.htm

unity3D游戏开发之边锋(杭州)聘:游戏策划/设计/U3D/测评/文案等

杭州边锋网络技术有限公司简介 杭州边锋网络技术有限公司创建于1999年,2004年整合入盛大网络旗下.2013年浙报传媒斥资32亿元收购边锋,边锋现为浙报传媒旗下全资子公司. 一直以来,边锋致力于打造以互动休闲娱乐内容为核心的多终端垂直型交互社区,秉承"乐趣.亲切.进取.创新"的原则,倾力为所有国人打造集休闲.娱乐.社交于一体的互动娱乐平台.边锋以在线棋牌.电子竞技平台.桌面游戏.无线终端为四大主营业务,旗下拥有边锋游戏.游戏茶苑.浩方电竞.三国杀等众多知名品牌,均是各自所处领域中的领

【Unity游戏开发】不接SDK也能在游戏内拉起加QQ群操作?

一.引子 一般在游戏进行对外测试的时候都会有一个玩家QQ群,方便玩家反馈问题.交流游戏心得等.那么为了增加玩家加QQ群的欲望,可能会在游戏里面设计一个小功能,点击一下可以直接拉起手Q加群的操作,加了QQ群以后,也会自动下发一些小奖励刺激玩家.原本我以为要拉起手Q加QQ群的操作一定要接入相关平台的SDK才行,直到我详细地阅读了下腾讯官网的QQ群官方主页,我才了解到在游戏内拉起手Q发起加群的操作是如此的简单,根本不需要接入任何第三方SDK,只需短短几行代码即可轻松实现.闲言少叙,书归正文,咱们马上就

【读书笔记《Android游戏编程之从零开始》】9.游戏开发基础(如何快速的进入 Android 游戏开发)

1.不可盲目看API文档很多人在接触学习一门新的平台语言时,总喜欢先去探究一番API文档.先不说成效如何,至少编者认为这种方式不适合大部分人来效仿,主要原因在于 API 领域广泛,牵涉到的知识点太多,而对于刚刚接触平台开发语言的大部分人来说,遗忘速度远远大于记忆!这种做法是大量消耗精力.小量吸取知识的方法,只会事倍功半. 2.前人栽树,后人乘凉对于初学者来说,任何想要学习与掌握的知识点,之前都会有高人总结过:所以建议大家每学习一个知识点,都尽可能的先动手去网上搜索和学习别人总结出来的相关知识点的

【3】【MOOC】Python游戏开发入门-北京理工大学【第三部分-游戏开发之机制(事件处理机制)】

学习地址链接:http://www.icourse163.org/course/0809BIT021E-1001873001?utm_campaign=share&utm_medium=androidShare&utm_source=qq Pygame事件处理机制 1.Pygame事件处理机制简介 =================================================================================== 2.键盘事件及类型的使用

游戏开发怎么样学能入门零基础学游戏编程

游戏编程入门级教程,讲解通俗易懂.用具体实例讲解的方式让你用最短的时间掌握游戏编程基础知识.本程序使用中文开发平台搭建之星,搭建之星采用可视化构件,不需有英文基础,开发速度极快,操作非常简单.不论你使用何种编程语言开发,本课程里的例子都是一个很好的学习例子,参考其编程思路,对快速掌握开发技术非常有益.部分内容如下:生成我方战机编程生成敌方战机编程炮弹发射编程为游戏配音游戏空间的时光控制看完就会,自动动手制作游戏.游戏编程教程资料 原文地址:http://blog.51cto.com/131720

HTML5吃豆豆游戏开发实战(一)使用Canvas绘制游戏主角

最近在学习HTML5,爱因斯坦曾说过,"最好的学习就是自己去经历".于是,我想在学习HTML5的同时,做一款简单的小游戏,这样学习起来也会很有趣的,我想做的是以前小时候玩儿的小霸王上面的很经典的一款游戏,叫"吃豆豆",后面有怪物跟着跑,蛮好玩的,还很虐心,相信大家都玩儿过. 吃豆豆就是这款啦: 我就用前面学的一些HTML5的简单的一些知识来简单模拟这款游戏吧.我做这款游戏不打算用图片,全部用canvas来画,这样才有意思,嘿嘿. 正如大家所看到的,我们游戏的主角就是

[Unity3D]Unity3D游戏开发Lua随着游戏的债券(在)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 喜欢我的博客请记住我的名字:秦元培,我的博客地址是blog.csdn.net/qinyuanpei. 转载请注明出处,本文作者: