制作思路
- 搭建打地鼠游戏场景
- 新建游戏交互对象“地鼠”
- 设置游戏规则:
“地鼠”被打到时(受到鼠标点击)消失
同时在原有“地鼠”位置出现新对象“死地鼠”并在规定时间内消失
未受到点击的“地鼠”在指定时间内自动消失
“地鼠”能在相同时间间隔内随机产生
- 添加游戏相关的音乐和音效
制作步骤
搭建打地鼠游戏场景
- 搭建2D场景
- 确认相机参数Projection的选项为Orithographic
- 新建文件夹Sprites用来存放图片素材,并导入背景素材
(这里导入的背景图片可以自行在网上搜索,由一个大的背景图片.jpg(ground)和一个有α通道的地鼠洞图片.png(hole)组成) - 对两个素材进行相关的调整:
选中图片,打开inspector面板,参数如下图所示
Texture Type:Sprite(2D and UI)
Sprite Mode:Single
Pixels Per Unit:100 【每个像素点个数为100】
关掉【自动生成小地图】的选项Generate Mip Map(一般情况下为未勾选状态) - 将背景图片ground拖拽进窗口,根据背景图片的大小修改Game窗口分辨率为新增分辨率,并用Scale调整大小
调整摄像机大小Size(可以使用鼠标拖拽调整或者用公式【高度除以2除以每单位像素数100调整数值修改) - 将hole也拖拽进屏幕,调整位置,新建空物体Map做容器放置ground和hole
注意此处要确保他们的参数Order in layer 层级关系:hole为1层,ground为0层
使得hole放置在ground上面而不至于被遮挡不可见
保存场景
Ps:此处有一些出入。如果我们有相匹配的“地鼠”的3D模型和材质,可以使用3D模型制作。不过由于我没有找到相关的素材,而恰巧我们此次制作为2D游戏,所以可以采取给图片即2D对象添加碰撞器的做法,如下。
- 将“地鼠”素材图片.png导入,拖拽入Scene面板,重置,并给它添加一个box 2D的碰撞器。
同理制作对象“死地鼠”,并将该对象拖拽为预制体。
如果光线较暗的话可以添加Directional light平行光
摄影机设置Clear Flags项选项为Solid Color,颜色改为黑色,如图所示。 - 创建脚本S1,代码如下
void OnMouseDown() {
Destroy(gameObject); //点击销毁对象“地鼠”
}
使对象“地鼠”在受到鼠标点击时自动销毁
将脚本加到对象“地鼠”上
- 继续编写S1脚本,实现点击“地鼠”后,“地鼠”变为“死地鼠”的效果
首先定义预制体“死地鼠”对象
public GameObject
m_prefab2; //引用“死地鼠”对象
然后在销毁对象“地鼠”前实例化对象“死地鼠”
Instantiate(m_prefab2,
transform.position, Quaternion.identity);
//实例化生成 “死地鼠”,位置为当前【点击“地鼠”】的原位置,旋转角度为任意值
注意:要先生成,再销毁。因为在逻辑上来讲如果对象已经被销毁而不存在,那么所在位置则有可能出现错误。
注意脚本写好以后将“死地鼠”的预制体拖拽给“地鼠”对象身上的脚本S1的m_prefab2
- 新建S2脚本给“死地鼠”,(也可以直接Add Component脚本S2取代拖拽)
void Start () {
Destroy(gameObject, 0.5f);
}
使对象“死地鼠”在出现0.5秒以后自动销毁
同理可以应用在S1脚本中,使对象“地鼠”在始终没有受到点击时出现3秒后自动销毁
保存场景
- 新建空物体命名为GreateTarget,并给他添加脚本CreateTarget,实现对象的自动随机生成,代码如下
public GameObject
m_Target; //引用对象“地鼠”
InvokeRepeating函数可以在制定间隔调用指定函数,实现Create函数的重复调用,即实现“地鼠”对象的重复生成
void Start() {
InvokeRepeating("Create", 0, 1);//该调用函数为Create,等待时间为0(密集运行),间隔为1s
//每指定间隔调用生成一次函数
}
Create函数实现地鼠的实例化生成以及随机出现
首先定义位置变量pos,然后产生随机的id值,再使用if函数根据随机产生的id值确定pos的值即对象实例化的位置,最后Instantiate函数进行对象的实例化
void Create() {
Vector3 pos = Vector3.zero; //初始化建立位置变量
int id= 0;
id = Random.Range(1,10); //在1~9的9个数中随机产生一个数值
if (id== 1)
pos = new Vector3(0, 0, 0);
if (id== 2)
pos = new Vector3(2, 0, 0);
if (id== 3)
pos = new Vector3(-2, 0, 0);
if (id== 4)
pos = new Vector3(0, 1, 0);
if (id== 5)
pos = new Vector3(2, 1, 0);
if (id== 6)
pos = new Vector3(-2, 1, 0);
if (id== 7)
pos = new Vector3(0, -1, 0);
if (id== 8)
pos = new Vector3(2, -1, 0);
if (id== 9)
pos = new Vector3(-2, -1, 0);
Instantiate(m_Target, pos, Quaternion.identity);
//实例化对象
}
- 此时功能基本实现完全,最后给两个对象添加Audio Source组件,导入出现和击中地鼠的音效并对应添加音效
- 运行游戏,对时间间隔等数值进行适当的调整,并保存工程
出现的问题及解决方法
- “地鼠”对象模型问题。因为没有现成的地鼠模型,如果直接把贴图贴给3d cube的话形状不匹配而且是倒着的
解决过程:但我想到之前讲到的3D对象和2D对象的不同在于2D对象需要手动添加碰撞器。而此次游戏刚好是一个2D游戏,所以我猜想如果给2D的图片添加碰撞器是否可以在游戏中实现需要的对象效果。尝试成功。
- 但是2D的“地鼠”对象偶尔会出现“隐身”的情况,只能看到边框而看不到图片内容。
解决过程:我搜索了2D对象看不到的原因,但是没有找到解决办法。无奈之下我删除原来制作好的对象并重新导入图片做了一遍,对象就又是可见的了。我猜想这可能是因为软件的稳定性等等原因造成的。
收获
- 学到了平面图形可以添加碰撞器,从而在2D游戏中达到和3D对象同样的效果
- 学习了一个新的函数InvokeRepeating(“函数名”,等待时间,调用时间间隔),可以在每指定时间间隔调用生成一次函数。
之前学习unity3D时有学过一个类似功能的函数叫携程函数,不过实现的功能更加全面,可以设置多个时间间隔,从而体现出关卡的效果。 - 第一次接触到设置对象自动销毁时间的方法,Destory(gameObject,销毁时间)。
就是不知道这些用在Unity2D游戏里的函数能不能同样在Unity3D游戏中使用,不过理论上应该是可以的。 - 学习到制作一个游戏的过程是把每一个想要实现的功能细化到最小的指令,然后用代码一一对应实现。