[TOC]

1 创建新项目

启动unity,点击“新项目”,选择“2d”,这样就创建了一个新项目。

导入素材有两种方法:

①点击window菜单栏 -> Asset Store -> 搜索 -> Import

将所有资源一次性全部导入。

② 准备好本地资源,拖拽到Assets文件夹下。

保存游戏关卡:

点击File -> save as -> 选择Scenes文件夹 -> 重命名为“Stage1” -> 保存。

点击File -> Build Settings…,将保存好的场景文件拖拽到Scenes in build的框内,这样这个场景就可以使用了。

2 使用图像素材制作游戏画面

将背景图像和跳台图像拖拽到场景视图中,注意要放在摄像机的范围内,并将跳台的Order in layer设置为2(0以上的数值)。

把玩家图像拖拽到场景视图中,Order in layer设置为3。

这样,图像显示的优先顺序就变成了玩家>跳台>背景。

3 制作玩家角色

选择玩家,单击Add Component -> 搜索Rigidbody 2D -> 单击添加。

将重力Gravity Scale设置为1.5。

勾选Freeze Rotation Z。(禁止旋转)

单击Add Component -> 添加Capsule Collider 2D。

给物体添加碰撞体积:

选中跳台,单击Add Component -> 搜索Rigidbody 2D -> 单击添加。

这样,也给跳台添加了重力效果。

单击Add Component -> 添加Box collider 2D,这样就给跳台添加了碰撞体积。

微信截图_20240808020912

可以看到角色稳稳当当地落在跳台上。

4 用脚本控制角色移动、跳跃、动画

新建C#脚本,命名为PlayerController。

拖拽脚本使其附着在玩家角色上。

1
2
3
GameObject obj =(游戏物体).GetComponent<类型名>();
可以用此方法取得附着于该游戏物体上的任意组件。
当用的是this.时,表示从自身取得。此外,this.的写法可以省略。

Update函数:

游戏通过定期对画面进行微小的刷新,来使画面看起来在动,这就是帧。

在unity中,每一帧都会调用一次update函数,将画面刷新和游戏动作相关的内容在update函数中实现,就可以反映在游戏中了。

update函数不一定就是周期调用的,FixedUpdate函数才是周期调用。

移动:

1
2
3
4
float axisH = 0.0f;//输入
//省略
//(Update函数)
axisH = Input.GetAxisRaw("Horizontal");

这一行用来检测键盘的左右方向键有没有被按下。horizontal在英语中是水平的意思。
当按下右,GetAxisRaw会返回1.0f,
按下左会返回-1.0f,
什么都不按下会返回0.0f。

1
2
3
4
public float speed = 3.0f;//移动速度
//省略
//FixedUpdate函数
rbody.velocity = new Vector2(axisH * speed, rbody.velocity.y);

物理类的处理需要添加到FixedUpdate函数中。
Rigidbody2D类所带的velocity变量是反映该游戏物体当前移动速度的vector2类型的变量。通过给这个变量赋值,可以对Rigidbody2D组件的速度进行操作。
右:3.0f,
左:-3.0f,
不动:0.0f。

角色翻转:

1
2
3
4
5
6
7
8
9
10
11
if (axisH > 0.0f)
{
//向右移动
Debug.Log("向右移动");
transform.localScale = new Vector2(1, 1);
}
else if (axisH < 0.0f) {
//向左移动
Debug.Log("向左移动");
transform.localScale = new Vector2(-1, 1);//左右翻转
}

localScale是设置缩放倍率的参数,当其设置为负值时,就可以达到翻转效果。

角色跳跃:

这一步接在5的后面。

对玩家角色选中Player标签。

1
2
3
4
public float jump = 9.0f;//跳跃力
public LayerMask groundLayer;//可以落脚的层
bool goJump = false;//跳跃开始的旗标
bool onGround = false;//立于地面的旗标

groundLayer是用来设定对地面增加的Ground层的。

层用LayerMask类型表现。

在LayerMask的前面加上public,从而能够在unity编辑器中修改它。

1
if (Input.GetButtonDown("Jump"))   Jump();//跳跃

Input是用于处理输入的类。

GetButtonDown是用于判定指定按键时候被按下的函数,返回值为bool类型。

1
2
3
4
5
6
if (onGround || axisH != 0)
{
//在地面上或速度不为0
//更新速度
rbody.velocity = new Vector2(axisH * speed, rbody.velocity.y);
}

实现当按键松开时,玩家不会笔直坠落。

为了使角色跳跃,调用了Rigidbody类的AddForce函数。

这是一种为附着了Rigidbody2D组件的游戏物体施加力的方法。这里向上施加了9.0f的力,也就是向正上方起跳,然后通过AddForce的第二参数来指定施加怎样的力。

ForceMode2D.Impulse指定的是施加瞬时的力。

做到这里,在脚本中找到Ground Layer,选择Ground。

动画:

1
2
3
4
5
6
7
8
9
10
 //接触开始
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Goal"){
Goal();
}else if (collision.gameObject.tag == "Dead")
{
GameOver();
}
}

OnTriggerEnter2D函数是当物体触碰到了碰撞体积时自动调用的方法。

其参数collision是触碰到的Collider组件,其带有的gameObject变量是附着了Collider组件的游戏物体。如果tag为Goal,就调用Goal函数,tag为Dead,就调用GameOver函数。

之后,调整玩家的游戏状态变量等以实现初始化。

5 制作游戏关卡

Layer-> Add layer… -> 新增layer为Ground。

对跳台和障碍物都设定为Ground。

将障碍物拖拽到画面上,将Order in Layer设置为2,添加Box Collider 2D组件。

设置终点:

把终点图像拖拽到画面上,Order in Layer设置为2,附着Box Collider 2D组件,并勾选Is Trigger,进行终点判定。

之后通过脚本来进行实际的终点判定。

Tag -> Add Tag… -> Tags + -> 输入Goal -> save保存,将标签设置为Goal标签。

制作看不见的碰撞体积:

为了不让玩家角色从画面的两端掉下去,需要造一堵看不见的墙,也就是碰撞体积。

单击层级视图左上角的+ -> Create Empty -> 命名为WallObject,添加两个Box Collider 2D组件,调整成适合的形状。

制作游戏失败的碰撞体积:

首先利用跳台制作一个空穴,判定玩家掉进空穴就会失败。

Create Empty -> 改名为DeadObject,将Box Collider 2D组件附着在空物体上,调整成适合的形状,选中Is Trigger。再制作一个Dead标签。

6 开发游戏的UI

添加图像UI:

Create -> UI -> Image,这样就在层级视图中添加了一个叫做Canvas的物体。

选中Canvas,将Render Mode设置为Screen Space-Camera,将Order in Layer设置为10。点住Main Camera,将其拖到Render Camera的文本框中。这样Canvas的尺寸就收入了摄像机的范围内了。

把项目视图中的Game Start拖拽到Source Image。

微信截图_20240808132100