Menu
CoddyTech

Стояние на земле

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 11 из 63.

У каждого контакта есть нормаль: направление длиной 1, перпендикулярное поверхности, которой ты коснулся, и направленное от неё к твоему объекту. collision.GetContact(0) — это первая точка контакта, а её normal показывает, какой стороны ты коснулся. Если стоять на ровной земле, это (0, 1, 0); если коснуться стены справа — (-1, 0, 0); если удариться головой о потолок — (0, -1, 0).

Этот ящик отличает приземления от боковых столкновений:

void OnCollisionEnter(Collision collision)
{
    Vector3 normal = collision.GetContact(0).normal;
    if (normal.y > 0.5f)
    {
        Debug.Log("Landed on " + collision.gameObject.name);
    }
    else
    {
        Debug.Log("Bumped the side of " + collision.gameObject.name);
    }
}

Проверка использует normal.y > 0.5f, а не ровно 1, чтобы склоны тоже считались землёй: на склоне под углом 60 градусов y равно 0.5 — это круче, чем ходит кто-либо. Ещё два сообщения помогут отследить всё, что длится дольше: OnCollisionStay выполняется на каждом шаге физики, пока длится контакт, а OnCollisionExit — один раз, когда он заканчивается. При выходе точек контакта нет, поскольку больше ничего не соприкасается, поэтому не вызывай там GetContact.

challenge icon

Задание

Легко

Игрок может ходить и прыгать, но клавиша Space работает и в воздухе, поэтому он может взбираться в небо прыжок за прыжком и прыгать со стены в сторону. (У его коллайдера материал без трения, поэтому он скользит вниз по стенам, а не прилипает к ним.) Сделай так, чтобы он прыгал, только когда стоит на чём-нибудь.

  • Используй bool grounded: значение true, пока игрок касается чего-либо, нормаль контакта с чем направлена вверх (y больше 0.5), и false, как только он перестаёт касаться.
  • Прыгай, только когда была нажата клавиша Space и значение grounded равно true. Нажатие в воздухе игнорируется, а не сохраняется до приземления.

Нажми Играть, попробуй прыгнуть дважды и забраться на стену, затем нажми Проверить.

Попробуйте сами

using UnityEngine;

public class Hopper : MonoBehaviour
{
    public float speed = 4f;
    public float jump = 6f;
    private Rigidbody rb;
    private bool jumpPressed;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            jumpPressed = true;
        }
    }

    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        rb.linearVelocity = new Vector3(h * speed, rb.linearVelocity.y, 0);
        if (jumpPressed)
        {
            rb.AddForce(Vector3.up * jump, ForceMode.Impulse);
            jumpPressed = false;
        }
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Физика и игровой процесс