Unity3D研究院之2D游戏开发制作原理(二十一) 【转】
转载自雨松MOMO程序研究院本文链接地址:Unity3D研究院之2D游戏开发制作原理(二十一) http://blog.csdn.net/xys289187120/article/details/8394188
经过了4个月不懈的努力,我和图灵教育合作的这本3D游戏开发书预计下个月就要出版了。这里MOMO先打一下广告,图灵的出版社编辑成员都非常给力,尤其是编辑小花为这本书付出了很大的努力,还有杨海玲老师,不然我也无法完成这本书的编写。等这本书出版了大家记得买喔,哇咔咔~ 下面,这篇文章是MOMO 3D游戏开发书籍中的一小段章节的修改版本,本篇文章我们将探讨一下Unity3D中如何来制作2D游戏。目前市面上已经有非常成熟的2D游戏引擎,比如cocos2d 或cocos2d-x等,并且都是免费的开发者可以直接用来制作2D游戏。然而使用3D引擎来制作2D游戏会让游戏画面更加附有立体感,因为2D游戏中Z轴永远是0,而3D游戏中Z轴是可变化的。
接着说说在Unity3D中制作2D游戏的原理。在Unity3D中绘制贴图的方式大致可分为两种,第一种是在GUI中绘制贴图,第二种是在网格面上绘制贴图。先说说第一种,GUI主要用来制作简单的游戏2D界面,比如游戏主界面中绘制的“游戏名称”、“开始游戏”、“保存游戏”、“退出游戏”一些按钮或界面中一切其它的高级控件,文本框,输入框等等、GUI只能制作简单的图形化界面,因为它的渲染效率非常低,它与3D世界中网格模型的渲染机制完全不一样。第二种的属于将图片绘制在3D中网格平面中,它的渲染效率远远高于GUI中,在制作2D游戏时都是将所有贴图绘制在平面模型对象之上,最后用摄像机以90度垂直的角度照射这这些平面。
下面我们开始学习在Unity3D中制作2D游戏的原理。2D游戏又可以分为两种,区别是物体碰撞时带物理引擎或不带物理引擎。带物理引擎就好比《奋斗的小鸟》一样,大家应该都玩过,小鸟发射后下落击落其它物体将发生物理的碰撞。(我没有细看这款游戏,但是我知道2D 与3D引擎都都可制作),不带物理引擎的就好比《捕鱼达人》这种游戏,游戏中碰撞都是由代码自己来完成的,经典的2D碰撞监测包括:矩形与矩形的碰撞、点与矩形的碰撞、圆与圆的碰撞等。今天这篇文章我们主要讨论第二种不带物理引擎的2D游戏。
如下图所示,我们盘点一下2D游戏中必备的几个元素。
摄像机:无论是3D游戏还是2D游戏摄像机都是非常重要的属性,移动摄像机即可更改屏幕中显示的内容,游戏地图的坐标永远都不会发生改变。
地图:2D游戏中的地图一般是由tile拼接而成,它可由地图编辑器生成然后将每一块tile绘制在整个贴图中,最后将贴图贴在平面网格面之上即可。还有一种作法是将两个或两个以上屏幕大小平面以队列的形式排在屏幕后面,当摄像机移动超出第一块面显示范围时,将它的坐标移动在第二块面后面,此时地图就形成了一个排序的队列。为了让地图的效果更加完美,一般地图可以由好几层来组成,比如背景层、与主角的遮挡曾、物理层等等。
地图拼接:地图的排序队列中两张图应当是可以无缝拼接,这个应当是由美术来提供资源,这里我就不那么细致了将远离说明白即可。
主角:它的范围就比较广的,敌人、物品等等出现在地图之上的都可以使用它。如果控制主角移动,摄像机移动的同时主角也当跟随移动,并且保持屏幕中的移动比例,除非摄像机无法移动,这时将直接移动主角在屏幕中的坐标。 说的有点绕了呵呵,大家仔细想想哈哈。。
然而上面的一切面是由Plane面来完成。
再Unity层次视图中选择摄像机对象,右侧监测面板视图中我们看看摄像机组件的一些属性,如下图所示。需要注意的就是Projection 投影类型。
首先我们应当修改摄像机的属性,默认摄像机投影的类型是Perspective,它保持摄像机以扩散的的形式照射着不利于2D平面的展示。这里我们应当选择Orthographic,这样摄像机将直直的照射在显示的区域。
Perspective类型
Orthographic
从侧面观察摄像机,通过这两张图我相信大家应当能看懂为什么2D游戏要用Orthographic了吧,摄像机的投影类型是可以在代码中动态的修改的。
1
|
//得到游戏中摄像机对象
|
2
|
Camera camera = Camera.mainCamera;
|
3
|
//设置摄像机投影类型OrthoGraphic
|
4
|
camera.isOrthoGraphic = true ;
|
5
|
//设置摄像机投影类型Perspective
|
6
|
camera.isOrthoGraphic = false ;
|
在代码中取得摄像机投影的区域大小,它也可以动态的修改,这样就可是实现摄像机拉近与拉远的效果。根据投影区域的大小配合着整个地图的宽高来写判断条件,避免移动摄像机时超过地图的范围。
1
|
Camera camera = Camera.mainCamera;
|
2
|
Debug.Log(camera.orthographicSize);
|
接着我们使用代码来得到地图面的宽高,这段代码写的就比较精细,因为网格面是可以缩放的,首先得到网格面的宽与高,然后分别乘以缩放系数就可以得到真实面的宽与高,然而Unity中的坐标是以“米”为单位。下面代码中用到了中文,如果要想在编辑器中显示中文C#语言需要修改编码格式为UTF-16。JavaScript修改编码格式UTF-8或UTF-16即可。
01
|
using UnityEngine;
|
02
|
using System.Collections;
|
03
|
04
|
public class Test : MonoBehaviour
|
05
|
{
|
06
|
07
|
void Start ()
|
08
|
{
|
09
|
10
|
GameObject plane = GameObject.Find( "Plane0" );
|
11
|
//得到面默认宽度
|
12
|
float size_x = plane.GetComponent<MeshFilter>().mesh.bounds.size.x;
|
13
|
//得到面宽度的缩放比例
|
14
|
float scal_x = plane.transform.localScale.x;
|
15
|
//得到面默认高度
|
16
|
float size_z = plane.GetComponent<MeshFilter>().mesh.bounds.size.z;
|
17
|
//得到面高度缩放比例
|
18
|
float scal_z = plane.transform.localScale.z;
|
19
|
20
|
//原始宽度乘以缩放比例计算出真实宽度
|
21
|
float mapWidth = size_x * scal_x;
|
22
|
float mapHeight = size_z * scal_z;
|
23
|
24
|
Debug.Log( "得到面的位置:" +plane.transform.position);
|
25
|
Debug.Log( "得到面的宽度:" + mapWidth);
|
26
|
Debug.Log( "得到面的高度:" + mapHeight);
|
27
|
}
|
28
|
29
|
}
|
有了摄像机照射的区域以及背景地图的宽高尺寸那么就可以在代码中编写逻辑判断条件啦。下面我们来使用简单的代码控制摄像机移动以及主角移动。
01
|
using UnityEngine;
|
02
|
using System.Collections;
|
03
|
04
|
public class Controller : MonoBehaviour
|
05
|
{
|
06
|
07
|
//动画数组
|
08
|
private Object[] anim;
|
09
|
//主角对象
|
10
|
private GameObject hero;
|
11
|
//限制一秒多少帧
|
12
|
private float fps = 10;
|
13
|
//帧序列
|
14
|
private int nowFram;
|
15
|
//记录当前时间
|
16
|
private float time;
|
17
|
18
|
void Start ()
|
19
|
{
|
20
|
//得到资源名称为down文件夹中的所有对象资源
|
21
|
anim = Resources.LoadAll( "down" );
|
22
|
//得到主角的对象
|
23
|
hero = GameObject.Find( "hero" );
|
24
|
}
|
25
|
26
|
void FixedUpdate ()
|
27
|
{
|
28
|
//上、下、左、右平移摄像机
|
29
|
if (Input.GetKey (KeyCode.A))
|
30
|
{
|
31
|
transform.Translate(-0.01f,0,0);
|
32
|
33
|
}
|
34
|
35
|
if (Input.GetKey (KeyCode.D))
|
36
|
{
|
37
|
transform.Translate(0.01f,0,0);
|
38
|
}
|
39
|
40
|
if (Input.GetKey (KeyCode.W))
|
41
|
{
|
42
|
transform.Translate(0,0.01f,0);
|
43
|
}
|
44
|
45
|
if (Input.GetKey (KeyCode.S))
|
46
|
{
|
47
|
transform.Translate(0,-0.01f,0);
|
48
|
}
|
49
|
50
|
//上、下、左、右平移主角
|
51
|
if (Input.GetKey (KeyCode.J))
|
52
|
{
|
53
|
54
|
hero.transform.Translate(0.001f,0,0);
|
55
|
}
|
56
|
57
|
if (Input.GetKey (KeyCode.L))
|
58
|
{
|
59
|
60
|
hero.transform.Translate(-0.001f,0,0);
|
61
|
}
|
62
|
63
|
if (Input.GetKey (KeyCode.I))
|
64
|
{
|
65
|
hero.transform.Translate(0,0,-0.001f);
|
66
|
}
|
67
|
68
|
if (Input.GetKey (KeyCode.K))
|
69
|
{
|
70
|
hero.transform.Translate(0,0,0.001f);
|
71
|
}
|
72
|
73
|
DrawAnimation(anim);
|
74
|
}
|
75
|
76
|
void DrawAnimation(Object[] tex)
|
77
|
{
|
78
|
79
|
//计算限制帧的时间
|
80
|
time += Time.deltaTime;
|
81
|
//超过限制帧切换贴图
|
82
|
if (time >= 1.0 / fps){
|
83
|
//帧序列切换
|
84
|
nowFram++;
|
85
|
//限制帧清空
|
86
|
time = 0;
|
87
|
//超过帧动画总数从第0帧开始
|
88
|
if (nowFram >= tex.Length)
|
89
|
{
|
90
|
nowFram = 0;
|
91
|
}
|
92
|
}
|
93
|
//将对应的贴图赋予主角对象,强制将资源文件转换成贴图
|
94
|
hero.renderer.material.mainTexture = (Texture)tex[nowFram];
|
95
|
}
|
96
|
}
|
代码中我们使用 Resources.LoadAll(“down”);来加载主角动画资源,这里将主角一组4帧的行走动画放在项目资源视图中 Resources文件夹中的down文件夹内。值得注意的是,使用Resources来加载资源就必须将资源放在Resources文件夹中,否则提示无法找到喔。在书中我以将人物四宫格行走动画加入在其中,因为这里只是一个是示例,所以我只加载了向下行走的4帧动画。我们看看资源在项目资源视图中的保存结构。
还有一个比较重要的地方就是要修改材质的shder类型,因为默认的材质是Diffuse,它是不支持透明的。如果材质不支持透明。主角的背景将会是白色。如下图所示,这里选择Transparent/Diffuse。保存为Transparent家族中的材质都是支持透明的。
最后2D游戏效果图映入我们眼帘了哦。按键W、S、A、D控制摄像机移动,按键J、K、I、L、控制主角移动。
总结一下这篇文章,本文我们在多个Plane对象身上贴上材质资源,再让摄像机直直的照射着它。实现2D游戏的基本原理,本文没有涉及到Unity3D的物理引擎,不要紧在下章中我将向大家介绍一下Unity3D中的刚体组件与角色控制器组件如何来实现模型的物理效果,包括物理引擎与3D或2D游戏的结合。另外大家一定要期待我的新书喔,哇咔咔~嘿嘿。
转载于:https://www.cnblogs.com/songtzu/archive/2013/04/09/3009507.html
Unity3D研究院之2D游戏开发制作原理(二十一) 【转】相关推荐
- python scratch unity_Unity3D研究院之2D游戏开发制作原理(二十一)
经过了4个月不懈的努力,我和图灵教育合作的这本3D游戏开发书预计下个月就要出版了.这里MOMO先打一下广告,图灵的出版社编辑成员都非常给力,尤其是编辑小花为这本书付出了很大的努力,还有杨海玲老师,不然 ...
- unity 2D游戏开发 制作帧动画的两种方法
本小主在这里给大家分享一下unity 2D游戏开发中制作帧动画的两种方法. 比较简单,一学即会. 方法一: 是用代码控制: 先创建一个2D工程.导入图片资源,并设置texture的texture ty ...
- 【Unity3D】学习笔记(第2记) 2D游戏开发基本技巧之背景制作
最近看了龚老师的u3d视频讲座游戏<Platform>7讲,是关于2D游戏开发的,现将一些个人学习笔记记录于此. 1 背景图导入 首先创建一个Cube,通过缩放调整成和背景图一样的宽高,然 ...
- 游戏开发 unity3d python_游戏研发系列 Unity3D/2D游戏开发从0到1 第2版.pdf
作 者 :刘国柱著 出版发行 : 北京:电子工业出版社 , 2018.01 ISBN号 :978-7-121-33499-3 页 数 : 507 丛书名 : 游戏研发系列 原书定价 : 99.00 开 ...
- unity超级马里奥2d游戏开发课程-01课程介绍
大家好,我是小兵,今天给大家带来Unity开发超级马里奥2d游戏的第1课,课程介绍,你可以在我的个人博客geekape.net上找到完整的课程. 我之前主要是做前端开发工作的,并不是做游戏开发的,但由 ...
- Unity 2D 游戏开发解决方案大全
Unity 2D 游戏开发解决方案大全 一些官方腔 这篇文章会是一个大纲模式,致力于,为刚入坑的小白,对于一些常见的 Unity 2D 开发问题给出解决方案(啊,尤其是我) 一些方案可能并非最优解,但 ...
- unity 2d 游戏开发教程(2d战棋)
unity 2d 游戏开发教程(2d战棋) 类似的游戏有:火焰纹章,梦幻模拟战 先上效果 源码领取方式:私信发送 2D战棋资料领取 这是 unity3d 战棋游戏开发 专题的内容拓展 这个专题完整的讲 ...
- Unity4.x 2D游戏开发基础教程第1章Unity及其组成的介绍
Unity4.x 2D游戏开发基础教程第1章Unity及其组成的介绍 本书主要讲解的是,如何使用Unity开发2D游戏.但在开始讲解之前,最好先熟悉一下Unity这个工具.本章会首先介绍Unity的下 ...
- Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏
Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏 即使是现在,很多初学游戏开发的同学,在谈到Unity的时候,依然会认为Unity只能用于制作3D游戏的.实际上,Unity在2013年发布 ...
- Unity 2D游戏开发快速入门(内部资料)
Unity 2D游戏开发快速入门(内部资料) 试读样张:http://pan.baidu.com/s/1hqh5oqw Unity 2D游戏开发快速入门4 前 言 Unity是一款综合的游戏开发工具 ...
最新文章
- python信用卡违约_Python信用卡验证
- 全局变量与静态全局变量
- automatic asynchronous creation if no note exists
- 在Spring MVC中,InternalResourceViewResolver做什么?
- day35-mysql之表的详细操作
- linux登录后自动打开终端,linux登录信息/打开终端信息
- c/c++教程 - 2.4.2.5 深拷贝和浅拷贝,堆区内存重复释放
- Ubuntu安装ARM架构GCC工具链(ubuntu install ARM toolchain)最简单办法
- 化学专业与计算机的联系PPT,计算机在化学中的应用ppt
- 无线中继后要不要关闭dhcp服务器,tplink无线路由器WDS桥接后副路由开启DHCP 好还是关闭好。...
- 上半年要完成的博客占坑77
- Asciinema - 终端日志记录神器,机器学习开发者的福音
- GetFLV.v9.1.1.8-kg-REPT
- 申请邓白氏D-U-N-S编码遇到两个公司名称一样英文翻译的解决方法
- [Python深度学习入门]实战一·Numpy梯度下降求最小值
- [转]深度剖析闪电网络
- 手机app开发需要哪些技术?
- CodeForces 464E The Classic Problem | 呆克斯歘 主席树维护高精度
- python 图表_测试多图表展示Python版
- 天龙八部TLBB搭建(四)游戏端和补丁及上传CentOS修改篇
热门文章
- 【2020牛客寒假基础算法训练营】第五场总结
- 深度学习、机器学习、自然语言处理NLP优秀文章整理
- python立方体类_python学习12类
- Google Code Review 如何进行代码审查
- 获取以及自定义User-Agent在URLSession, NSURLConnection, WKWebView iOS
- 创建CocoaPods的Framework Swift组件化之路(下)
- android ble 写失败,Android低功耗蓝牙BLE写入数据很大几率会失败 求解
- 找零钱问题系列之动态规划
- oppor17山寨机的特点_国产山寨厂商智慧生生不息:拼多多山寨手机仍在
- debian rabbitmq离线安装_Rabbitmq web-mqtt在debian上的安装