Grawitacja ręcznie
Część sekcji Tworzenie prawdziwych gier ścieżki Unity w Coddy. Lekcja 39 z 60.
CharacterController opada tylko wtedy, gdy skrypt sprawia, że opada, a rzeczywisty spadek przyspiesza: grawitacja dodaje do prędkości opadania około 9.81 jednostki na sekundę w każdej sekundzie. Dlatego skrypt przechowuje prędkość pionową w polu, dodaje do niej co klatkę gravity * Time.deltaTime i przemieszcza obiekt o tę wartość w tym samym wywołaniu Move co podczas chodzenia:
public float gravity = -9.81f;
float verticalSpeed;
void Update()
{
if (controller.isGrounded && verticalSpeed < 0f)
{
verticalSpeed = -2f; // na ziemi: zakończ spadanie, utrzymuj lekką siłę skierowaną w dół
}
verticalSpeed += gravity * Time.deltaTime;
Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
move.y = verticalSpeed;
controller.Move(move * Time.deltaTime);
}Time.deltaTime pojawia się dwa razy i za każdym razem pełni inną funkcję: gravity * Time.deltaTime to przyrost prędkości w tej klatce, a prędkość pomnożona przez Time.deltaTime to odległość pokonana w tej klatce. Prędkość jest przechowywana w polu, ponieważ musi być zachowana z klatki na klatkę; zmienna lokalna zaczynałaby od 0 w każdej klatce. Spadając od spoczynku, kontroler po pół sekundy osiąga prędkość -4.9 jednostki na sekundę, a po jednej sekundzie -9.81.
Reset jest równie ważny jak sam spadek. Na podłożu Move zatrzymuje kontroler, ale nic nie zatrzymuje pola: bez resetu jego wartość stale rośnie, gdy gracz stoi, a po zejściu z krawędzi gracz spada z pełną prędkością. Wartość jest resetowana do niewielkiej liczby ujemnej zamiast do 0, dzięki czemu każde wywołanie Move nadal dociska obiekt do podłoża: przy wysokiej liczbie klatek na sekundę siła nacisku wywołana grawitacją w jednej klatce może być mniejsza niż Min Move Distance, Move nic nie zrobi, a isGrounded przyjmie wartość false. isGrounded jest odczytywane przed wywołaniem Move, więc opisuje działanie Move z poprzedniej klatki.
Wyzwanie
ŚredniDodaj grawitację nurkowi, aby jego spadanie przyspieszało.
- Na początku
Update(), gdycontroller.isGroundediverticalSpeed < 0f, ustawverticalSpeed = -1f;. - Dodaj do niej
gravity * Time.deltaTimei utrzymuj ją na poziomie-maxFalllub wyższym, używającMathf.Max. - Przed linią
controller.Moveustawmove.y = verticalSpeed;.
Naciśnij „Graj” i zejdź z wieży: spadanie przyspieszy do 10 jednostek na sekundę. Następnie naciśnij „Sprawdź”.
Spróbuj swoich sił
using UnityEngine;
public class Diver : MonoBehaviour
{
public float speed = 4f;
public float gravity = -12f;
public float maxFall = 10f;
CharacterController controller;
float verticalSpeed;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
// Grawitacja: zresetuj verticalSpeed na ziemi, dodaj grawitację, ogranicz prędkość spadania i przypisz wynik do move.y
Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
controller.Move(move * Time.deltaTime);
}
}
Wszystkie lekcje w sekcji Tworzenie prawdziwych gier
1Tekst na ekranie
Canvas i tekstWyświetlanie wynikuFormatowanie liczbOdliczanie czasuPowtórka: prędkościomierz2Przyciski i ekrany
Przyciski i onClickLambdyPodłączanie w InspectorzeWłączanie i wyłączanie paneliPaski zdrowiaPodsumowanie: sklep z ulepszeniami5Zapisywanie za pomocą PlayerPrefs
Zapisz liczbęWczytywanie z wartością domyślnąNajlepszy wynikZapisz ustawieniaPodsumowanie: monety w banku8Sterowanie postacią
CharacterController.MoveGrawitacja ręcznieSkakaniePopychanie obiektówPoruszanie się w kierunku patrzeniaPodsumowanie: podwójny skokPoćwicz samodzielnie: Edytor online Unity