目录
一、前言
本案例是初级案例,意在引导想使用unity的初级开发者能较快的入门,体验unity开发的方便性和简易性能。
游戏中,小球会以恒定的速度向前运动。玩家通过控制小球左右移动来避开小球在前进路上的障碍物。如果玩家控制小球一直向前跑,一定距离后则认定玩家取得胜利。当玩具在取得胜利前,碰到路上的障碍物或者跌落路面,游戏失败。
二、开发环境
操作系统:Windows
Unity 版本:2021.3.11f1c2 LTS
三、场景搭建
1. 创建项目
1.1 打开Unity Hub,在Project标签下,点击右上角 New project 按钮。打开新建项目对话框。
1.2 在新建项目窗口中,选择3D 模板,填入项目名称 BallRun,选择项目保存的位置,取消版本控制选项的对钩,点击 Create project 按钮,完成项目创建。
2. 创建场景内物体
2.1 创建跑道
在场景中新建一个 Cube(立方体),重命名为Road,并将其长度设定为1000, 宽度改为8,然后将其位置向前移动480,此作为小球的跑到,如图。
2.2 创建玩家
新建一个小球(Sphere)作为玩家,重命名为Player,并放在道路上,调整到合适的位置。(小提示:按住Ctrl建拖拽,可以更好的控制小球的位置)
2.3 创建障碍物
新建若干个Cube(立方体)作为障碍物,并重命名为Barrier,调整障碍物的大小并放到合适的位置。因为要创建多个障碍物,为了以后使用方便,我们可以把障碍物做成预制体,这样我们就可以重复使用这个预制体了。
在Project窗口下,新建文件夹并命名为 Prefabs,然后把 新建的障碍物(Cube)直接拖到Prefabs 目录下,这样预制体就做好了。
在Hierarchy窗口中选中障碍物(Barrier), 按住Ctrl+D, 复制多个物体,并调整他们到合适的位置,完成小球前进路上障碍物的设置。最终效果如图:
2.4 改变跑道和障碍物的颜色
现在,我们看到场景里的小球、道路和障碍物都是白色的,为了更好的区分,我们更改一下道路和障碍物的颜色。更改3D物体的颜色,我们可以通关修改3D物体材质的颜色来改变物体的颜色。
选中物体,我们发现道路和障碍物使用的默认材质并不能直接修改颜色,因此我们需要自己创建跑道和障碍物的材质。
2.4.1 创建材质
在Project窗口下新建文件夹,命名为Materials,用来保存我们自己创建的材质。在Materials文件夹内右键,依次选择 Create -> Material,将新建的Material命名为Road,并调整其颜色为深灰色(颜色值为:201E1E)。用同样的方式创建障碍物的材质,命名为Barrier,并调整其颜色为浅灰色(颜色值:A49898)。( 读者也可以调整为自己喜欢的颜色,颜色主要为了更好地区分场景内的物体,提高用户游戏体验)
2.4.2 给跑道和障碍物更换材质
将我们创建的材质Road,直接拖拽到 Hierarchy 窗口的Road物体上,可以看到跑道的颜色以已经改变。用同样的方式,更换障碍物的材质。
小提示:
由于障碍物是使用的预制体,因此,我们选中预制体,直接把Barrier材质拖到预制体上,这样场景中的所以物体都会改变。这就是使用预制体的好处。
最终效果如图:
好了,到此为止,我们的场景就算搭建完了,下面我们就要进行功能的实现了。
四、功能脚本实现
在Project窗口中新建文件夹Scripts,用来保存我们的脚本文件。
1. 创建玩家脚本
和创建材质一样,在Scripts文件夹右键,依次点击 Create -> C# Script,并命名为Player。将创建的Player脚本拖拽到 Hierarchy 窗口的Player物体上,如图:
双击打开Player脚本,输入以下代码,其中,speed 是小球向前跑的速度,是一个恒定值,默认为10;turnspeed 是玩家控制小球时,小球左右移动的速度。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float speed = 10f;
public float turnSpeed = 5f;
void Update()
{
float turnX = Input.GetAxis("Horizontal");
transform.Translate(turnX * turnSpeed * Time.deltaTime, 0, speed * Time.deltaTime);
}
}
运行游戏,发现小球开始向前跑,当按下键盘上的左右方向键或者A/D键的时候,小球会左右移动。
如果感觉速度不合适,可以通过 Inspector 面板对速度进行调节,如图:
但是在运行时,我们发现,小球会越跑越远,慢慢的就超出我们是视线了,而我们平时玩的跑酷都是一直在视线内。接下来我们就实现相机的跟随。
2. 相机跟随
其实,实现相机的跟随有两种方式,一种是利用脚本控制相机的位置,使相机和小球一直保持一定的相对位置。另一种则更为简单,直接把相机作为小球的子物体,这样小球在移动的时候,相机也会跟着一起移动。这里我们采用第二种方式。
在Hierarchy窗口中拖到相机(Main Camera)到小球(Player)底下。再次运行游戏看下效果,相机一直跟随小球运动了。
3. 胜负的判定
当小球碰撞到障碍物或者掉落到跑道之外的时候,游戏失败。当小球一直未碰到障碍物,一段距离后,判定游戏胜利。
为方便管理,我们将场景中的障碍物都放到一个空物体下。在Hierarchy窗口右键,点击 Create Empty, 创建一个空物体,命名为Barriers,然后选中所有的障碍物,拖动到空物体(Barriers)下。
3.1 游戏失败
3.1.1 碰撞到障碍物
在Scripts文件夹下新建脚本Barrier.cs文件,然后把脚本拖拽到预制体Barrier之上。选中Barrier预制体,勾选预制体上Box Collider的Is Trigger 选项。
双击Barrier.cs文件,在脚本中输入以下代码:
using UnityEngine;
public class Barrier : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
if (other.name == "Player")
{
Debug.Log("游戏失败");
Time.timeScale = 0; // 游戏停止
}
}
}
小提示:
Time.timeScale表示游戏的运行时间倍率,设置为0即表示游戏里的时间停滞,1即正常的时间流逝速度,2即两倍于正常的时间流逝速度,以此类推。
在Hierarchy窗口中选中小球(Player),添加Rigid Body 组件。然后保存,运行游戏,当小球碰到障碍物的时候,游戏便会停止。
3.1.2 小球掉下跑道
双击打开Player.cs脚本,在Update方法里继续补充小球掉下跑道的逻辑。由于跑道的宽度是8,所以跑道的左边缘为-4,右边缘是4. 小球超出边缘后,直接掉落,在掉落一段距离(此处设置的是20)后,判定游戏结束。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float speed = 10f;
public float turnSpeed = 5f;
void Update()
{
float turnX = Input.GetAxis("Horizontal");
transform.Translate(turnX * turnSpeed * Time.deltaTime, 0, speed * Time.deltaTime);
// 小球的位置超出跑道的边缘,则直接掉落
if(transform.position.x<-4||transform.position.x>4)
{
transform.Translate(0, -10 * Time.deltaTime, 0);
}
// 下落一定距离之后游戏结束
if(transform.position.y<-20)
{
Debug.Log("游戏结束");
Time.timeScale = 0;
}
}
}
保存脚本,运行游戏,则小球超出边缘后会垂直下落,一段距离后游戏停止。
3.1.3 重新开始游戏
当游戏失败结束时应该允许玩家重新开始游戏,这里设置键盘上的R键为重置游戏的按键,在按R键后即可重新加载当前场景,重新开始游戏。
在Player.cs脚本的 Update 方法里继续添加代码。注意:这次是添加在前面,注意引入命名空间 using UnityEngine.SceneManagement;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Player : MonoBehaviour
{
public float speed = 10f;
public float turnSpeed = 5f;
void Update()
{
// 按键盘上的R键,重新开始游戏
if(Input.GetKeyDown(KeyCode.R))
{
SceneManager.LoadScene(0); // 重新加载场景
Time.timeScale = 1;
return;
}
float turnX = Input.GetAxis("Horizontal");
transform.Translate(turnX * turnSpeed * Time.deltaTime, 0, speed * Time.deltaTime);
// 小球的位置超出跑道的边缘,则直接掉落
if(transform.position.x<-4||transform.position.x>4)
{
transform.Translate(0, -10 * Time.deltaTime, 0);
}
// 下落一定距离之后游戏结束
if(transform.position.y<-20)
{
Debug.Log("游戏结束");
Time.timeScale = 0;
}
}
}
3.2 游戏胜利
当小球跑一段距离后,我们判定游戏胜利,因此我们需要在跑道上建一个空的物体,作为小球胜利的终点。这个空的物体和障碍物一样,只是它看不见,仅仅作为小球胜利的触发器。
我们在跑道上新建一个空物体。在Hierarchy窗口,右键->Create Empty。将空物体命名为Victory,点击Add Component 按钮,添加Box Collider组件,调整空物体的大小和位置(位置可以自己设定),同时勾选空物体Box Collider 上的Is Trigger 复选框,使空物体变成触发器。如图:
3.2.1 给空物体添加脚本
在Scripts文件夹下,新建脚本文件,命名为Victory,作为小球胜利的逻辑脚本。把Victory脚本挂载到空物体上(直接把脚本拖到空物体上即可)。双击打开Victory脚本,编写胜利逻辑。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Victory: MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
if (other.name == "Player")
{
Debug.Log(" 恭喜胜利! ");
Time.timeScale = 0;
}
}
}
保存脚本,运行游戏。至此,这个小游戏的基本代码就完成了。
五、结束语
本案例作为初级游戏案例,意在使初级开发者可以快速的上手一款游戏的开发,了解Unity开发游戏的便捷,培养初级开发者对游戏开发的兴趣。
作为初级开发者案例,本案例还有许多不足和可以改进的地方,比如可以增加按上键使小球跳跃、增加音乐音效、增加金币、积分,更进一步可以做出胜利和失败的UI界面,这些都可以留待读者自行添加。
最后,希望本案例能对您有所帮助或有所启迪,在游戏开发的道路上,做出自己喜欢的游戏。