Menu
CoddyTech

Ande na plataforma

Parte da seção Criando Jogos de Verdade do Journey de Unity da Coddy. Lição 51 de 60.

Um CharacterController não é carregado pelo objeto em que está apoiado: em uma plataforma móvel, ele fica parado, e a plataforma desliza para longe por baixo dele. Alterar seu transform.position não ajuda, porque o próximo Move começa de onde a física o viu pela última vez e desfaz a alteração.

Então, o jogador soma o movimento da plataforma ao próprio movimento. OnControllerColliderHit(ControllerColliderHit hit) é executado para cada colisor que um Move toca; um contato por baixo tem hit.normal.y próximo de 1. Uma balsa que carrega uma caixa da mesma forma:

private Ferry ferry;

void OnControllerColliderHit(ControllerColliderHit hit)
{
    if (hit.normal.y > 0.7f && hit.gameObject.TryGetComponent(out Ferry f))
    {
        ferry = f;
    }
}
challenge icon

Desafio

Médio

Faça o jogador andar na plataforma móvel.

  1. Em Player, adicione private MovingPlatform platform; e OnControllerColliderHit: quando hit.normal.y > 0.5f e o objeto tiver um MovingPlatform, mantenha-o em platform.
  2. Em Update(), coloque (move + velocity) * Time.deltaTime em Vector3 motion. Se platform != null, adicione platform.delta e defina platform = null.
  3. Chame controller.Move(motion).

Pressione “Jogar” e pule na plataforma: ela levará você. Depois, clique em “Verificar”.

Experimente você mesmo

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);
    }
}

Todas as lições de Criando Jogos de Verdade

Pratique por conta própria: Playground de Unity