Unity2D 入门教程
教程来源:B 站 Up 主的课程:Unity教程 入门第一款游戏制作
以下都是基于 2D 游戏
常用操作
通用操作
游戏状态进行保存
在游戏运行时修改 Inspector 中组件的参数,点击组件右上角,选择 Copy Componpent,
游戏运行结束后,点击组件右上角,选择 Paste Component Values,可以实现保存运行时的参数
使用 TileMap 绘制地图
TileMap 创建:Hirerachy > 右键 > 2D Object > TileMap
创建调色板:Window > 2D > Tile Palette
-
将图片拖到调色板中即可变成 Tile 文件,然后可以用调色板的工具绘制地图
-
Tile 文件可以存在 Environment 下新建一个 map 目录
每单位像素数 (Pixels Per Unit):选中精灵资源在 Inspetor 面板里会看到,表示在一个 Unity 单位中一行或一列有几个像素点
- 如果瓦片拖到界面上后,瓦片之前有间距,可以调整这个参数
切割图集:选中一张精灵图片资源,将 SpriteMode 从 single 改为 mutiple,可制作成图集,再点击 SpriteEditor 可进行切割。
切割有三种形式:自动,按像素切割,按行列切割
- 对于一张比较大的精灵图,我们拖到 Scene 上看似占用比较大的空间,其实只占用了一个格子,为了让它的实际占用很看起来一样大,需要将这张图切割成图集
- 对于这种看似比较大的图片,使用按行列切割,切割成一个个小格子
实现碰撞体效果
Rigidbody:刚体组件,使游戏物体能获得重力,接受外界的受力和扭力功能的组件
BoxCollider:碰撞器组件,使游戏物体具有跟挂载刚体组件的游戏物体发生碰撞能力的组件
实现碰撞效果:给人物添加 Rigidbody 2D 和 Box Collider 2D 组件,给 Tilemap 添加 Tilemap Collider 2D 组件
不允许旋转效果:Rigidbody 2D > Constraints > Freeze Rotation
移动 Bug 的修复
如果给整个人物添加方形的 Collider,移动时会卡住,解决方案是下半身使用圆形的 Collider
实现人物控制
输入按键设置:Edit > Project Settings > Input Manager,这里可以更改各个轴向映射的按键
GetAxis
获取 [-1, 0], [0, 1] 之间的小数:
float horizontalMove = Input.GetAxis("Horizontal");
GetAxisRaw
获取的是 -1, 0, 1 中的某个值
float faceDirection = Input.GetAxisRaw("Horizontal");
GetButton
可以检测到用户按下某个功能键,如 Jump - 跳跃
if (Input.GetButton("Jump"))
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce * Time.deltaTime);
}
动画系统
打开动画面板:Window -> Animation -> Animation
- 动画面板用于制作动画,将一系列图片拖进去做出动画效果
打开动画器面板:Window -> Animation -> Animator
- 动画器面板用于关联各个动画之间的状态转换
添加动画效果:
1、给游戏组件添加 Animator 组件
2、创建一个存放动画的文件夹,在文件夹里创建一个 Animator Controller,用于控制动画
3、将 Animator Controller 拖到 Animator 组件上
4、选中游戏组件,在动画面板,创建一个 idle 动画,并将动画图片拖入
实现跑动动画:
1、创建一个 run 动画
2、在动画器面板,run 和 idle 之间创建过渡(make transition)
3、Parameters 中添加参数 running
,float 类型
4、idle -> running 的过渡,将 Has Exit Time 去掉,Transition Offset 设为 0,Conditions 为 running > 0.1
running -> idle 同理,Conditions 为 running < 0.1
5、根据上面给过渡设置的 Conditions,在代码中用 animator.SetFloat()
给 running 赋值,来控制跑动动画
实现跳跃和降落动画:
1、创建 jump 动画、fall 动画
2、在动画器面板,各个动画之间创建过渡(make transition)
3、Parameters 添加参数 jumping
、falling
,Bool 类型
4、过渡的 Inspector 中,将 Has Exit Time 去掉,Transition Offset 设为 0
往 jump 过渡的 Conditions 为 jumping = true
;往 fall 过渡的 Conditions 为 falling = true
5、根据 Conditions,编写代码
public Rigidbody2D rb; // 刚体
public BoxCollider2D coll; // 碰撞体
public Animator animator; // 动画器
public LayerMask ground; // 地面图层
...
// 检查并切换动画状态
void SwitchAnim()
{
// 处于跳跃状态
if (animator.GetBool("jumping"))
{
// y轴的力没有了
if (rb.velocity.y < 0)
{
animator.SetBool("jumping", false);
animator.SetBool("falling", true);
}
}
// 处于降落状态, 碰撞了地面
else if (coll.IsTouchingLayers(ground))
{
animator.SetBool("falling", false);
animator.SetBool("idle", true);
}
}
6、代码中的 public LayerMask ground
指的就是游戏物件所处的图层:
为了实现检测碰撞地面,需要给 Tilemap 设置一个图层 Group,并在代码中获取:
镜头控制
脚本控制
这个方法就是给 Main Camera 添加一个脚本,让它的 Transform 的 x、y 时刻与 player 保持一致即可
关于 y 是否需要保持一致主要看游戏需求,例如超级马里奥跳起来镜头不会动,恶魔城跳起来镜头就会跟随
public class CameraController : MonoBehaviour
{
public Transform player;
void Update()
{
transform.position = new Vector3(player.position.x, 0, -10f);
}
}
Cinemachine
首先在 Package Manager 中安装 Cinemachine,然后顶部菜单会多一个 Cinemachine
背景跟随:
1、Cinemachine > Create 2D Cinemachine,创建一个 CM vcam 1 对象
2、将要跟随的游戏对象拖到 CM vcam 1 > Inspector 中的 Follow
Inspector 中的一些参数:
-
Lens > Orthographic Size:调整镜头大小
-
Body > Dead Zone:镜头不会跟随的一段区域,超出这个区域则会自动跟随
-
…
给背景限定区域:
-
CM vcam 1 > Inspector > Add Extension > Cinemachine Confiner
-
需要给上面的组件指定一个 Collider,给 Background 添加 Collider(勾选 isTriger)
这里使用 Polygon Collider
-
CM vcam 1 > Inspector > Cinemachine Confiner > Bounding Shape 2D 指定为 Background 的 Collider
添加物品
在界面上添加游戏物件的方法:
- 创建一个 Sprites,将物品素材拖给它,记得修改对应的层级
给物品添加的动画效果:
- 给物体添加 Animator 组件,在文件夹中创建一个 Animate Controller 并拖到物体身上的 Animator 中
- 在动画面板中创建动画效果
给物品添加碰撞销毁事件
-
给物品添加 Box Collider 2D 组件,并勾选的 isTrigger
不勾选 isTrigger 则像墙一样撞不动,勾选后可以进行一些触碰事件(配合
OnTriggerEnter2D
函数) -
给物体设置 Tag 为 Collection
// 碰撞事件
private void OnTriggerEnter2D(Collider2D collision)
{
// 如果碰撞到的物体标签是Collection,则销毁
if (collision.CompareTag("Collection"))
{
Destroy(collision.gameObject);
}
}
制作预制体
创建一个 Prefabs 文件夹,将做好的 Cherry 物品拖到该文件夹中,后面就做好的物品为模版,反复创建其他物品(功能相同)
如果不使用 Prefabs,则每次新增一个物品都需要反复执行大量重复操作,有 Prefabs 只需要复制即可
代码理解
Time.deltaTime
代表两帧之间的时间差。
- 脚本中的
update()
方法虽然是每帧运行,但实际运行时两帧之间的时间间隔不一定相等。
对于 Rigidbody、Collider 这种,几乎每个游戏物件身上挂载后是不会变的,因此可以不声明为 pubilc,再通过 Unity 中拖拽赋值,
可以直接声明为 private,并在代码中赋值。
[SerializeField]
可以使得 private 变量也显示在 Unity 中。
[SerializeField] private Rigidbody2D rb;