赛道
本课属于 Coddy Unity 学习旅程的“打造真正的游戏”单元。第 49 课,共 60 课。
这一章会制作一款 3D 平台跳跃游戏。你可以在漂浮的平台间奔跑和跳跃,乘上滑动的平台,触碰检查点,这样跌落后就不会回到起点;还可以收集屏幕上计数的宝石,冲过终点进入下一关,并试着刷新自己的最佳用时。游戏从一开始就包含 5 个脚本:Player、MovingPlatform、Checkpoint、Gem 和 FinishLine。后 4 个脚本目前是空的,每节课会完成其中一个。玩家使用 CharacterController,由 Input System 的操作控制;摄像机是玩家的子对象,因此无需脚本就能跟随玩家。
CharacterController 有两种移动方式。Move(motion) 会按指定距离移动它,不会添加其他效果,因此重力、跳跃和 Time.deltaTime 都需要由脚本处理,就像 Character Controller 这一章中讲的那样。SimpleMove(speed) 接收每秒移动的单位数作为速度,会自动乘以当前帧的时间并添加重力;它会忽略传入的 y 值,因此用它移动的角色会从边缘掉下去,却永远无法跳跃。这个俯视牧羊游戏中的牧羊犬不需要跳跃,所以 SimpleMove 和 Move 操作就是它的完整脚本:
using UnityEngine;
using UnityEngine.InputSystem;
public class Sheepdog : MonoBehaviour
{
[SerializeField] private float speed = 6f;
private CharacterController controller;
private InputAction moveAction;
void Start()
{
controller = GetComponent<CharacterController>();
moveAction = InputSystem.actions.FindAction("Move");
}
void Update()
{
Vector2 input = moveAction.ReadValue<Vector2>();
controller.SimpleMove(new Vector3(input.x, 0f, input.y) * speed);
}
}平台跳跃游戏中的玩家需要跳跃,因此要自行保存垂直速度,并使用 Move 移动;玩家读取的是 Move 和 Jump 操作,而不是 Input 类。Unity 建议每帧只调用一次 Move 或 SimpleMove:行走和下落会放在同一次调用中处理,而 isGrounded 描述的也是这次完整的移动。
挑战
中等让玩家行走、跳跃和下落。
- 在
Start()中,使用InputSystem.actions.FindAction查找Move和Jump。 - 在
Update()中,以speed的速度行走:让 Move 的 x 沿 x 轴移动,让它的 y 沿 z 轴移动。 - 将
gravity * Time.deltaTime加到velocity.y上;着地且正在下落时,将其设为-2f。着地时跳跃,则将其设为Mathf.Sqrt(jumpHeight * -2f * gravity)。 - 调用一次
controller.Move((move + velocity) * Time.deltaTime)。
按下“开始”:跳到第一个平台上。然后按“检查”。
亲手试试
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
[SerializeField] private float speed = 5f;
[SerializeField] private float jumpHeight = 1.5f;
[SerializeField] private float gravity = -9.81f;
private CharacterController controller;
private Vector3 velocity;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
// 用 Move 动作移动,用 Jump 动作跳跃,受重力作用下落
}
}
打造真正的游戏中的所有课
自己练习: Unity 在线编辑器