Unity3d使用经验总结 数据驱动篇

我这里说的数据驱动,不是指某种框架,某种结构,或者某种编码方式。 我要说的,是一种开发方式。
大家都知道,U3D中,我们可以为某个对象编写一个脚本,然后将这个脚本挂在对象上,那这个对象就拥有了相应的能力。 但,由于脚本的威力是无穷的,它不仅可以操作这个对象本身,它同时还能改变整个世界。而U3D这种十分方便的开发模式,和你在FLASH CS中新建一个MovieClip,然后在它的时间轴上写代码如出一辙。 这种代码驱动的方式,在某些场合是非常有用的。
比如。 怪物AI,状态机,一些特殊的效果等(比如,摄相机振动)。
也就是说,如果我们想要让自己的代码很好地管理,那第一步,就是要限制代码与对象的关系。 世界中的任何单体对象,都不应该拥有改变世界(游戏逻辑)的能力。它唯一能做的,就是操作它自己,同时,如果遇上了自己能力以外的事情,必须要向管理器报告。
所以,为了实现数据驱动,我们的游戏大概有以下几种东西。
1、一个逻辑管理器,它决定了整个世界是如何运转,不同对象之间如何交互
2、事件管理器,它负责接收来自各个对象的报靠,比如(啊,有人踩到我了;咦,这是一个传送点耶;哎哟,你为什么点我。) 事件管理器起到事件队列缓存的作用,同时,游戏逻辑应该定时处理这些事件。 当然,这个事件管理器,也是逻辑管理器的一个小弟,如果逻辑管理器觉得不怕麻烦,也可以亲自操刀,负责事件收集。
3、若干对象相关的脚本,用于决定对象能力。 这些脚本不做别的,只做它们自己目标对象相关的事情。 比如,控制一个对象的动画切换,检查敌人是否进入攻击范围等等。 这些脚本,是做为脚本的一种能力挂上去的。当相应事件触发时,他们会将事件通知给事件管理器。 理论上,我们是可以完全避免这样做的, 就像早期的引擎中,对象只是资源,逻辑代码用来操作这些资源。 但是,既然U3D提供了如此便利的东西,我们为何不用呢。 因为有许多事件的检测,U3D已经为我们做好了,并且,也只有挂接在此对象上的脚本,才能够监听到这些事件。 比如OnTriggerEnter
当我们把代码限制在一定范围后,接下来的事情,就是限制场景树(Hierarchy)中对象的使用。
U3D很强大,你可以通过对象关系、组件,参数调节,快速地构建出一个对象。 这一步,是必须的。 但我们还是要限制一下, 我们不允许非Prefab的对象在场景树中出现,同时,Prefab除了Transform以外,不能被更改。(后面会说为什么,以及如何面对确实要更改的情况)。
接下来,我们来解决U3D中,一个操蛋的SVN冲突问题。 U3D的SCENE是基于二进制存储的,不管你怎么整,怎么避免,都会有冲突,并且冲突无法合并。 那,这事儿太简单了,我们不用它的SCENE文件就可以了。
需要做下面几件事
一、新增菜单 打开场景,保存场景
二、当我们保存场景的时候,遍历场景中的对象,将它们的transform,name,prefab,parentname存下来。输出到文本文件中,记住,这一定要是文本文件,不然,照样冲突。
三、如果只有一个文件,那冲突还是在所难免的,因此,我们需要把场景保存的时候,分割为多个文件。 如何分割呢, 我们需要提供一个配置文件,这个配置文件负责提供一个唯一的名字,以及对象ID段。 对象ID段的目的,这个对象ID,先前没有提过,但作为一个场景中的对象来说,如果没有ID,那将无法做到对它进行准确定位。 但,大家是工作在不同的机器上的,如果使这个ID唯一呢。 连接一个服务器? 那太坑爹了。 所以,我们可以把ID分段,项目组中,每个人拥有一个不相互冲突的ID段,和一个名字(可以是名字的拼音+后缀:如果有冲突的情况)。 当我们在编辑器中,把一个prefab拖入hierarchy的时候,修改这个对象的名字 ID_PrefabName_UserName 这样,这个对象在场景中就有了唯一的名字。 当我们保存的时候,我们根据USERNAME,将场景保存到不同的子文件划分中。
四、这样一来,我们的U3D场景就不需要保存了。 那我们如何做到点PLAY就即时运行查看效果呢。 这里有一个小小的技巧性方案。 在我们的编辑场景中,新建一个GameObject,在它上面挂上一个脚本,这个脚本什么事都不做,直接start的时候,就LoadLevel("game"). (这里,假设我们的游戏场景是game,game是一个新建好的场景,且加入到了当前项目的场景列表中的。 这个game其实也只有一个GameObject,它负责启动游戏。 加载我们先前输出的场景文件).
还有一个细节要处理,由于我们的game场景只有一个,那我们编辑许多个场景,要如何查看呢。 那我们可以使用一个静态变量来存储当前编辑的场景,这样game在加载的时候,就知道应该加载哪个场景的文件了。
五、为了使我们的开发更佳清析,在新建项目的时候,我们就新建两个Scene 一个叫Editor,一个叫Game。 大家都在Editor里面工作。 最后发布的时候,只发布Game.
六、SVN的提交, Editor和Game是一开始就新建好了的,直接在SVN上把它锁掉,禁止提交。 其余的文件,都是可以提交的。
这样,我们的U3D,就和自家引擎一样了。
在实施的过程中,我也遇上了一些问题。
一、保存场景的时候,取得所有的对象, 为了保证得到完整的场景树TOP结构,我有一个SceneRoot的空GameObject,所有的东西,都挂在这个下面。 当输出的时候,我直接从SceneRoot开始遍历,从而拿到了完整的parent,child关系。
二、监听对象改变的事件,我目前,只能在EditorWindow的OnHierarchyChange里面来做,但这样做有个不好的,就是这个EidtorWindow需要保持显示,如果不小心关了,就失效了(不知道哪位兄弟有更好的办法)
三、由于这套东西,没有使用U3D的场景保存功能,所以,CTRL+S是无效的。 不过,CTRL+S可以让你的东西保存到Editor.unity3d里面,虽然不可以提交,但不会导致你的东西丢失。
四、使用的过程中,也出现了一些大大小小的问题。
五、目前是强制让Prefab的其它属性不可修改,如果有变动的,就新建一个Prefab. 或许还有更好的办法.
如果有喜欢这个东西的朋友,可以一起来完善。
Unity3d使用经验总结 数据驱动篇的更多相关文章
- Unity3D使用经验总结 缺点篇
不论是从官方手册,还是各种第三方教程,几乎涉及到的,都是讲如何使用U3D,以及U3D的优点. 虽然我是用的一个让步语气,但请不要否认U3D的这些优点,它们的确存在. 但对于一个引擎的特性来说,优点与缺 ...
- Unity3D使用经验总结 优点篇
09年还在和其它小伙伴开发引擎的时候,Unity3D就初露头角. 当时就对这种基于组件式的设计结构很不理解. 觉得拆分过于细致,同时影响效率. 而时至今日,UNITY3D已经成为了众多团队的首选3D引 ...
- Unity3D使用经验总结 编辑器扩展篇
一个引擎,最重要的就是工具,工具除了提升开发速度,提供可视化操作环境以外,还带了容错功能. 它使得大家的工作局限在一定的范围内,比如一个变量的配置,或者是一些类型的选择. 使用编辑器,使得既使不太明白 ...
- Unity3D使用经验总结 编辑器扩展篇【转】
一个引擎,最重要的就是工具,工具除了提升开发速度,提供可视化操作环境以外,还带了容错功能. 它使得大家的工作局限在一定的范围内,比如一个变量的配置,或者是一些类型的选择. 使用编辑器,使得既使不太明白 ...
- 跟我从零基础学习Unity3D开发--资源打包篇(AssetBundle)
好久没更新了,一直在加班敢项目进度.这里和关注我的博客的童鞋表示一下歉意!这里有我录的Unity3D从零开始的视频教程大家可以关注一下:http://www.imooc.com/view/555 视 ...
- Unity3D 游戏开发构架篇 ——角色类的设计与持久化
在游戏开发中,游戏角色占了很大的篇幅,可以说游戏中所有的内容都是由主角所带动.这里就介绍一下角色类的设计和持久化. 一.角色类应用场景和设计思想 游戏中的角色类型不一而足,有不同的技能,有不同的属性等 ...
- Unity3D 游戏开发构架篇 ——输入控制
临近毕业之初.进入Unity3D这个行业,是一家小工作室.老板人非常不错,公司氛围也非常单纯.近期公司开发一款小游戏,初次上手,颇多周折,记录下自己的开发心得.主要涉及一些设计理念,互相交流. 先说下 ...
- Unity3D 游戏开发构架篇 —— 动态大场景生成 = 区域加载+对象池管理
项目做一个类似无尽模式的场景,想了一想,其实方法很简单,做一个相关的总结. 主要先谈一谈构架,后期附上代码. 一.区域加载 其实无尽场景的实现很简单,因为屏幕限制,那么不论何时何地,我们只能看到自己的 ...
- Unity3D 游戏开发架构篇 ——性格一流的设计和持久性
在游戏开发.游戏人物占了非常大的空间.所有内容都是由主角可以说游戏驱动. 下面来介绍一下一流的设计和持久性的作用. 一.应用场景 游戏中的角色类型不一而足,有不同的技能.有不同的属性等等.有些一个玩家 ...
随机推荐
- android书籍
教程 源码下载 高薪招聘 Cocos2d-x 博客 签到 视频教程 wiki 帖子 搜索 热搜:二维码定时器手电筒滑块斗地主书架定位买手机聊天游戏开发游戏股票查询机顶盒通话记录二维码扫描振动器 ...
- 移动平台对于META标签的定义[转]
下面介绍一些有关标记的例子及解释. 一.meta 标签分两大部分:HTTP 标题信息(http-equiv)和页面描述信息(name). 1.http-equiv 属性的 Content-Type 值 ...
- LeetCode(97) Interleaving String
题目 Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example, Given: ...
- JSTL和EL表达式多重if问题
俾人以前在写一个查询功能时,由于结果状态分好几种,于是页面就用<c:if></c:if>写了一大堆来判断,后来上网查了下资料,发现有个语法类似于多重if,挺方便的,语法是 &l ...
- HTML5所有标签汇总
来自lampbrother兄弟连HTML5与CSS3教程.<xmp> 结构标签:(块状元素) 有意义的div<article> 标记定义一篇文章<header&g ...
- 通过反射获取父类泛型的Class对象 ParameterizedType
((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0] 这个方法这么用啊,返回什么,请给 ...
- smarty模板中获得循环次数
在smarty中可以有两种写法来获得循环次数(当然lz只会这两种:>,要是有大神会有其他的,欢迎补充) 写法一: {section name=loop loop=3} {$smarty.loop ...
- 查找原始MySQL死锁ID
转载地址:http://yueliangdao0608.blog.51cto.com/397025/1180917 如果遇到死锁了,怎么解决呢?找到原始的锁ID,然后KILL掉一直持有的那个线程就可以 ...
- UDP及其组播,接收发送封装
1.Receiver public class Receiver { public delegate void HeartBeat(byte[] data); public event HeartBe ...
- 7.4 MVC vs MVP
MVC(Model_view_contraller)"模型_视图_控制器". MVC应用程序总是由这三个部分组成.Event(事件)导致Controller改变Model或View ...