Efekt ruchu celu po ścieżce

Efekt ruchu celu po ścieżce jest jednym z prostszych zachowań automatów utworzonych w scenie świata gry 3D. Ten krótki film ilustruje treść tego tematu.

Efekt ruchu celu po ścieżce Unity

Ścieżkę tworzą kolejne punkty współrzędnych 3D, które są kolejno odwiedzane przez poruszający się obiekt. Ścieżka w edytorze może być reprezentowana przez same punkty lub punkty połączone linią. Patrz poniższy rysunek.

ruch po ścieżce unity

Linia pomiędzy punktami jest widoczna tylko w edytorze sceny. Ten temat pokaże jak zrobić ruch automatu oraz taką ścieżkę.

Przygotowujemy siatkę poruszającego się obiektu

Przyjmujemy, że ruch obiektu będzie oparty na modelu ruchu pojazdu czterokołowego. W celach poglądowych zrobimy napęd na wszystkie cztery koła ora każde z kół będzie skrętne. Uzyskamy podwójny układ kierowniczy, co przy dość długiej ramie sprawi, że pojazd będzie bardziej zwrotny.

Poniżej proponowana siatka przygotowana w Blenderze

siatka fbx tarczy unity

Siatkę eksportujemy z Blendera do pliku *fbx i importujemy w Unity. W unity tworzymy prefabrykat obiektu pojazdu czterokołowego.

Siatka modelu 3d użyta w przykładzie dostepna jest pod tym linkiem- pobierz

Ogólne zasady budowy pojazdu w Unity

Fizyka pojazdu w Unity wymaga przestrzegania kilku zasad.

W prefabrykacie budowanego pojazdu dodajemy dwa puste obiekty (Create Empty), którym przypisujemy odpowiednio nazwy Kola, ZderzaczeKol. Do głównego nadrzędnego obiektu budowanego pojazdu dodajemy Box Collidera i Rigidbody. Box Collider?a edytujemy tak aby był na ramie i nie wchodził w koła (przygotuj margines odstępu na skręt kół). Masę pojazdu próbnie ustawiamy na 1000 jednostek. Patrz poniższy rysunek

Create Empty unity

Do obiektu Kola (Create Empty) przeciągamy siatki kół.

koła unity

Do obiektu ZderzaczeKol (Create Empty) dodajemy cztery puste obiekty (Create Empty) tak aby ich współrzędne pokrywały się z siatkami kół. Zmieniamy im nazwę na (ja nadałem ZderzaczKolo1, ZderzaczKolo2,?). Do każdego dodajemy Wheele Collider. Patrz poniższa ilustracja.

zderzacz kół unity

Piszemy skrypt dla pojazdu

Utworzymy skrypt o nazwie TarczaStrzelnicza. W skrypcie dodajemy trzy publiczne pola na tablice siatek kół, tablice WheelCollider?ów oraz na obiekt siatki, względem której będzie się poruszać pojazd. Początkowy stan skryptu przedstawia poniższy kod

Wskazówka:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TarczaStrzelnicza : MonoBehaviour
{
    public Transform[] Kola;
    public WheelCollider[] KolaKolider;
    public GameObject sciezka;
    // Start is called before the first frame update
    void Start()
    {
        
    }
   // Update is called once per frame
    void Update()
    {
    }
   
}

Skrypt podpinamy do prefabrykatu tworzonego pojazdu. Tablice siatek kół oraz ich colliderów uzupełniamy odpowiednimi obiektami budowanego modelu 3D. Patrz poniższa ilustracja.

WheelCollider zderzacz kół unity

Na tę chwilę można uruchomić scenę. Pojazd ni powinien zapadać się w grunt. Może się staczać z nierówności. Jeżeli będzie ci podskakiwać, to oznacza ,że jego masa jest zbyt mała w stosunku do ustawionej wartości sił sprężyn amortyzatorów (właściwość dostępna w WheelCollider)

Ścieżka ruchu

Ścieżka ruchu zbudowana jest z obiektów typu Create Empty, jeden jest główny a pozostała są podrzędne. Do głównego obiektu podpięty jest skrypt, którego zadaniem jest rysowanie linii w edytorze ora przechowywanie podrzędnych obiektów, z których pobierane są współrzędne podczas ruchu.

Do tworzonego świata dodaj pusty obiekt Create Empty. Zmień mu nazwę na sciezka. Dodaj kolejny mu podrzędny. Zmień mu nazwę na p. Przypisz ikonę (na rysunku krok 3). Utworzony obiekt kilkukrotnie zduplikuj zmieniając im współrzędne (p 1,p 2,p 3?). Patrz poniższy rysunek.

scieżka ruchu unity

Utwór skrypt o nazwie Sciezka

Wskazówka:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class Sciezka : MonoBehaviour
{

    public Transform[] Punkt;
}
//tylko dla widoczności ścieżki w edytorze
[CustomEditor(typeof(Sciezka))]
public class ExampleEditor : Editor
{
    public void OnSceneGUI()
    {
        var t = target as Sciezka;
        Handles.color = Color.yellow;
        for (int i = 0; i < t.Punkt.Length-1; ++i)
        {
            Handles.DrawLine(t.Punkt[i].position, t.Punkt[i + 1].position, 3);
        }
    }
}

Skrypt podepnij do obiektu sciezka. W odpowiednie pola tablicy dodaj osadzone punkty p, p 1, p 2 itd.

Transform unity

Jeżeli wszystko prawidłowo zostało zrobione, to po wskazaniu myszką głównego obiektu sciezka w edytorze zostaną narysowane linie łączące kolejne punkty. Pierwszy i ostatni punktu w tablicy to te same punkty. Ścieżka zostanie zamknięta, a pojazd będzie się w niej poruszać cyklicznie.

Modyfikacja skryptu TarczaStrzelnicza

Wcześniej utworzony skrypt o nazwie TarczaStrzelnicza modyfikujemy tak aby była możliwa jazda. Dodajemy zmienne na maksymalny kąt skrętu kół, maksymalny moment obrotowy, maksymalną prędkość i indeks aktualnego punktu celu pobranego ze ścieżki. Jazda pojazdu to kolejno wykonywane funkcje ObracajKola(), UaktualnijSkret(), Jazda(), ZmianaPunktu(). Poniżej pełny kod skryptu

Wskazówka:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TarczaStrzelnicza : MonoBehaviour
{
    public Transform[] Kola;
    public WheelCollider[] KolaKolider;
    public GameObject sciezka;
    private float maxKatSkretu = 55.0f;
    [SerializeField] float maxMomentObrotowy = 1000;
    [SerializeField] float maxPredkosc = 25;
    int idAktualny = 0;

    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 UaktualnijSkret()
    {

        Vector3 dir = transform.InverseTransformPoint(
                       new Vector3(
                           sciezka.GetComponent<Sciezka>().Punkt[idAktualny].position.x,
                           transform.position.y,
                           sciezka.GetComponent<Sciezka>().Punkt[idAktualny].position.z
                           )
                       );
        float skret=dir.x/dir.magnitude*maxKatSkretu;
        //przednia para
        KolaKolider[0].steerAngle = skret;
        KolaKolider[2].steerAngle = skret;
        //tylna para
        KolaKolider[1].steerAngle = -skret;
        KolaKolider[3].steerAngle = -skret;
    }
    void Jazda()
    {
        float predkosc = 2 * Mathf.PI * KolaKolider[0].radius * KolaKolider[0].rpm * 60 / 1000;
        if (predkosc < maxPredkosc)
        {
            for (int i = 0; i < KolaKolider.Length; i++)
                KolaKolider[i].motorTorque = maxMomentObrotowy;
        }
        else
        {
            for (int i = 0; i < KolaKolider.Length; i++)
                KolaKolider[i].motorTorque = 0;
        }

    }
    void ZmianaPunktu()
    {
        Vector3 cel = new Vector3(sciezka.GetComponent<Sciezka>().Punkt[idAktualny].position.x,
                        transform.position.y,
                        sciezka.GetComponent<Sciezka>().Punkt[idAktualny].position.z);
        //zbliżaj sie do odległości do 5 metrów
        if (Vector3.Distance(transform.position, cel) < 5.0f)
        {
            if (idAktualny == sciezka.GetComponent<Sciezka>().Punkt.Length - 1)
                idAktualny = 0;
            else
                idAktualny++;
        }
    }
    // Update is called once per frame
    void Update()
    {
        ObracajKola();
        UaktualnijSkret();
        Jazda();
        ZmianaPunktu();
    }
   
}

Uruchom scenę i sprawdź zachowanie się kół. Może się okazać, że siatki kół będą się źle obracać

motorTorque unity

Przyczyną tego jest inna orientacja osi siatek kół. Poprawkę zrobisz taką linijką kodu w funkcji ObracajKola()

Wskazówka:


Kola[i].rotation = rot*Quaternion.Euler(0,-90,90);

Gdzie współrzędne dla kwaternionu dobierz z danych rotacji siatki koła

Quaternion Euler unity

W prawidłowo działającym skrypcie skręcają się wszystkie cztery koła

skręcanie kół unity

Dokładność osiągnięcia celu jest określana z bieżącej pozycji poruszającego się obiektu i bieżącego punktu celu. Osiągniecie celu mierzone jest z dokładnością pięciu jednostek

Wskazówka:


if (Vector3.Distance(transform.position, cel) < 5.0f)

Przyjęta dokładność wynika z wielkości ramy poruszającego się obiektu. Zauważ, że przy obliczeniach wektorowych nie jest brana współrzędna y kolejnych punktów scieżki. Związane jest to z różną wysokością terenu.

Układ okresowy- kod qr
Układ okresowy

Układ okresowy pierwiastków- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Alkomat- wirtualny test kod qr
Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Taklarz- olinowanie stałe kod qr
Olinowanie stałe- kalkulator średnic

Olinowanie stałe- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
przepis na gogfry

Przepis na gofry

zobacz
przepis na bitą śmietanę

Przepis na bitą śmietanę

zobacz