我这里说的数据驱动,不是指某种框架,某种结构,或者某种编码方式。 我要说的,是一种开发方式。

大家都知道,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使用经验总结 数据驱动篇的更多相关文章

  1. Unity3D使用经验总结 缺点篇

    不论是从官方手册,还是各种第三方教程,几乎涉及到的,都是讲如何使用U3D,以及U3D的优点. 虽然我是用的一个让步语气,但请不要否认U3D的这些优点,它们的确存在. 但对于一个引擎的特性来说,优点与缺 ...

  2. Unity3D使用经验总结 优点篇

    09年还在和其它小伙伴开发引擎的时候,Unity3D就初露头角. 当时就对这种基于组件式的设计结构很不理解. 觉得拆分过于细致,同时影响效率. 而时至今日,UNITY3D已经成为了众多团队的首选3D引 ...

  3. Unity3D使用经验总结 编辑器扩展篇

    一个引擎,最重要的就是工具,工具除了提升开发速度,提供可视化操作环境以外,还带了容错功能. 它使得大家的工作局限在一定的范围内,比如一个变量的配置,或者是一些类型的选择. 使用编辑器,使得既使不太明白 ...

  4. Unity3D使用经验总结 编辑器扩展篇【转】

    一个引擎,最重要的就是工具,工具除了提升开发速度,提供可视化操作环境以外,还带了容错功能. 它使得大家的工作局限在一定的范围内,比如一个变量的配置,或者是一些类型的选择. 使用编辑器,使得既使不太明白 ...

  5. 跟我从零基础学习Unity3D开发--资源打包篇(AssetBundle)

    好久没更新了,一直在加班敢项目进度.这里和关注我的博客的童鞋表示一下歉意!这里有我录的Unity3D从零开始的视频教程大家可以关注一下:http://www.imooc.com/view/555  视 ...

  6. Unity3D 游戏开发构架篇 ——角色类的设计与持久化

    在游戏开发中,游戏角色占了很大的篇幅,可以说游戏中所有的内容都是由主角所带动.这里就介绍一下角色类的设计和持久化. 一.角色类应用场景和设计思想 游戏中的角色类型不一而足,有不同的技能,有不同的属性等 ...

  7. Unity3D 游戏开发构架篇 ——输入控制

    临近毕业之初.进入Unity3D这个行业,是一家小工作室.老板人非常不错,公司氛围也非常单纯.近期公司开发一款小游戏,初次上手,颇多周折,记录下自己的开发心得.主要涉及一些设计理念,互相交流. 先说下 ...

  8. Unity3D 游戏开发构架篇 —— 动态大场景生成 = 区域加载+对象池管理

    项目做一个类似无尽模式的场景,想了一想,其实方法很简单,做一个相关的总结. 主要先谈一谈构架,后期附上代码. 一.区域加载 其实无尽场景的实现很简单,因为屏幕限制,那么不论何时何地,我们只能看到自己的 ...

  9. Unity3D 游戏开发架构篇 ——性格一流的设计和持久性

    在游戏开发.游戏人物占了非常大的空间.所有内容都是由主角可以说游戏驱动. 下面来介绍一下一流的设计和持久性的作用. 一.应用场景 游戏中的角色类型不一而足,有不同的技能.有不同的属性等等.有些一个玩家 ...

随机推荐

  1. iOSview整体上移下移(点击键盘)

    首先创建一个textFiled 并实现起代理方法 - (void)textFieldDidBeginEditing:(UITextField *)textField { //设置动画的名字 [UIVi ...

  2. XAMARIN +VS2015 ANDROID 开发禁止屏幕自动转动 Portrait,Nosensor

    网上有很多java的写法,但是放在C#中都无法使用,其实有时候还是安下心来认真的去看官网文档比在百度或者google来的快的多 this.RequestedOrientation = Android. ...

  3. javascript typeof

    https://zhidao.baidu.com/question/79159257.html typeof 运算符返回一个用来表示表达式的数据类型的字符串. 可能的字符串有:"number ...

  4. WebView 上传文件 WebChromeClient之openFileChooser函数

    原链接:http://blog.saymagic.cn/2015/11/08/webview-upload.html?utm_source=tuicool&utm_medium=referra ...

  5. 《photon中配置lite的相关问题》

    前几天在学习photon的时候发现了一个问题: 无论如何都找不到Lite文件夹,我是一个新手这也是写给那些新上手的朋友: 首先下载SDK以后配置完成后无论如何都找不到Lite文件夹和相关的Lite.d ...

  6. ulipad源码包配置环境及安装

    一.准备下载的安装包: 1.python(我电脑配置的是2.7)下载地址http://pan.baidu.com/s/1qWrGZk4 2.wxpython(我这里是wxpy3.0,配套python2 ...

  7. 移动App崩溃的测试用例设计

    我们的日常生活中对移动设备越来越多的使用意味着移动App测试这个主题已成为需要考虑的一个无法避免的问题.根据最近的调查研究,用户难以容忍有bug的移动App. 移动App Bug的影响是用户体验差.A ...

  8. Redis第二篇(Redis基本命令)

    -x     从标准输入读取一个参数 such as: echo –en “shaw” |./redis-cli –x setname == set name shaw -r     重复执行一个命令 ...

  9. Linux命令之awk数组使用范例

    目录 取ifconfig bond0的IP地址    1 命令如下:    2 统计apache日志单IP访问请求数排名    2 第一种方法    2 第二种方法    2 统计域名访问量    3 ...

  10. C#将科大讯飞语音合成文件转换为MULAW音频格式

    任务描述:通过科大讯飞语音合成组件在线完成文本转语音的合成,然后再转换为电话系统IVR要求的音频格式: wave mu-law 16位 8kHZ 64kbps. 完成步骤: 首先,我们要先通过科大讯飞 ...