Unity3d QuickTip – czyli szybkie porady, rozwiązania częstych problemów i sztuczki w Unity3d!

Dzisiejszy odcinek: Jak zrobić zbieranie przedmiotów?

Uwaga! Jest to poradnik typu QuickTip. Zatem skupia się on na osiągnięciu założonego celu. Zatem zakładamy że użytkownik zna na tyle program Unity3d, aby samodzielnie wykonać najprostsze czynności, jak np. dodanie modelu kostki do sceny czy dodanie modelowi jakiegoś komponentu. Jeżeli brakuje Ci tej podstawowej wiedzy, zapraszam do tutoriala:
Unity Tutorial – Podstawy

Teoria

Teoria jest bardzo prosta. W każdej grze, czy to platformowej, czy RPG czy w dowolnym innym gatunku, trafiamy na coś takiego jak zbieranie przedmiotów. Może się to sprowadzać do kolekcjonowania znajdziek w RPG, monet w platformówce, czy np. boostów na trasie wyścigu. Nie omówimy tutaj tworzenia ekwipunku do gry cRPG, bo to bardziej złożona i skomplikowana kwestia.

Wykonanie

Pierwsze co nam potrzeba, to nasza postać i jakiś obiekt do zbierania. Dlatego na scenie ustawiam:

  • First Person Controller z pakietu Character Controller
  • Obiekt Sphere, który sobie pomniejszyłem i dodałem teksturę żółtego koloru by upodobnić ją do monety.

Przygotowanie monety

Najpierw należy monecie dodać Collider (który powinien być domyślnie dodany dla obiektu Sphere) i ustawić mu parametr isTrigger. Następnie możemy go powiększyć, tak aby postać którą sterujemy mogła łatwiej na niego wejść.
[stextbox id=”info” defcaption=”true”]Jest to powszechnie stosowany trik w grach. Obiekty “pozytywne” dla gracza, mają collider znacznie większy od samych siebie. Tak żeby było nam łatwo złapać się drabinki, zebrać amunicję itp. Gdybyśmy musieli 30 razy przebiegać po amunicji, żeby trafić sobie w mały collider mogłoby być irytujące. Natomiast collidery dla rzeczy “negatywnych” są mniejsze. Dlatego w platformówkach typu Bride, faktyczny collider wrogów, jest nieco mniejszy od nich samych, aby dać graczowi ten dodatkowy ułamek sekundy na reakcję.[/stextbox]
Ostatecznie, nasz moneta powinna wyglądać tak:

Wygląd Collidera Monety
Wygląd Collidera Monety

Teraz tworzymy i dodajemy naszej monecie nowy skrypt. Ja stworzyłem skrypt Coin.cs i dodałem go do monety przeciągając skrypt na monetę w panelu hierachy. Nasz skrypt jest bardzo prosty i jeśli wykonywałeś wcześniej Unity3d QuickTip , o wyświetlaniu podpowiedzi, prawdopodobnie domyślasz się jak będzie wyglądał:

using UnityEngine;
using System.Collections;

public class Coin : MonoBehaviour 
{

    void OnTriggerEnter(Collider other) 
    {
        if(other.tag == "Player") {
            other.SendMessage("collectCoin");
            Destroy(gameObject); 
        }
    }
}

Oczywiście OnTriggerEnter wykona się gdy znajdziemy się w zasięgu collidera monety. Następnie sprawdzamy czy obiekt, który wszedł w interakcję to obiekt gracza (o tym później). Other.SendMessage, nakazuje obiektowi, który wszedł w interakcję z monetą wykonać jego funkcję collectCoin. Destroy(gameObject) usuwa ze sceny obiekt. gameObject jest odwołaniem się do samego siebie, więc w tym przypadku, usuniemy samą monetę.

Postać

Z naszą postacią będzie prościej, ponieważ do obiektu gracza stworzymy przypiszemy sobie tylko jeden skrypt. Ja stworzyłem plik CollectCoins.cs i przypisałem go do mojego First Person Controllera.

Nasz skrypt i tym razem wygląda banalnie:

using UnityEngine;
using System.Collections;

public class CollectCoins : MonoBehaviour {

	public static int coins = 0;

	void collectCoin() {
		coins++;
	}
}

Mamy tylko publiczną, statyczną zmienną z liczbą zebranych monet – nie jest to rozwiązanie optymalne, ale dla przykładu wystarczające – na starcie ustawiamy ich liczbę na 0. Dodatkowo mamy funkcję collectCoin, która jest wywoływana przez skrypt monety, a jej zadaniem jest zwiększenie zmiennej trzymającej liczbę monet o 1.

Kolejną rzeczą jest ustawienie jej tagu. Aby ustawić tag, zaznaczamy wybrany obiekt, u samej góry w panelu Inspektor, będziemy mieli widoczny dropdown zatytułowany tag, który powinien wskazywać na untagged. Klikamy na niego i wybieramy z listy “Add Tag” Znajdujące się u samego dołu. Panel inspektor zmieni się ukazując menu, dostępne z poziomu: [Edit -> Project Settings -> Tags & Layers]. Rozszerzamy panel Tags, klikając w niego,  i wpisujemy w pole Element0 wartość Player. Powinno wyglądać to tak:

QuickTip_06_01
Panel Tags & Layers

Teraz wracamy do obiektu gracza, klikając na niego, a następnie rozwijamy znów listę tagów i wybieramy nasz nowo utworzony Player.

Jak to wykorzystać?

W grze platformowej, czasami jest tak, że wymaga się zebrania pewnej liczby monet by otworzyć jakieś drzwi.

Dodajmy sobie do sceny kopię jeszcze 2 naszych monet, oraz dodatkowy cube, który nazwiemy door. Jego collider, jak w przypadku monet, ustawmy na IsTrigger, oraz powiększmy go trochę. U mnie wygląda on następująco:

QuickTip_06_03
Wygląd komponentów transform i collider dla drzwi

Stworzymy i dodamy naszym drzwiom również skrypt. U mnie nazywa się Door.cs.

using UnityEngine;
using System.Collections;

public class Door : MonoBehaviour {

	void OnTriggerEnter(Collider other) 
	{
		if(other.tag == "Player") {
			if(CollectCoins.coins == 3) {
				Destroy(gameObject); 
			}
		}
	}
}

I ten skrypt również jest prosty. Wykrywamy wejście w Collider, sprawdzamy czy obiekt z którym się zderzyliśmy ma tag Player, jeśli tak, sprawdzamy czy zmienna coins  w skrypcie CollectCoins jest równa 3. Jest to możliwe, ponieważ zmienna coins jest zmienną publiczną i statyczną. Jeśli jest równa 3, co oznacza, że gracz zebrał 3 monety, niszczy nasz obiekt drzwi, symulując ich otwarcie.