搭上平台
本课属于 Coddy Unity 学习旅程的“打造真正的游戏”单元。第 51 课,共 60 课。
CharacterController 不会被它站立的平台带着移动:站在移动平台上时,它会停在原地,平台则会从它脚下滑走。修改它的 transform.position 没有用,因为下一次 Move 会从物理系统上次记录的位置开始,并撤销这次修改。
因此,玩家会把平台的移动加到自己的移动中。每当 Move 接触到一个碰撞体时,都会调用 OnControllerColliderHit(ControllerColliderHit hit);从下方碰到的平台,其 hit.normal.y 接近 1。下面是一个用相同方式载着箱子的渡船示例:
private Ferry ferry;
void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.normal.y > 0.7f && hit.gameObject.TryGetComponent(out Ferry f))
{
ferry = f;
}
}挑战
中等让玩家乘坐移动平台。
- 在
Player中,添加private MovingPlatform platform;和OnControllerColliderHit:当hit.normal.y > 0.5f且对象上有MovingPlatform时,将它保存在platform中。 - 在
Update()中,将(move + velocity) * Time.deltaTime放入Vector3 motion。如果platform != null,则添加platform.delta,并设置platform = null。 - 调用
controller.Move(motion)。
按“开始”,然后跳上平台:它会带着你移动。接着点击“检查”。
亲手试试
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 InputAction moveAction;
private InputAction jumpAction;
private Vector3 velocity;
void Start()
{
controller = GetComponent<CharacterController>();
moveAction = InputSystem.actions.FindAction("Move");
jumpAction = InputSystem.actions.FindAction("Jump");
}
void Update()
{
if (controller.isGrounded && velocity.y < 0f)
{
velocity.y = -2f;
}
Vector2 input = moveAction.ReadValue<Vector2>();
Vector3 move = new Vector3(input.x, 0f, input.y) * speed;
if (jumpAction.WasPressedThisFrame() && controller.isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move((move + velocity) * Time.deltaTime);
}
}
打造真正的游戏中的所有课
自己练习: Unity 在线编辑器