Tor wyścigowy- prefabrykat samochodu
Na podstawie oficjalnej dokumentacji Unity dotyczącej kolizji kół- Wheel Colliders(zobacz), stworzymy prostą symulację jazdy samochodem po torze wyścigowym. Na początku po torze prostym. Zobacz krótki film
W nowym projekcie organizujemy układ katalogów ułatwiający organizację tworzeni projektu gry. W głównym katalogu Assets tworzymy podkatalogi: FBX, Materialy,Prefabrykaty, Textury, Skrypty. Podkatalog Scenes tworzony jest automatycznie.
Model samochodu
Model prostej drogi oraz model samochodu przygotowujemy w Blenderze.
Modele eksportujemy do plików *.fbx i importujemy w Unity.
Na scenę dodajemy drogę oraz nasz samochód. Zwróć uwagę, że importowany z Blendera samochód ma kilka obiektów wewnątrz importowanego pliku *.fbx.
Patrz ikona trójkąta widoczna w hierarchii obiektów sceny. Kliknięcie w ikonę pozwoli rozwinąć zawartość importowanego pliku.
Przed przystąpieniem tworzenia prefabrykatu samochodu rozbijamy zawartość importowanego obiektu. Kliknij prawym przyciskiem myszki w nazwę obiektu tak jak poniżej. Wybierz opcje Prefab/ Unpack
Otwieramy katalog Prefabrykaty i myszką przeciągamy z hierarchii sceny obiekt samochodu w obszar otwartego folderu. Patrz poniższy rysunek.
Usuwamy obiekt ze sceny. Klikamy dwa razy szybko w ikonę tworzonego prefabrykatu znajdującą się w otwartym folderze Prafabrykaty. Unity przeniesie nas do edytora tworzenia prefabrykatów. Edycję rozpoczniemy od wyzerowania współrzędnych położenia i rotacji. Patrz poniżej.
O ogólnych zasadach tworzenia pojazdów w silniku Unity wspominałem w tym temacie (zobacz). Tych zasad będziemy się trzymać
Do hierarchii elementów samochodu dodajemy dwa obiekty typu Create Empty. Zmieniamy im nazwę na Kola, CollideryKol. Do obiektu Kola przenosimy siatki kół. Szybę, rurę wydechową i inne elementy karoserii przenosimy do głównego obiektu karoserii. Otrzymujemy taką hierarchię obiektów tworzonego prefabrykatu auta.
Do siatki karoserii dodajemy Mesh Collider, w którym ustawiamy właściwość Convex
Pojazd mamy gotowym. Brakuje oprogramowania obsługującego ruch samochodu.
Skrypt kontroli ruchu samochodem
Tworząc skrypt możemy zdecydować czy pojazd będzie mieć napęd na wszystkie koła czy też na przednie lub tylne. Za każdym razem zachowanie pojazdu jest inne.
Inicjujemy nowy skrypt o nazwie RuchAuta. W skrypcie deklarujemy tablicę transformacji siatek kół oraz tablicę colliderów kół. Określamy maksymalny kąt skrętu, maksymalny moment obrotowy podawany z silnika na pojedyncze koło, moment obrotowy hamowania. Odświeżanie fizyki jazdy wykonamy w funkcji FixedUpdate(). Pełna postać proponowanego skryptu podana jest poniżej.
Wskazówka:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RuchAuta : MonoBehaviour
{
public Transform[] Kola;
public WheelCollider[] KolaKolider;
private float maxKatSkretu = 40.0f;
[Header("Opcje")]
[Range(100.0f, 500.0f)]
[SerializeField] float maxMomentObrotowy = 100;
void ObracajKola()
{
for (int i = 0; i < Kola.Length; i++)
{
var pos = Vector3.zero;
var rot = Quaternion.identity;
KolaKolider[i].GetWorldPose(out pos, out rot);
Kola[i].position = pos;
Kola[i].rotation = rot * Quaternion.Euler(0, -90, 90);
}
}
// Start is called before the first frame update
void Start()
{
}
void Jazda()
{
KolaKolider[0].motorTorque = Input.GetAxis("Vertical") * maxMomentObrotowy;
KolaKolider[1].motorTorque = Input.GetAxis("Vertical") * maxMomentObrotowy;
KolaKolider[0].steerAngle = Input.GetAxis("Horizontal") * maxKatSkretu;
KolaKolider[1].steerAngle = Input.GetAxis("Horizontal") * maxKatSkretu;
}
void Hamowanie()
{
if (Input.anyKeyDown)
{
if (Input.GetKeyDown(KeyCode.Space))
{
foreach (var kolo in KolaKolider)
{
kolo.brakeTorque = 1000;
}
}
else
{
foreach (var kolo in KolaKolider)
{
kolo.brakeTorque = 0;
}
}
}
}
// Update is called once per frame
void Update()
{
}
private void FixedUpdate()
{
Jazda();
ObracajKola();
Hamowanie();
}
}
Przechodzimy do hierarchii widoku prefabrykatu tworzonego auta. Dodajemy ciało fizyczne Rigidbody. Ustawiamy masę pojazdu. Podpinamy skrypt. Odpowiednio do tablic dołączamy siatki kół i ich collidery. Zwróć uwagę które koła są na przedniej, a które na tylnej osi.
Prefabrykat samochodu jest gotowy. Osadź go w scenie.
Uruchom scenę i przetestuj zachowanie auta. Możesz zmieniać i dobierać wiele różnych parametrów kół.
Ruch kamery za pojazdem
Wpatrując się w ruch pojazdu można zauważyć drgania. Drgania te przybierają na sile wraz ze wzrostem prędkości. W zależności od przyjętej metody ruchu kamery za pojazdem, drgania te będą przeszkadzać. Podany poniżej skrypt śledzenia ruchu pojazdu zawiera prostą konstrukcję wygładzającą drgania w osi pionowej. Skrypt jest modyfikacją skryptu ruchu kamery przedstawionego w tym temacie zobacz
Utwórz nowy skrypt o nazwie Kamera. Podepnij do głównej kamery sceny i wypełnij poniższym kodem.
Wskazówka:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class Kamera : MonoBehaviour
{
[SerializeField] private Transform obserwowanyObiekt;
private Vector3 odleglosc;
public float spowalniaczWysokosci = 2.0f;
// Start is called before the first frame update
void Start()
{
odleglosc = transform.position
- obserwowanyObiekt.position;
}
private void LateUpdate()
{
float tempWysokosc = obserwowanyObiekt.position.y + odleglosc.y;
float wysokosc = transform.position.y;
//wygladz w pionie ruch kamery wzgledem sledzonego obiektu
wysokosc = Mathf.Lerp(wysokosc, tempWysokosc, spowalniaczWysokosci * Time.deltaTime);
Vector3 poz = obserwowanyObiekt.position + odleglosc;
transform.position = new Vector3(poz.x,
wysokosc,
poz.z);
transform.LookAt(obserwowanyObiekt);
}
}
Do podpiętego skryptu dołącz obiekt samochodu umieszczonego na scenie . Patrz poniższa ilustracja.
Uruchom scenę i rozpocznij jazdę samochodem. Kamera powinna podążać za ruchem auta.