Unity3d FPS Tutorial, czyli tworzymy własną grę FPS od podstaw z wykorzystaniem silnika Unity3d.

Temat: Druga broń

Spis treści

Jeżeli nie używałeś do tej pory Unity3d:

#0 – Podstawy Podstaw

FPS Tutorial:

#1 – Tworzenie nowego projektu i narzędzie terenu

#2 – Sterowanie postacią

#3 – Życie, pancerz i wytrzymałość postaci

#4 – Regeneracja życia i energii. Efekty trafienia

#5 – Kamera z bronią i strzelanie

#6 – Przeładowanie i amunicja

#7 – Zbieranie przedmiotów

#8 – Druga broń

#9 – Rzut granatem i seria z karabinu

#10 – Celowanie i dziury po kulach

#11 – Przeciwnik z prostym AI, sztuczna inteligencja

#12 – Animacja postaci przeciwnika. Animator

#13 – Menu główne gry. GUI

#14 – Ostatnie szlify i budujemy projekt

Teoria

Co to za strzelanka z jedną bronią? Dlatego w dzisiejszym odcinku, postaramy się o podniesienie nowej broni. Ale, żeby wypróbować coś nowego, broń będziemy podnosić na kliknięcie przycisku. Dodatkowo, musimy zadbać o to, aby dało się bronie zmieniać.

Co będzie nam potrzebne? Jakiś modny model karabinu i dźwięku wystrzału do niego. Ja pobrałem fikuśne MP5, które wam tutaj udostępniam:

Tutorial#8_Zasoby

Podnoszenie broni

Z racji, że broń chcemy zbierać z ziemi, pierwszy krok jest bardzo prosty. Umieść model broni, gdzieś na mapie. Później dodajemy mu Collider, najlepiej w kształcie sfery. [Component -> Physics -> Sphere Collider] i ustawiamy go na IsTrigger. Rozmiar Collidera powinien być na tyle duży, żeby cały obiekt broni się w nim zawierał. Dodatkowo może być trochę większy:

Ustawienia Collidera MP5
Ustawienia Collidera MP5

Teraz czas dołożyć skrypt umożliwiający podnoszenie broni. Dlatego tworzymy sobie prosty skrypcik, który ja nazwałem “GroundWeapon.cs” Oczywiście skrypt przypisujemy do modelu broni i uruchamiamy MonoDevelop, żeby coś tam naskrobać. Skrypt jest tak prosty, że wrzucam w całości:

using UnityEngine;
using System.Collections;

public class GroundWeapon : MonoBehaviour {

	public int weaponNumber;

	private bool isPlayer;

	void OnTriggerStay(Collider other)
	{
		if(other.tag.Equals("Player")) {
			isPlayer = true;
			if(Input.GetKeyDown(KeyCode.E)) {
				other.SendMessage("addGun", weaponNumber);
				Destroy(gameObject);
			}
		}
	}

	void OnTriggerExit(Collider other) {
		if(other.tag.Equals("Player")) {
			isPlayer = false;
		}
	}

	void OnGUI(){
		if(isPlayer) {
			GUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 10, 100, 20), "Press E to grab");
		}
	}
}

O co tu chodzi? Po pierwsze, przygotowujemy sobie zmienną publiczną typu int, z numerem broni, oraz prywatną isPlayer typu bool. Zmienna publiczna, żebyśmy mogli w łatwy sposób z poziomu Unity decydować jakim rodzajem broni jest dany obiekt. Dzięki temu, obiekt który leży na ziemi, nie musi być fizycznie bronią, może to być cokolwiek. Zadaniem tego obiektu jest po prostu przekazanie do gracza informacji, z jakiej nowej broni może korzystać.

Zmienną isPlayer, wykorzystamy, żeby wiedzieć, czy wyświetlić graczowi podpowiedź czy nie.

Najpierw funkcja OnTriggerStay. Sprawdzamy czy tag obiektu, który wszedł w collider to “Player”. Nie będę tego omawiał, bo wykorzystaliśmy to już nie raz. Jeśli mamy do czynienia z graczem, ustawiamy zmienną isPlayer na true. Wewnętrzny if, sprawdza czy nacisnęliśmy “E”. Jeżeli tak, wykorzystujemy funkcję SendMessage, aby wykonać akcję w obiekcie gracza, jako parametr przesyłamy naszą zmienną publiczną. Sam obiekt broni niszczymy, bo nie jest już potrzebny.

Tutaj nasuwa się pytanie: Czemu OnTriggerStay, a nie OnTriggerEnter? Otóż, gdy wybierzemy Enter, nie będziemy mogli nacisnąć E w dowolnym momencie.

Druga funkcja to OnTriggerExit. Jeżeli gracz opuści obszar broni , ustawiamy zmienną isPlayer na false, żeby schować podpowiedź. Sama podpowiedź jest wyświetlana w funkcji OnGUI. Jeżeli nasza zmienna jest ustawiona na true, wykorzystujemy funkcję GUI.Label, aby wyświetlić tekst. Standardowo dla funkcji GUI, pierwszy parametr to zmienna typu Rect, któa zawiera pozycję lewego górnego narożnika prostokąta, oraz jego wymiary. Drugi parametr to sam tekst, który wyświetlimy. Dla wymiarów stosujemy prostą sztuczkę, która wyświetli tekst na środku. Tzn. szerokość/wysokość ekranu dzielimy przez dwa i odejmujemy połowę szerokości/wysokości przewidzianej na okno z tekstem.

Tyle. Gra jednak się nie uruchomi, do póki nie stworzymy funkcji addGun. Dlatego zaczynamy od utworzenia sobie skryptu GunsInventory.cs, który będzie odpowiadał za zarządzanie bronią. Dodajemy go do First Person Controllera. Jego początkowa składnia będzie również prosta:

using UnityEngine;
using System.Collections;

public class GunsInventory : MonoBehaviour {

	private bool[] guns = new bool[] {false, true, false, false, false, false, false, false, false, false};

	
	public void addGun(int number)
	{
		guns[number] = true;
		maxGuns++;
	}
}

Mamy prostą boolowską tablicę, gdzie kolejne parametry odpowiadają kolejnym cyferkom na klawiaturze (Zero jest na samym początku!). Wartość true oznacza, że daną bronią dysponujemy, a false, że nie.

Poniżej mamy naszą funkcję addGun. Jako parametr przyjmuje numer typu int, aby było to zgodne z poprzednią funkcją SendMessage. Sam skrypt, to podmiana na true wartości w tablicy, dla numeru równego podanemu. Efekt? Gdy nasza leżąca broń wysyła dwójkę, wykonuje się guns[2] = true, czyli broń dostępna pod cyfrą dwa, staje się dostępna. Dodatkowo zwiększamy liczbę posiadanych broni o 1. Dzięki czemu napisana później funkcja chowająca broń, będzie widziała iloma sztukami broni dysponujemy.

Ale póki co tylko teoretycznie. Nadajmy temu życie!

Wybór broni

Pierwszy ruch, to umieszczenie karabiunu przy postaci, jak miało to miejsce w przypadku pistoletu. Jeśli nie pamiętasz jak to zrobić, wróć do rozdziału #5 – Kamera z bronią i strzelanie.

W skrócie przypomnę najważniejsze kroki:

  • Ustaw broń tak, by była ułożona podobnie do pistoletu
  • Ustaw Layer broni na Guns
  • Broń ma być childem obiektu MainCamera

Do tego celu możesz skopiować leżący na ziemi egzemplarz broni i usunąć mu wszelakie komponenty. Można również skopiować emiter cząstek (Sparks) z pistoletu do modelu broni. Na koniec przypisujemy karabinowi skrypt Shooting.cs i uzupełniamy zmienne. Jak widać, dzięki temu, że sprytnie napisaliśmy kod Shooting.cs zmiana rozmiaru magazynka, czasu przeładowania, celownika czy dźwięku wystrzału, jest bardzo proste.

Należy też pamiętać o tym, żeby w komponencie Audio Source odznaczyć parametr “Play On Awake”. Jeżeli tego nie zrobimy, po wyciągnięciu broni, automatycznie odtworzy się dźwięk wystrzału.

Ustawianie MP5
Ustawianie MP5

[stextbox id=”info” defcaption=”true”]Kod mógłby wyglądać jeszcze lepiej i sprytniej, gdybyśmy użyli klas abstrakcyjnych. Możliwe, że do tego wrócimy, jak starczy czasu.[/stextbox]
Jeżeli teraz włączysz grę, zobaczysz, że dźwięki obu broni uruchomią się na raz i wszystko się nałoży. Dlatego wyłączymy póki co MP5, odznaczając checkbox u samej góry panelu Inspector, ten tuż obok nazwy obiektu.

Jak wyłączyć MP5
Jak wyłączyć MP5

Wracamy do skryptu GunsInventory. Na początek dopiszemy parę zmiennych:

public GameObject[] gunsList = new GameObject[10];

private bool[] guns = new bool[] {false, true, false, false, false, false, false, false, false, false};
private KeyCode[] keys = new KeyCode[] {KeyCode.Alpha0, KeyCode.Alpha1, KeyCode.Alpha2, KeyCode.Alpha3, KeyCode.Alpha4, KeyCode.Alpha5, KeyCode.Alpha6, KeyCode.Alpha7, KeyCode.Alpha8, KeyCode.Alpha9};
private int maxGuns = 1;

Publiczna zmienna, to lista wszystkich broni jakimi dysponuje gracz. MaxGuns to liczba obecnie posiadanych broni. Dodatkowo stworzyliśmy sobie listę wszystkich przycisków alfanumerycznych. Dzięki temu, nasz kod podmiany broni, będzie prostszy i bardziej przejrzysty. Teraz możesz przeskoczyć do Unity, rozwinąć listę borni i dopisać pistolet do numerka 1 oraz MP5 do numerka 2.

Uzupełnienie tabeli z bronią
Uzupełnienie tabeli z bronią

Czas na istotę podmiany broni:

void Update()
{
	for(int i = 0 ; i < keys.Length ; i++) {
		if(Input.GetKeyDown(keys[i]) && guns[i]) {
			hideGuns();
			gunsList[i].SetActive(true);
		}
	}

}

Jeżeli gracz naciśnie odpowiedni numerek (1-9), oraz dysponuje daną bronią (w tablicy guns ustawiona jest na true), to chowamy wszystkie bronie, a broń przypisaną do danego numeru ustawiamy na aktywną.

Zostaje dopisać funkcję hideGuns(), a wygląda ona tak:

private void hideGuns()
{
	for(int i = 1 ; i < maxGuns + 1 ; i++) {
		gunsList[i].SetActive(false);
	}
}

Przelatujemy wszystkie nasze bronie (posługując się zmienną maxGuns), i ustawiamy je na nieaktywne. Zaczynamy liczenie od 1, dlatego też, do maxGuns musimy dodać 1.

Podsumowanie

Po dzisiejszych zmaganiach, możemy już podnieść broń po kliknięciu przycisku, możemy wybierać jedną z dwóch broni i wszystko ładnie działa.

Poprzednia część <- #7 – Zbieranie przedmiotów

Kolejna część -> #9 – Rzut granatem i seria z karabinu

Podoba Ci się? Udostępnij!