在沙盒游戏里,能自由建造是很重要的特点,比如说风靡全球的《我的世界》,用一个个方块就能搭建出规模宏大的世界。甚至有偏激的人说,没有自由建造,就不是一个真正的沙盒游戏。的确,沙盒游戏的魅力有很大一部分是能自由构建一个游戏世界。看着自己一砖一瓦搭建起一个城堡世界会很有成就感的。

现如今的手游,大多数就是一个争斗和炫耀的世界。不管是传奇类的狂霸拽酷,还是连连看,消消乐等好友排名,就是消费国人的虚荣心。其实,游戏是第九艺术,要上升到艺术的角度。在游戏里,玩家需要一种情感的宣泄和寄托以及体验。

说了这么多,还是回到正题。我是如何在自己编写的独立游戏《中世纪之路》里实现建筑物的摆放呢?

在实现这个功能的时候,我首先考虑的不是代码。而是考虑其他游戏是如何实现这样功能的,有那些可以借鉴的地方。我首先想到了《魔兽争霸》里建筑物的摆放,可以自由的拖放。然后想到了《部落冲突》(简称COC)里的建筑放置方式,在COC里建筑是按格子摆放的,在一个平面上。

在我的游戏《中世纪之路》里,我既不想让玩家一砖一瓦的搭建建筑,又想让玩家一下就把建筑整体放置到地上了。我觉得像搭积木那样,既可以节省玩家时间,又有建造的乐趣。选定了这种方式后,我就要考虑建筑模块的数据储存方式了:我需要储存单个模块的三维空间里的坐标值(x,y,z的值),同时为了让模型选择,我还需要储存模型的旋转角度数。

然后,我还需要考虑如何用鼠标去执行这个操作。我构想的方案是:点击背包里的物品后,一个模型就动态产生,然后跟随鼠标在地面移动。然后按"E"键就放置到地面上鼠标所指的位置(E键放置,是我学《兽人必须死》得来的)。而组件的旋转呢?我考虑的是让鼠标滚轮(也就是中键)滚动时,就绕着Y轴旋转。当然如果更近一步,可以做到绕三个轴都能自由旋转。具体操作见下图:

建筑摆放动画

使用鼠标放置篝火

通过上面的操作,我们可以看到代码的实现效果很好,完美达到了我们的需求。不过想通了上面的操作原理后,还需要我们动脑筋来构思,如何用代码来实现这些操作功能。这对新手来说可能过难了点,但对于有经验的开发者就能比较快的找到近似的解决方案,然后加以改进。

我首先想到的是我曾经在手机上做过2D积木的搭建功能。把我们的操作动作拆解开来,无非就是三个步骤:

1.第一次按下手指或者鼠标,找到初始坐标,让物体动态出现在坐标位置上。

2.然后判断移动情况,让物体跟随鼠标或者手指的移动。

3.最后抬起手指或者鼠标,让物体固定在最后的坐标位置,把坐标数据写入到文本或者数据库里。

想清楚了这三个步骤,我们就心里底了,我们只要实现了这三步操作代码,基本上物体摆放功能就可以实现了。

在我实现第一个步骤的时候,我就遇到了个问题。我之前在写搭积木游戏的时候是2D的,坐标很好获取。但是在《中世纪之路》里,我可是要获取的是鼠标在地面上的坐标点啊。我开始用的是两行代码:

Vector3 mousePosition= Input.mousePosition;    //获取鼠标所在的坐标

Vector3 mouseWorldPosition =Camera.main.ScreenToWorldPoint(mousePosition) ; //把鼠标的坐标变成3D游戏世界里的空间坐标

我以为我的思路是没问题的,结果运行代码一看。哈哈,建筑物完全不是摆在地面上的啊,是在空中的啊。后来查了相关文档才知道,这个鼠标位置是鼠标在屏幕这个立体面上的位置(你可以想象屏幕是一个透明的立体墙,这个墙是树立在地面上的)。再说得专业点,是从主摄像机为起点,鼠标所指为终点的一个射线,与屏幕所在立体面相交的点。对于这个立体面的直观感觉,大家可以看看在3D空间里2D UI界面所在的那个面。

所以,上面两行代码是不能够解决问题的。不过这么一分析,我就接触到了射线的概念。我转念一想,如果我找到这个射线和地面相交的焦点不就行了嘛!我们的思路就变成了以下的伪代码:

1.创建一个从主摄像机为起点,鼠标所指为终点的一个射线Ray。

2.找到Ray和地面Terrain的交点position。

3.把物体的坐标动态创建于position。

核心代码如下:

if (Input.GetMouseButton())
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if(Physics.Raycast(ray, out hit))
{ if(hit.transform.name=="Terrain")
{
position = hit.point;//得到与地面碰撞点的坐标
}
}
}

解决这个核心难题后,移动的代码就很好写了。只要在手指或者鼠标移动的时候,动态更新物体的坐标为新的position就可以了。旋转物体的代码也可以写到一起,动态更新物体的旋转度就可以了。这段代码很容易写了,我就不贴出来了,新手可以锻炼自我动手能力。老手早就不用看在眼里了。当然需要提醒的是这段代码是需要在update函数里去运行的。

最后的固定物体坐标的代码,也就演变成了把最后的position记录于文本或者写入数据库了。这些代码都不是有多难写的。

最后回顾下,我们整个解决问题的思路:

构思操作步骤和方式->分解操作步骤->用代码实现分解后的操作步骤->完善和修正代码

如果大家问我要整个代码,坦白的说:我觉得"授人于鱼,不如授于渔"。大家能获取正确解决问题的思路就够了,然后记住核心代码就可以了。做程序员到一个“手中无剑,心中有剑”的境界就够了。当然新手还是多练练剑,比划比划下招式。

PS:游戏DEMO试玩群:198035671  Unity3d技术交流群:308185833  斗鱼游戏开发直播地址:www.douyutv.com/unity3d

Unity3D独立游戏开发日记(二):摆放建筑物的更多相关文章

  1. Unity3D独立游戏开发日记(一):动态生成树木

    目前写的独立游戏是一个沙盒类型的游戏.游戏DEMO视频如下: 提到沙盒类型的游戏,就有人给出了这样的定义: 游戏世界离现实世界越近,自由度.随机度越高才叫沙盒游戏.所谓自由度,就是你在游戏里想干啥就干 ...

  2. unity独立游戏开发日记2018/09/27

    今天优化了下昨天的代码,并且添加了树木和其他资源的生成.还修复了接近石头后,挖掘图标不出现的bug.目前可以在unity中稳定60-70fps. 详看文章:https://www.cnblogs.co ...

  3. 《Unity3D/2D游戏开发从0到1(第二版本)》 书稿完结总结

    前几天,个人著作<Unity3D/2D游戏开发从0到1(第二版)>经过七八个月的技术准备以及近3个月的日夜编写,在十一长假后终于完稿.今天抽出一点时间来,给广大热心小伙伴们汇报一下书籍概况 ...

  4. 关于《Unity3D/2D游戏开发从0到1》书籍再版说明

    关于<Unity3D/2D游戏开发从0到1>第一版本在2015年7月1日全国发行,累计得到不少国内高校教师.培训机构的好评.但是由于Unity官方对于技术不断的升级与版本的快速迭代,基于U ...

  5. 《Unity3D/2D游戏开发从0到1》正式出版发行

    <Unity3D/2D游戏开发从0到1>正式出版发行 去年个人编写的Unity书籍正式在2015年7月正式发行,现在补充介绍一下个人著作.书籍信息:      书籍的名称: <Uni ...

  6. Unity3D 入门 游戏开发 Unity3D portal game development

    Unity3D 入门 游戏开发 Unity3D portal game development 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com ...

  7. Unity3D手机游戏开发

    <Unity3D手机游戏开发> 基本信息 作者: 金玺曾 出版社:清华大学出版社 ISBN:9787302325550 上架时间:2013-8-7 出版日期:2013 年8月 开本:16开 ...

  8. 项目游戏开发日记 No.0x000005

    14软二杨近星(2014551622) 还有一周就要交项目了, 看着周围的人也都忙碌了起来, 看着大部分人的项目都已经初具容貌, 我们团队里面也搞得人心惶惶, 一来是, 时间不多了, 还有很多事情要做 ...

  9. 项目游戏开发日记 No.0x000002

    14软二杨近星(2014551622) 项目开发的开始, 到现在已经很久了, 软件工程的课也上了很久了, 不过, 我们的游戏现在依然还没有影子, 只能说...还是啥也不会... 从一开始, 兴致勃勃地 ...

随机推荐

  1. [转]Linux下权限掩码umask

    本文转自:http://www.cnblogs.com/123-/p/4188942.html ---------------------------------------------------- ...

  2. pageX和pageY

    pageX() 属性是鼠标指针的位置,相对于文档的左边缘. pageY() 属性是鼠标指针的位置,相对于文档的上边缘. 例1 $(document).mousemove(function(e){ $( ...

  3. sublime学习

    1:goto anything 特性 快捷键  ctrl + P    @  : # 使用 2:多行游标功能 快捷键 ctrl + D     ctrl + K 跳过选择 alt + F3 多选 产生 ...

  4. 广搜+输出路径 POJ 3414 Pots

    POJ 3414 Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13547   Accepted: 5718   ...

  5. CSS3 圆角(border-radius)详解

    在做网页的时候,常常需要实现圆角,以前的做法就是切图,现在好了,有了css3的 border-radius 特性之后,实现边框圆角效果就非常简单了,而且其还有多个优点:一是减少网站维护工作量:二是提高 ...

  6. POJ 2001 Shortest Prefix

    字典树基本题. 代码: #include <iostream> #include <cstdio> #include <cstring> #include < ...

  7. java 20 -3 递归之删除特定目录下的特定文件

    /* 需求:删除H:\demo目录下的带内容的文件 分析: A:封装该目录 B:获取该目录下所有的文件或文件夹的File数组 C:遍历该File数组,获取每一个File对象 D:判断所遍历的FIle对 ...

  8. iOS学习资料

    1. UI整理 http://www.cocoachina.com/ios/20151110/14067.html. 2. iOS学习路径 http://www.cocoachina.com/ios/ ...

  9. 使用gulp插件来自动刷新页面。

    http://itakeo.com/blog/2016/05/19/gulpreload/?none=123 使用gulp插件来自动刷新页面.再也不用修改一次,按一下F5了. 首选通过npm inst ...

  10. MVC ajaxSubmit上传图片

    注意事项: 1.提交form,必须引用jquery.form.min.js 2.不要使用mvc自带的Ajax.Form() 1.页面cshtml <form name="frmInpu ...