Perspektywa pierwszoosobowa- schody i skakanie

W tym temacie zajmiemy się chodzeniem po schodach i skakaniem. Temat jest rozwinięciem poprzedniego tematu (zobacz).

Film pokazujący uzyskany efekt (kliknij na obrazku)

chodzenie po schodach i skakanie Unity

Jeszcze nie będziemy używać animacji, ale siatkę postaci proponuję już zrobić tak, aby można ją było wykorzystać do przyszłej animacji. Moją postać przygotowałem w Blenderze i jest tylko pustą siatką bez sytemu kości.

mesh fbx. Unity

Drugim obiektem do testowania wchodzenia po schodach jest konstrukcja przypominająca trampolinę z kilkoma stopniami.

trampolina schody mesh fbx. Unity

Scenę organizujemy z kilku obiektów. Gdzie Bohater to Create Empty z osadzoną siatką z zaimportowanego pliku *.fbx.

scena mesh fbx. Unity

Ruch bohatera

Ruch bohatera sceny jest oparty na komponencie Character Controller, w którym definiujemy dopuszczalną wysokość schodów (Step Offset ustawiam na 0,5 metra), kąt nachylenia wzniesień (Slope Limit ustawiam na 45°). Określam wysokość postaci na 1,5 metra. Promień wewnętrznego collidera na 0,25 metra. Położenie środka dobieramy w trakcie działania sceny.

Character Controller Unity

Skrypt ruchu bohatera jest modyfikacją skryptu z poprzedniego tematu (zobacz).

W edytorze Unity zainicjuj nowy skrypt o nazwie RuchBohatera. Skrypt podepnij do postaci i wypełnij poniższym kodem.

Wskazówka:


using System.Collections;
using System.Collections.Generic;
using Unity.Android.Gradle.Manifest;
using UnityEngine;

public class RuchBohatera : MonoBehaviour
{
    public CharacterController kontroler;
    public Transform kamera;
    private bool fGrunt;
    //przyspieszenie grawitacyjne
    public float g = -9.8f;

    //współczynnik prędkości
    public float v = 5.0f,
                 wysSkoku=2.0f;
    Vector3 wektorPredkosci = Vector3.zero;
    public float wygladzenie = 0.1f;
    float buforBiezacegoWygladzania;


    void Ruch()
    {
        float poziom = Input.GetAxis("Horizontal");
        float pion = Input.GetAxis("Vertical");
        Vector3 kierunek = new Vector3(poziom, 0, pion).normalized;
        //czy ruch, powiedzmy wiecej niż 5 centymetrów
        if (kierunek.magnitude >= 0.05f)
        {
            //obrót postaci
            //zwróc kąt w radianach z płaszczyzny 2D- oś X a Z
            //zamień radiany na stopnie
            float katPatrzenia = Mathf.Atan2(kierunek.x, kierunek.z)
                                 *Mathf.Rad2Deg+
                                 kamera.eulerAngles.y;
            //wygladzaj obrot,
            //predkosc wygladzania wyslij do bufora
            float kat = Mathf.SmoothDampAngle(
                      transform.eulerAngles.y,
                      katPatrzenia,
                      ref wygladzenie,
                      buforBiezacegoWygladzania
                      );
            transform.rotation = Quaternion.Euler(0, kat, 0);
            Vector3 kierunekRuchu = Quaternion.Euler(0, katPatrzenia, 0)
                                    *Vector3.forward;
            kontroler.Move(kierunekRuchu.normalized * v * Time.deltaTime);
        }
    }
    
    // Start is called before the first frame update
    void Start()
    {
        //blokuj kursor na srodku ekranu
        Cursor.lockState = CursorLockMode.Locked;
        //ukryj kursor
        //standardowo klawisz Esc przywróci widok kursora
        Cursor.visible = false;
    }

    // Update is called once per frame
    void Update()
    {
        Ruch();
    }
    
}

Do podpiętego skryptu dołącz kontroler, kamerę. Ustaw przyspieszenie grawitacyjne na -9.8, współczynnik prędkości na 2.5, wysokość skoku na 2, wygładzanie ruchu kamery na 0.1.

parametry skryptu Character Controller Unity

Uruchom scenę i sprawdź działanie. Postać się porusza ale nie spada, kamera zmienia położenie z ruchu myszki. Aby postać spadała musimy dopisać kolejną funkcję.

Spadanie

Komponent Character Controller nie korzysta z fizyki ciała tak jak Rigidbody, ale wykrywa kolizję z innymi obiektami sceny. Aby zasymulować spadanie należy wykorzystać wzory z fizyki ruchu spadku swobodnego.

spadek swobodny wzór na prędkość Unity

W skrypcie musimy wykrywać czy postać jest nad dowolnym podłożem czy w powietrzu.

Dopisujemy funkcję spadku

Wskazówka:


void Spadaj()
{
	wektorPredkosci.y += g * Time.deltaTime;
	if (fGrunt && wektorPredkosci.y < 0)
	{
		//nie spadaj szybciej niż 5m/s
		wektorPredkosci.y = -5f;
	}
	kontroler.Move(wektorPredkosci * Time.deltaTime);
}

I robimy modyfikację w funkcji Update()

Wskazówka:


void Update()
{
	//sprawdzaj czy jestes nad dowolnym podlozem
	fGrunt = kontroler.isGrounded;
	Ruch();
	Spadaj();
}

Uruchom scenę i sprawdź zachowanie postaci. Zauważysz, że postać spada oraz bez żadnej ingerencji w kod potrafi wejść na schody.

spadanie Character Controller Unity

Skakanie

Przy skakaniu musimy określić albo siłę wybicia lub prędkość początkową oraz cały czas mieć na uwadze ograniczenie wysokości skoku. Najłatwiej jest wykorzystać wzory z ruch jednostajnie przyspieszonego, a konkretnie na prędkość końcową w pionowym spadku z podanej wysokości

skakanie Character Controller Unity

Do skryptu dopisujemy funkcję Skok, który odbędzie się po wciśnięciu klawisza spacji.

Wskazówka:


public void Skok()
{
	if (fGrunt && Input.GetAxis("Jump") != 0)
	{
		//v=Pierwiastek(2gh)
		wektorPredkosci.y = Mathf.Sqrt(-2f * g * wysSkoku);
	}
}

Nową funkcję wywołujemy w Update. Patrz poniżej.

Wskazówka:


void Update()
{
	//sprawdzaj czy jestes nad dowolnym podlozem
	fGrunt = kontroler.isGrounded;
	Ruch();
	Skok();
	Spadaj();
}

Uruchom scenę sprawdź działanie skryptu.

skakani ei chodzenie po schodach Character Controller Unity

Pełny kod skryptu przedstawiam poniżej

Wskazówka:


using System.Collections;
using System.Collections.Generic;
using Unity.Android.Gradle.Manifest;
using UnityEngine;

public class RuchBohatera : MonoBehaviour
{
    public CharacterController kontroler;
    public Transform kamera;
    private bool fGrunt;
    //przyspieszenie grawitacyjne
    public float g = -9.8f;

    //współczynnik prędkości
    public float v = 5.0f,
                 wysSkoku=2.0f;
    Vector3 wektorPredkosci = Vector3.zero;
    public float wygladzenie = 0.1f;
    float buforBiezacegoWygladzania;

    public void Skok()
    {
        if (fGrunt && Input.GetAxis("Jump") != 0)
        {
            //v=Pierwiastek(2gh)
            wektorPredkosci.y = Mathf.Sqrt(-2f * g * wysSkoku);
        }
    }

    void Spadaj()
    {
        wektorPredkosci.y += g * Time.deltaTime;
        if (fGrunt && wektorPredkosci.y < 0)
        {
            //nie spadaj szybciej niż 5m/s
            wektorPredkosci.y = -5f;
        }
        kontroler.Move(wektorPredkosci * Time.deltaTime);
    }
    void Ruch()
    {
        float poziom = Input.GetAxis("Horizontal");
        float pion = Input.GetAxis("Vertical");
        Vector3 kierunek = new Vector3(poziom, 0, pion).normalized;
        //czy ruch, powiedzmy wiecej niż 5 centymetrów
        if (kierunek.magnitude >= 0.05f)
        {
            //obrót postaci
            //zwróc kąt w radianach z płaszczyzny 2D- oś X a Z
            //zamień radiany na stopnie
            float katPatrzenia = Mathf.Atan2(kierunek.x, kierunek.z)
                                 *Mathf.Rad2Deg+
                                 kamera.eulerAngles.y;
            //wygladzaj obrot,
            //predkosc wygladzania wyslij do bufora
            float kat = Mathf.SmoothDampAngle(
                      transform.eulerAngles.y,
                      katPatrzenia,
                      ref wygladzenie,
                      buforBiezacegoWygladzania
                      );
            transform.rotation = Quaternion.Euler(0, kat, 0);
            Vector3 kierunekRuchu = Quaternion.Euler(0, katPatrzenia, 0)
                                    *Vector3.forward;
            kontroler.Move(kierunekRuchu.normalized * v * Time.deltaTime);
        }
    }
    
    // Start is called before the first frame update
    void Start()
    {
        //blokuj kursor na srodku ekranu
        Cursor.lockState = CursorLockMode.Locked;
        //ukryj kursor
        //standardowo klawisz Esc przywróci widok kursora
        Cursor.visible = false;
    }

    // Update is called once per frame
    void Update()
    {
        //sprawdzaj czy jestes nad dowolnym podlozem
        fGrunt = kontroler.isGrounded;
        Ruch();
        Skok();
        Spadaj();
    }
    
}
Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
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