Unity3d QuickTip – czyli szybkie porady, rozwiązania częstych problemów i sztuczki w Unity3d!
Dzisiejszy odcinek: Jak zrobić system edycji broni?
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
Poniższy tutorial jest pracą konkursową, a jej autorem jest: Votan.
W tym tutorialu zaprezentuję, jak zrobić system edycji broni palnej. Pokażę, jak dodać do niej latarkę, laser, tłumik oraz chwyt dolny. Co będzie potrzebne?
- Oczywiście modele broni i modyfikacji do niej,
- FPSController,
- Jakaś przykładowa scena,
- Dźwięki do naszego karabinu.
Nie będę podawał do tego linków, bo potrzebne dźwięki i modele można łatwo znaleźć w internecie np. na soundbible.com i tf3dm.com. Zresztą – szukajcie, a znajdziecie;)
Względem wstępnych przygotowań: Karabin podpinamypod naszą kamerę i ustawiamy go w sposób jak najbardziej realistyczny w stosunku do niej. To samo robimy z akcesoriami do broni, z tym że podpinamy je pod karabin i umieszczamy w stosownych miejscach tzn. tłumik u wylotu lufy, latarkę z lewej jej strony, laser z prawej, a chwyt pod nią. Teraz możemy przystąpić do pisania skryptu, w c#, oczywiście ;)
Menu modyfikacji broni
Całość umieścimy w jednym skrypcie, ja nazwałem go Weapon.cs. Dodajemy go do modelu naszej broni. Najpierw trochę zmiennych:
public int Accuracy = 50; public int Damage = 50; public GameObject Silencer; public GameObject Vertgrip; public GameObject Flashlight; public GameObject Laserpointer; private bool showModificationsMenu = false; private bool getSilencer = false; private bool getVertgrip = false; private bool getFlashlight = false; private bool getLaserpointer = false;
Co tutaj mamy? Najpierw statystyki naszej broni. Będziemy modyfikować nie tylko jej wygląd, ale również i jej parametry, a mianowicie celność i obrażenia. Dalej są „sloty” na akcesoria – tłumik, chwyt, latarkę i laser, wszystkie publiczne, abyśmy mogli je łatwo uzupełnić z poziomu edytora Unity.
Flagi showModificationsMenu będziemy używać do otwierania i zamykania naszego menu edycji broni. Pozostałe flagi, opatrzone przedrostkiem get posłużą nam do montowania i demontowania poszczególnych akcesoriów.
Teraz pora na utworzenie menu w funkcjji OnGUI().
void OnGUI() { if(showModificationsMenu) { GUI.Label (new Rect(10, 10, 200, 30), "Celność: " + Accuracy + "%"); GUI.Label(new Rect(10, 80, 100, 30), "Obrażenia: " + Damage); if(GUI.Button(new Rect(10, 200, 100, 30), "Tłumik")) { getSilencer = !getSilencer; } if(GUI.Button(new Rect(10, 230, 100, 30), "Chwyt dolny")) { getVertgrip = !getVertgrip; } if(GUI.Button (new Rect(10, 260, 100, 30), "Latarka")) { getFlashlight = !getFlashlight; } if(GUI.Button (new Rect(10, 290, 100, 30), "Laser")) { getLaserpointer = !getLaserpointer; } } }
Jeśli menu jest otwarte najpierw wyświetlamy sobie statystyki naszej broni za pomocą labeli. Potem wyświetlamy przyciski, którymi będziemy montować lub demontować poszczególne akcesoria. Stosujemy tutaj popularną metodę zmiany wartości flag boolowskich; po naciśnięciu przycisku zmieniamy obecną wartość na jej negację tzn. jeśli mamy true robimy false, a jeżeli false – ustawiamy true.
W kwestii funkcji OnGUI() to tyle, pora przejść do funkcji Update().
void Update() { if(Input.GetKeyDown(KeyCode.C)) { showModificationsMenu = !showModificationsMenu; } Silencer.SetActive(getSilencer); Vertgrip.SetActive(getVertgrip); Flashlight.SetActive(getFlashlight); Laserpointer.SetActive(getLaserpointer); }
Na samym początku implementujemy otwieranie i zamykanie menu za pomocą klawisza C. Stosujemy tu tą samą metodę z flagą showModificationsMenu, co w przyciskach w funkcji OnGUI(). Dalej wykorzystujemy publiczną metodę SetActive() klasy gameObject aby montować lub demontować dodatki. Jako parametr podajemy nasze flagi z przedrostkiem get.
Modyfikacja statystyk broni
Teraz czas zająć się dodatkami, aby modyfikowały nie tylko jej wygląd, lecz także jej statystyki.
Najpierw coś prostego. Wracamy do Unity i do naszej latarki dodajemy komponent light. Zmieniamy parametr Type na spoted i modyfikujemy parametry Range, Spot Angle, Color i Intensity według własnych upodobań, możemy dodać też flarę.
Teraz zajmiemy się tłumikiem oraz chwytem. Wracamy do MonoDevelopa i w funkcji Update() dodajemy poniższe linijki:
if(getSilencer) { Damage = 40; if(getVertgrip) Accuracy = 75; else Accuracy = 60; } else if(getSilencer == false) { Accuracy = 50; Damage = 50; } if(getVertgrip) { if(getSilencer) { Accuracy = 75; Damage = 40; } else Accuracy = 65; }
Cóż, może to rozwiązanie nie jest do końca profesjonalne, ale nie miałem innego pomysłu;) Jeśli założyliśmy tłumik to zmniejszamy obrażenia do czterdziestu. Dodatkowo jeśli mamy założony chwyt to zwiększamy celność do 75, w przeciwnym wypadku tylko do 60. Dlaczego? Tłumik i chwyt modyfikują nam ten sam atrybut, dlatego musimy uwzględnić trzy sytuacje: kiedy założyliśmy tylko tłumik, kiedy założyliśmy tylko chwyt lub obie modyfikacje naraz. W kolejnych ifach uzupełniamy całość. Jeśli nie założyliśmy tłumika, nie modyfikujemy parametrów. Jeśli założyliśmy chwyt i tłumik to ustawiamy celność na 75, a obrażenia na pięćdziesiąt. W przeciwnym wypadku ustawiamy celność na 65.
Tłumienie dźwięku przez tłumik
Mamy tłumik, warto aby tłumił dźwięk. Dodajemy w Unity do naszego karabinu komponent AudioSource. W MonoDevelopie dodajemy kilka nowych atrybutów:
public AudioClip normal; public AudioClip silenced; private AudioSource weaponAudio;
Pierwsze dwa będą przechowywać dźwięki wystrzałów broni. Pierwszy to wystrzał „normalny”, drugi przytłumiony. Kolejna zmienna to nasz komponent AudioSource, którą inicjalizujemy w funkcji Start():
void Start() { weaponAudio = GetComponent<AudioSource> (); }
Teraz w funkcji Update() dodajmy możliwość „strzelania” z naszej broni:
if(Input.GetButtonDown("Fire1")) { weaponAudio.Play(); }
Cudów nie ma. Jeśli naciśniemy LPM to odtworzymy dźwięk z naszego komponentu AudioSource. Proste i logiczne.
Dodajmy zmianę dźwięków:
if(getSilencer) { Damage = 40; weaponAudio.clip = silenced; if(getVertgrip) Accuracy = 75; else Accuracy = 60; } else if(getSilencer == false) { Accuracy = 50; Damage = 50; weaponAudio.clip = normal; }
Dodajemy sobie tylko dwie linijki kodu (te zaznaczone). Za ich pomocą podmieniamy clip do odtworzenia w komponencie AudioSource na podany przez nas. Pora na ostatnią modyfikację – laser.
Laser
Najpierw dodajemy sobie w Unity do GameObjectu celownika laserowego komponent LineRenderer. Następnie w MonoDevelopie dodajemy sobie kolejną zmienną prywatną line, typu LineRenderer, którą inicjujemy w funkcji Start():
void Start() { weaponAudio = GetComponent<AudioSource> (); line = Laserpointer.GetComponent<LineRenderer> (); }
Dodajmy sobie kolejnego ifa w funkcji Update():
if(getLaserpointer) { Ray ray = new Ray(Laserpointer.transform.position, Laserpointer.transform.forward); line.SetPosition(0, ray.origin); line.SetPosition(1, ray.GetPoint(100)); }
Tworzymy sobie zmienną typu Ray oraz nadajemy jej pozycję celownika laserowego oraz jako kierunek podajemy przód.
Następnie podajemy pozycję dla dwóch punktów w naszym
laserze. Pozycję początku naszego lasera oraz pozycję jego końca. W tym celu używamy funkcji GetPoint() i w parametrze podamy 100. Wartość tego parametru możemy ustawić wedle woli, gdyż jest to długość naszego lasera. A, i jeszcze w komponencie LineRenderer warto zmienić parametry Start Width i End Width najlepiej na 0.01, aby nasz laser nie był za szeroki;) Można również zmienić jego kolor na dowolny inny.
To jest w zasadzie tyle, możemy wrócić do Unity i przetestować wynik naszej pracy. Pamiętajmy o uzupełnieniu wszystkich publicznych zmiennych skryptu Weapon.cs, aby poprawnie wszystko działało. W tym systemie przydałoby się jeszcze dodać możliwość montażu celowników optycznych bądź kolimatorów. Niestety nie dodałem tego w tym tutorialu, gdyż jeszcze nie rozgryzłem jak zrobić system takiego celowania;)
Mam nadzieję, że mój tutorial jest zrozumiały i nie trzeba podczas jego czytania brać tabletek na ból głowy;)