Menu
CoddyTech

Кинематические тела

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

Подвижные платформы, лифты и двери должны сталкиваться с объектами как твёрдые тела, но они не должны падать или сдвигаться от того, что на них приземляется. Это кинематическое тело: задайте rb.isKinematic = true, и гравитация, силы и столкновения больше не будут его перемещать. Его коллайдер по-прежнему учитывается, поэтому динамическое тело (которое перемещается физикой) ударяется о него, как о стену, и стоит на нём, как на полу. Кинематическое тело вы перемещаете сами, используя rb.MovePosition.

Этот лифт поднимается со скоростью lift м/с, пока не достигнет top. MovePosition принимает позицию, в которой тело должно оказаться после этого шага, поэтому код прибавляет перемещение за один шаг, используя Time.fixedDeltaTime:

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

void FixedUpdate()
{
    if (rb.position.y < top)
    {
        rb.MovePosition(rb.position + Vector3.up * lift * Time.fixedDeltaTime);
    }
}

Почему бы не задать transform.position? Это телепортирует объект, и физика не узнает, что он переместился: ящик на движущейся платформе останется позади, а не поедет вместе с ней. MovePosition сообщает физике, что тело переместилось на новое место за этот шаг, поэтому всё, с чем оно соприкасается, переносится и отталкивается должным образом. AddForce не действует на кинематическое тело, а кинематические тела никогда не сталкиваются со статическими коллайдерами или друг с другом: с ними сталкиваются только динамические тела.

challenge icon

Задание

Легко

Подвесь баржу над лавой и перемещай её стрелками.

  1. В Start() задай rb.isKinematic = true;.
  2. В FixedUpdate() считай float h = Input.GetAxisRaw("Horizontal"); и вызови rb.MovePosition(rb.position + Vector3.right * h * speed * Time.fixedDeltaTime);.

Нажми «Играть» и перемещай баржу: она будет висеть в воздухе, а дрон будет отскакивать от неё. Затем нажми «Проверить».

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

using UnityEngine;

public class Barge : MonoBehaviour
{
    public float speed = 2f;
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        // Сделайте баржу кинематической
    }

    void FixedUpdate()
    {
        // Перемещайте её вдоль оси x с помощью стрелок
    }
}

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

Потренируйтесь самостоятельно: Песочница Unity