Perspektywa pierwszoosobowa- zbieranie zasobów

Rozwijamy tworzenie kontrolera postaci opartego na komponencie Character Controller. Do kodu z projektu opisanego w tym temacie (zobacz) dojdzie kilka metod pozwalających zbierać przedmioty umieszczone w wirtualnym świecie 3D.

Krótki film przedstawiający omawiany temat (kliknij na obrazku)

zbieranie zasobów Unity

Nowa scena

W Blenderze przygotowujemy nową scenę, która może być dowolna. Ważne, aby zawierała siatkę modelu beczki i dzidy.

nowa scena Unity

Gotową scenę z Blendera wraz z przedmiotami eksportujemy do pliku *fbx, importujemy i osadzamy w scenie w Unity.

Po uruchomieniu sceny możemy zauważyć niepożądany efekt przechodzenia przez obiekty. Co oznacza brak wykrywania kolizji- obiekt nie ma podpiętego collidera.

brak kolizji Unity

W przypadku obiektów, na których nam zależy aby kolizja była dość zgodna z ich siatką najwygodniej jest zastosować Mesch Collider. Ale w przypadku użycia Character Controller do sterowania ruchem gracza, to nie wystarcza jeżeli chcemy zachować fizyczność obiektu kolidującego. Dodatkowo na komponent Charakter Controller postaci nie mogą wpływać obiekty poprzez fizykę. Należy opracować własne skrypty wykrywania kolizji.

Przepychanie obiektu

Przepychanie obiektu zademonstruję na przykładzie beczki, której podczas kolizji z graczem zostanie przekazana siła. Kierunek wektora działającej siły zostanie wyznaczony na podstawie współrzędnych pozycji gracza i beczki w świecie sceny gry 3D.

Do obiektu beczki dodajemy komponent Rigidbody i Mesh Collider. Poniżej ilustracja przedstawia przypisane opcje.

Rigidbody i Mesh Collider Unity

Tworzymy nowy skrypt o nazwie KolizjeZasoby(). Kod skryptu poniżej.

Wskazówka:


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

public class KolizjeZasoby : MonoBehaviour
{
    [SerializeField] float silaWartosc = 0;

    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        Rigidbody rb=hit.collider.attachedRigidbody;
        if (rb != null)
        {
            Vector3 silaKierunek =hit.gameObject.transform.position-
                    transform.position;
            //zeruj pion
            silaKierunek.y = 0;
            //wyznacz jednostkowy wektor kierunku wektora
            silaKierunek.Normalize();
            //przekaz siłe uderzenia
            rb.AddForceAtPosition(silaKierunek * silaWartosc,
                      transform.position,
                      ForceMode.Impulse);
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

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

Skrypt podpinamy do obiektu gracza. Wartość współczynnika siły wstępnie ustawiamy na 1.

ForceMode.Impulse Unity

Uruchamiamy scenę i staramy się tak poruszać postacią aby zderzyć się z beczką. Przy każdej kolizji beczka dozna działania siły. Jeżeli się przewróci to będzie się toczyć.

AddForceAtPosition Unity

Zbieranie obiektów

Zbieranie obiektów (artefaktów broni czy innych zasobów) przedstawię na modelu przejęcia dzidy. Dodatkowo w łatwy sposób bez zmiany już istniejących animacji można uzyskać animację niesienia włóczni. Animacje walki włócznią należy opracować i dołączyć do animatora postaci na zasadach wcześniej omówionych.

Przyjęte rozwiązanie wymaga przygotowania dwóch prefabrykatów dzidy. Pierwszy prefabrykat dzidy będzie dostępny do zabrania przez postać, drugi do noszenia. Oczywiście, nie jest to jedyny pomysł na zbieranie i noszenie broni w grze 3D.

Dla pierwszego prefabrykatu ustawiamy tag: dzida, dodajemy komponent Rigidbody i Capsule Collider. Masę ustawiamy na dwie jednostki, dopasowujemy rozmiar collidera.

Rigidbody i Capsule Collider Unity

Duplikujemy prefabrykat i z duplikatu tworzymy prefabrykat dzidy do noszenia. Dzida do noszenia musi zachować możliwość obrony przy machaniu lub dźganiu. Nie może spadać, kolizje z ciałem gracza powinny być ignorowane. Różne warunki można narzucić na niesione dzidę. Ja zostanę przy dwóch.

Do nowego prefabrykatu dzidy oprócz tagu: dzida przypisujemy warstwę (Layer): Gracz. W komponencie Rigidbody odhaczamy opcję Use Gravity, odznaczamy opcję Is Kinematic. W komponencie Capsule Collider wykluczamy warstwę Gracz (Exclude Layers :Gracz). Patrz ustawienia na poniższej ilustracji.

Is Kinematic Unity

Przechodzimy do skryptu KolizjeZasoby() i wprowadzamy poniższe modyfikacje. Kod zawiera komentarz, więc łatwo jest się zorientować o przeznaczeniu poszczególnych linii kodu.

Wskazówka:


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

public class KolizjeZasoby : MonoBehaviour
{
    [SerializeField] float silaWartosc = 0;
    [SerializeField] GameObject slotBroniPrawy;
    //tablica prefabrykatów broni
    [SerializeField] GameObject[] prafbBroni;

    private void KolizjaDzida(ControllerColliderHit hit)
    {
        GameObject dzida=hit.gameObject;
        //usuń dzidę ze swiata gry
        Destroy(dzida);
        //daj dzide do reki bohatera
        GameObject d = Instantiate(prafbBroni[0],
                                   slotBroniPrawy.transform.position,
                                   slotBroniPrawy.transform.rotation);
        d.transform.SetParent(slotBroniPrawy.transform);
    }

    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        Rigidbody rb=hit.collider.attachedRigidbody;
        if (rb != null)
        {
            if (hit.gameObject.tag == "dzida") 
                    {KolizjaDzida(hit); return; }
            //nie jest to dzida to przesuń ciało
            Vector3 silaKierunek =hit.gameObject.transform.position-
                    transform.position;
            //zeruj pion
            silaKierunek.y = 0;
            //wyznacz jednostkowy wektor kierunku wektora
            silaKierunek.Normalize();
            //przekaz siłe uderzenia
            rb.AddForceAtPosition(silaKierunek * silaWartosc,
                      transform.position,
                      ForceMode.Impulse);
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

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

Uaktualniamy postać gracza. Postać gracza przypisujemy do warstwy Gracz (Layer :Gracz). Do slotu na broń podpinamy ostatnią kość prawej ręki. Do tablicy prefabrykatów podpinamy prefabrykat dzidy przeznaczony do noszenia.

Layer Unity

Zapisujemy scenę i uruchamiamy. Poruszaj się postacią tak, aby trafić na dzidę umieszczoną na scenie.

animacja dzidy Unity

Postać powinna przechwycić dzidę. Przechwycona dzida porusza się zgodnie z animacją dłoni i całą postacią gracza.

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