Grawitacja ręcznie
Część sekcji Tworzenie prawdziwych gier ścieżki Unity w Coddy. Lekcja 38 z 56.
CharacterController spada tylko wtedy, gdy skrypt sprawia, że spada, a rzeczywisty upadek przyspiesza: grawitacja dodaje około 9.81 jednostki na sekundę do prędkości spadania w każdej sekundzie. Dlatego skrypt przechowuje prędkość pionową w polu, dodaje do niej gravity * Time.deltaTime w każdej klatce 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 opadanie, zachowaj lekki nacisk 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 prędkość uzyskana w tej klatce, a prędkość pomnożona przez Time.deltaTime to odległość pokonana w tej klatce. Prędkość jest polem, ponieważ musi być zachowana z klatki na klatkę; zmienna lokalna zaczynałaby od 0 w każdej klatce. Spadając z miejsca, CharacterController osiąga prędkość -4.9 jednostki na sekundę po pół sekundy i -9.81 po jednej sekundzie.
Reset jest równie ważny jak sam upadek. Na podłożu Move zatrzymuje CharacterController, 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ą. Prędkość jest resetowana do niewielkiej wartości ujemnej zamiast do 0, dzięki czemu każde wywołanie Move nadal dociska postać do podłoża: przy dużej liczbie klatek na sekundę siła grawitacji działająca przez jedną klatkę może być mniejsza niż Min Move Distance, Move nic nie robi, a isGrounded przyjmuje wartość false. Odczyt isGrounded następuje przed wywołaniem Move, więc opisuje działanie Move z poprzedniej klatki.
Wyzwanie
ŚredniNurek stoi na wysokiej wieży, a strzałki nim poruszają (to już jest napisane). Dodaj grawitację w Diver.cs. W Inspectorze ustaw gravity (-12) i maxFall (10), a skrypt ma pole verticalSpeed.
- W każdej klatce
verticalSpeedzwiększa się ogravityna sekundę, a nurek porusza się w dół o tę wartość w tym samym wywołaniu Move, co podczas chodzenia. - Opór powietrza spowalnia długi upadek: nurek nigdy nie spada szybciej niż
maxFalljednostek na sekundę. - Gdy kontroler wykrywa podłoże, a
verticalSpeedjest mniejsze od 0, ustawverticalSpeedna -1.
Naciśnij Play, zejdź z wieży, a następnie naciśnij Check.
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: na ziemi zresetuj verticalSpeed, dodaj grawitację, ogranicz prędkość opadania i przypisz ją do move.y
Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
controller.Move(move * Time.deltaTime);
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Tworzenie prawdziwych gier
1Tekst na ekranie
Canvas i tekstWyświetlanie wynikuFormatowanie liczbOdliczanie czasuPowtórka: prędkościomierz4Sceny i poziomy
Wczytaj scenęUruchom poziom ponownieNastępny poziomZachowaj między scenamiPodsumowanie: wybór poziomu10Projekt: platformówka 3D
TrasaRuchome platformy2Przyciski 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 skok