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:

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:

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

Dodatkowa Wiedza
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.

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:

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:

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:

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

  • Dawid Lewandowski

    Mam problem kiedy dodaje mi sie bron jest wszystko ok i klikam 2 i mam druga bron ale kiedy klikam 1 bronie się nakładają!
    Pomocy! I mam problem z dźwiękiem nie odtwarza!

    • Jeżeli chodzi o pierwszy problem. Prawdopodobnie coś jest nie tak z funkcją chowania broni.
      – Czy pistolet na pewno jest dodany do listy broni?
      – Czy funkcja HideGuns się wykonuje?

      W przypadku dźwięku, upewnij się czy na pewno dodany jest komponent AudioSource oraz czy odpowiednie klipy są przypisane do zmiennych.

    • Dawid Lewandowski

      Wszystko zrobiłem jeszcze raz i ciągle mam problem z funkcją HideGuns!

    • A gdzie dokładnie masz problemy z dźwiękiem? Który klip się nie odtwarza?

    • Dawid Lewandowski

      Nie odtwarza się strzał z MP5

    • I broń na pewno posiada AudioSource oraz zmienne typu AudioClip posiadają przypisane poprawne, działające pliki dźwięku?

  • matrix 2000

    Mam problem!
    Od początku jak włączam gre mam dwie bronie na sobie. Nie wiem o co chodzi funkcja HideGuns działa(sprawdziłem w konsoli).

    • Domyślnie jedną broń należy ręcznie ukryć. Czyli zaznaczyć ją w okienku Scene i z panelu Inspector odznaczyć checkboxa u samej góry. Broń zniknie i wtedy wszystko już powinno działać. ;)

    • matrix 2000

      Tak. Broń zniknęła, ale jak ją odblokuje(nacisnę e) to jak chcę na nią zmienić (klikając 2)to nic się nie dzieje.?

    • Przy próbie naciśnięcia 2, za pomocą funkcji Debug.Log(), sprawdź czy zmienna zapamiętująca czy dysponujemy daną bronią, zwraca true dla odpowiedniego parametru.
      Możliwe, że skrypt nie zapisuje czy masz broń i przez to jej nie wyświetla.

    • matrix 2000

      Oh! nie sprawdziłem, że w konsoli pisze ,,SendMessage AddGun has no receiver” , ale dalej nie wiem co robić.

    • Czyli, funkcja wywołująca funkcję AddGun nie może jej odnaleźć. Możliwe problemy:
      1) Nie stworzyłeś funkcji AddGun
      2) Odwołujesz się do złego komponentu/obiektu, który nie ma funkcji AddGun
      3) Masz gdzieś literówkę w nazwach funkcji

    • matrix 2000

      1)Jest

      2)Nie wiem. Jeśli chodzi np. o maxGuns itp. to nie.

      3)Chyba nie oto funkcja i jeszcze stworzyłem skrypt i wszystko skopiowałem(wszystkie skrypty, które są tutaj udostępnione) i na chwile podmieniłem (myślałem, że jakiś inny błąd), ale nie pomogło.?

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

    • matrix 2000

      Spróbowałem też zrobić przeciwnika. Jakimś dziwnym trafem jest to samo. To znaczy w tym wypadku nie otrzymał wiadomości TakeHit. Przypadek? Może mam inną wersje(5)

    • Prawdopodobnie odwołujesz się do złego komponentu, bo nie wiem co innego może pójść nie tak. Możesz się do mnie odezwać na priv (FB albo Email) i podesłać swój projekt, to zobaczę co tam może nie grać. ;)

    • matrix 2000

      Masz jakiegoś nie prywatnego emaila, żebym mógł to przesłać, bo nie znalazłem błędu.

    • Oficjalny mail blogowy: marek@mwin.pl :)

    • matrix 2000

      Wysłałem. Mam nadzieje, że doszło :)

    • matrix 2000

      Halo? Mój projekt jest aktualny?

    • Odpisałem w mailu. :)

    • matrix 2000

      Ok. Wielkie dzięki i tak jest postęp, bo nie ma błędu, ale jak zbiorę siekierę i nacisnę 2 to 1 broń znika, ale siekierka się nie pojawia(wiem, że tam jest, bo da się wtedy strzelać). Chciałbym jednak, żeby była widoczna.

    • Ten problem też opisywałem. Masz w zmiennej odpowiadającej za istnienie broni pomieszane wartości i pewnie wykłada się na warunku if(… & guns[i]).

    • matrix 2000

      Czyli co? Zmienić na minusy? (Sprawdziłem i nie działa). Napisałem tak jak jest pokazane powyżej.

    • Jak sprawdzałem u Ciebie kod, to miałeś true dla 3 elementu tablicy (tab[2]), a powinno być dla drugiego (tab[1]). Bo później gdy dodajesz broń, robi się addGun(2), czyli ustawiasz znów na true tab[2], czyli dalej dostępną masz jedną broń.
      W momencie gdzie jest pojawianie broni, zrób sobie Debug.Log(guns[i]); Jak zwróci false, to znaczy, że źle ustawiasz wartość w tablicy i zostaje tylko znaleźć miejsce gdzie tak się dzieje. A może się dziać w 2 miejscach. Przy wywołaniu funkcji addGun, albo w momencie deklaracji samej tablicy guns. Ewentualnie przesyłasz zły parametr z drugiego skryptu.

    • matrix 2000

      Pisze true. Ale siekierki nie widać

    • A masz ją dodaną do tablicy z poziomu Unity? Bo z tego co pamięta, to tego Ci też brakowało.

    • matrix 2000

      Wielkie dzięki nareszcie działa. Mam jeszcze jedno pytanie. Nadal wyskakuje mi błąd ze ,,TakeHIt has no received”. (Chodzi o wroga).

    • Czyli obiekt do którego się odwołujesz nie ma takiej funkcji. Najprawdopodobniej:
      a) Odwołujesz się do złego obiektu
      b) Skrypt dodany jest w złym miejscu
      c) Nie ma takiej funkcji lub gdzieś masz literówkę (np. w wielkości liter)

    • matrix 2000

      Chyba wiem gdzie popełniłem błąd. Mam tylko jedną zmienną ,,TakeHIt” A chyba mają być dwie.

      ,,Aby wszystko śmigało, robimy sobie bliźniaczą funkcję, do funkcji takeHit stworzonej dla gracza”
      ja mam tylko jedną w enemyAI.
      Chodzi mi oto, że nie mogę zabić mojego zombie. Myślałem, że to przez takeHit.
      Jeśli masz jeszcze mój projekt to czy mógłbyś zobaczyć co jest nie tak, bo to chyba złożony problem

    • Problem jest prosty jak koszulka dziecka.
      1) Twoje pociski zadają obrażenia, odwołując się do funkcji „ZmianaHP”.
      2) Zombie atakuje odwołując się do funkcji TakeHit
      3) Gracz posiada funkcję ZmianaHP
      4) Zombie posiada funkcję TakeHit.
      Odwołujesz się odwrotnie.
      Część skryptów masz w JS a część w C#, przez co może to nie do końca chcieć ze sobą działać. Ale próbuj ;)

    • matrix 2000

      Gdzie pokazywałeś funkcje ZmianaHP?

    • Nigdzie. W tutorialu nie ma takiego skryptu, a jest u Ciebie w projekcie.

    • matrix 2000

      Gdzie. I jak to poprawić, żeby chociaż zombie ginął.

    • 1) W kodzie pocisku, który zadaje obrażenia zombie, zmień odwołanie do funkcji ZmianaHP, na odwołanie do TakeHit.
      2) Tam gdzie atakuje zombie, zmień odwołanie z funkcji TakeHit na ZmianaHP, albo zostaw jak jest i dopisz brakującą funkcję TakeHit.

      Z tego co widzę pominąłeś kilka pierwszych części, gdzie pisałem o robieniu życia dla postaci gracza i stąd pewnie wynikają komplikację.

    • matrix 2000

      Zrobiłem tak i nic.

    • A są jakieś błędy?
      Jeżeli nie, to skup się najpierw na jednym. Np. zacznijmy od zadawania przeciwnikowi obrażeń.
      1) Sprawdź czy pocisk ma odpowiednią funkcję SendMassage
      2) Wsadź do niej parę Debug.Logów, żeby sprawdzić, czy tam kod wykonuje się cały.
      3) Wejdź do skryptu przeciwnika i odnajdź funkcję, do której wysyłasz kod. Tam też wstaw parę Debug logów i zobacz, do którego miejsca kod się wykonuje.
      Jak sobie poustawiasz dobrze logi, będziesz widział ile kodu się robi, a gdzie pojawia się problem. Wtedy można szukać rozwiązania.

    • matrix 2000

      Dodałem tą linijkę do skryptu z samym pociskiem.(Jest to jego wystrzał, shoot.cs)

      hit.transform.gameObject.SendMessage(„ZmianaHP”, demage);

      W Enemy AI mam:

      other.SendMessage („takeHit”, attackDemage);
      A w skrypcie strzelania(druga część, chodzi o strzelanie.cs) mam

      hit.transform.gameObject.SendMessage(„ZmianaHP”, demage)
      To wszystkie linijki z SendMassage.

    • Wyjaśnię to dokładnie na strzelaniu do przeciwnika, powinieneś na tej podstawie ogarnąć ataki na graczu.
      1) Za strzelanie do przeciwnika odpowiada u Ciebie niezależny od broni skrypt Shoot.cs znajdujący się w: gracz/First Person Controller/GameObject
      2) Skrypt ten wystrzeliwuje pocisk (bullet), który posiada skrypt: pocisk.js
      3) Tam jeśli trafiony obiekt ma komponent Zdrowie lub ZdrowiePrzeciwnika, to wywołujesz: col.gameObject.SendMessage(„ZmianaHP”, -10); Czyli szukasz funkcji ZmianaHP
      4) No to idziemy do przeciwnika. Jego kontroluje skrypt EnemyAI.
      5) Wewnątrz skryptu mamy funkcję takeHit z mojego tutoriala.

      Więc gdzie są problemy?
      W skrypcie pocisk.js
      1) Wywołujesz SendMessage jeśli obiekt trafiony ma skrypt Zdrowie lub ZdrowiePrzeciwnika. Twój przeciwnik ma tylko skrypt EnemyAI, więc metoda SendMessage, nie jest nawet wykonana.
      2) Jeśli byłaby wykonana, szukałaby skryptu ZmianaHP, którego również nie ma, i dostałbyś błąd „function has no receiver”.

      Co zrobić?
      1) Zmienić ifa, tak żeby oczekiwał poprawnego komponentu i/lub obiektu. Jeżeli nie chcesz za dużo zmieniać, to skrypt powinien w ife oczekiwać komponentu EnemyAI
      2) Zmienić funkcję w SendMessage ze ZmianaHP na takeHit.
      Obie zmiany, należy wykonać w skyrpcie pocisk.js

      ——–
      Atakowanie gracza.
      Masz trochę błędy kod z tutoriala, bo zamiast else (linia 37 skryptu EnemyAI), powinien być eleseif(distance < attackDistance) – przeciwnik atakuje, jeśli jest dość blisko gracza.
      Ale do sedna. Linia 39: other.SendMessage ("takeHit", attackDemage); Czyli w obiekcie gracza, szukamy funkcji takeHit.
      No to sprawdzamy skrypty gracza:
      Info, Zdrowie i Strzelanie.
      1) info.js – nie ma nic o zdrowiu, omijam
      2) strzelanie.cs to kolejny skrypt służący strzelaniu. (mamy teraz 2)
      3) zdrowie.js – bingo!
      Tylko, że tutaj mamy funkcję ZmianaHP.

      Co jest źle?
      1) Funkcja w EnemyAI, odwołuje się do nieistniejącej funkcji.

      Co zrobić?
      1) Zmienić funkcję w zdrowie.js ze ZmianaHP na takeHit.

      ——–
      Drugi skrypt strzelania
      On jest z tutoriala, więc teoretycznie powinien działać. Ale…
      1) Jest w złym miejscu – powinien być przypisany do broni
      2) Ma złe rzucanie promienia – rzucasz promień z obiektu w którym jesteś. Skrypt przypisałeś do zewnętrznej powłoki gracza, niezależnej od tego gdzie patrzysz. Czyli możesz rzucać promień w przeciwnym kierunku. – Rzucanie promienia jest poprawione w tutorialu i promień jest rzucany z kamery na wprost. Wtedy zawsze promień leci w kierunku gdzie patrzy gracz.
      3) Promień i tak by nie zaliczył trafienia, bo wymaga tagu "Przeciwnik", którego twój zombie nie ma.

    • matrix 2000

      Zrobiłem tak jak napisałeś. Nie mam jednak skryptu zdrowie.js. Może go usunąłem. Na razie chciałbym tylko, żeby zombie zginął. Zmieniłem też model M4A1 i nie ma w nim żadnych skryptów, nie pamiętam czy trzeba było tam jakieś włożyć.

      Pytam jeszcze czy tak ma wyglądać pocisk.cs:

      function OnCollisionEnter(col: Collision)
      {
      if(col.gameObject.GetComponent(„EnemyAI”))
      {
      col.gameObject.SendMessage(„takeHit”, -10);
      }
      }

    • Tak, takie coś powinno załatwić sprawę, jeśli reszta się zgadza.
      W moim tutorialu model broni posiadal skrypt shooting.cs

    • matrix 2000

      Tak. Wyszytko tak jak pokazales. Nie wiem dlaczego nie działa. Może dlatego, że nie mam skryptu zdrowie.js. Jak ma wyglądać i jeśli jest nie potrzebny to powiedz.

    • Skrypt miałeś dołączony w wersji którą mi wysyłałeś. Sam nie jest potrzebny, w jeden z części tutoriala tworzymy skrypt Stats.cs, który zajmuje się zdrowiem gracza. Mam wrażenie, że części tutoriala robiłeś wybiórczo zamiast po kolei i z tego zrodziła się masa problemów.

    • matrix 2000

      Ok. Narazie chciałem, żeby zombie zginął. Do tego nie jest chyba potrzebne zdrowie gracza. Dziwi mnie to, że nie wyskakują błędy i nie działa. Chyba wszystko jest teoretycznie dobrze.

    • Wstaw Debug.Log wewnątrz ifa i w funkcji, która powinna się wykonać. Zobacz, które logi się pojawią i będziesz wiedzieć, co się nie wykonuje. Wiem, że powtarzam to w kółko, ale tylko tak rozwiążesz problem.

    • matrix 2000

      Wyniki moich obserwacji:

      Skrypt Pocisk.ls działa prawidłowo.

      W części skryptu strzelanie.cs debug.log nie działa:

      if (Input.GetButtonDown („Fire1”) && obecnaamunicja > 0)
      {

      if(obecnaamunicja >0)
      {
      obecnaamunicja–;
      iskra.GetComponent().Emit();
      AudioSource.PlayClipAtPoint(dzwiekwystrzalu, transform.position);

      if(Physics.Raycast(transform.position, fwd, out hit))
      {
      if(hit.transform.tag == „Przeciwnik” && hit.distance < zasiegstrzalu)
      {
      hit.transform.gameObject.SendMessage("ZmianaHP", demage);
      GameObject go;
      go = Instantiate(bloodParticles, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal)) as GameObject;
      Destroy(go, 0.3f);
      Debug.Log("Trafiony przeciwnik");
      }
      else if(hit.distance < zasiegstrzalu)
      {
      GameObject dziura;
      dziura = Instantiate(dziurapokuli, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal)) as GameObject;
      Destroy(dziura,7);
      Debug.Log("Trafiony cosiek");
      }
      }

      }
      W skrypcie shoot.cs nic nie ma z sendmessage, ale jest w porządku.

    • Na 99% masz zły Raycast. Jest on poprawiony w późniejszym fragmencie tutoriala. Promień powinien wychodzić z kamery głównej.

    • matrix 2000

      Chyba wiem gdzie zrobiłem błąd. Poprawiłem Raycast i dodałem skrypt zdrowie.js. Przecież w ogóle nie miałem funckji ZmianaHP. Dodałem skrytp i trochę zmieniłem pocisk.js i wszystko działa. Dzięki za pomoc. Mam jeszcze pytanie do broni. (Pewie widziałeś) Z mojej broni cały czas lecą iskry. Można je jakoś zatrzymać ? Unity 5 nie rozumie tej linikji: Iskra.particleEmitter.emit = false;. Automatycznie przerabia na: Iskra.GetComponent.Emit () = false;, ale i tak są błędy i nie działa.

    • Unity 5 zmienia sposób dostawania się do komponentów. Jego kod jest teraz poprawnym. Musisz rozwiązać jego błędy.

    • matrix 2000

      Czyli co zrobić próbowałem chyba wszystkiego. Myślałem, że można to zrobić poprzez SetActive lub coś w tym stylu.

    • Podaj bledy jakie Ci wyskakuja.

    • matrix 2000

      Pisze tak:
      ‚ParticleEmitter’ attached to the ‚iskra’ game object, but a script is trying to access it.

    • Polecam lekturę tego wpisu:
      http://mwin.pl/unity3d-quicktip-24-debugowanie-skryptow/

      Błąd wynika z tego, że do swojego obiektu iskra nie masz dodanego ParticleEmittera, dlatego nie masz władzy nad emisją.

  • Pingback: Unity3d FPS Tutorial #2 - Sterowanie postacią | mWin GameDev()

  • Pingback: Unity3d FPS Tutorial #4 - Regeneracja życia i energii. Efekty trafienia | mWin GameDev()

  • patrix972

    Witam , mam problem polegający na tym , że nie wiem jak mam ustawić opcje Transform tak aby broń odpowiednio „leżała” w mojej ręce. Kiedy ustawiam parametry podane w poradniku ( tym i #5 ) broń nie wyświetla się wcale.

  • Pingback: Unity3d FPS Tutorial #6 - Przeładowanie broni i amunicja | mWin GameDev()

  • Justyna Brylok

    Hej hej, to znowu ja :) mam hmmm mało realistyczne zjawisko. Trawa. Jeśli strzele maksymalnie blisko siebie, dziura pokazuje mi sie na „szczycie” trawy. Też, jeśli zabije zombiaka wśród trawy, „kładzie” się na niej. Czy jestem w stanie to jakoś zmienić? Czy porostu dodatek wysokiej trawy nie jest na tyle zaawansowany, a ja czepiam się szczegółów? :D

    • Ja rozwiązałbym to tak, że pozwoliłbym trawie przenikać przez truchło, ale obniżyłbym trawę na tyle, żeby nie wystawała ponad niego, albo podniósł na tyle w górę, żeby nie wyglądało to źle (np. w polu zboża, nikt nie zwróci uwagi na to, że trawa przechodzi przez model).
      Jeżeli kolizja istnieje, to model położy się na trawie, jeśli nie będzie kolizji, to trawa będzie przenikać. Żeby zrobić to mega pro, trzeba by wyliczać ile trawy wystaje ponad model i skracać ją w tym miejscu. Tyle, że potrzebne do tego obliczenia, nie są warte efektu wizualnego.
      Możliwe, że jest jakaś prosta metoda rozwiązania tego, ale szczerze, nie znam jej.

    • Justyna Brylok

      ok, dzieki :)

  • Pablo111

    Witam, mam problem z ogólnie pojawianiem się broni i znikaniem jej.
    Po zebraniu przedmiotu tablica zwraca wartość TRUE, przed zebraniem nie pokazuje nic.
    Po wciśnięciu ‚2’ po podniesieniu miecza nic się nie dzieje, 1sza broń nie znika a druga nie pojawia, tablica zmienia wartości bo sprawdziłem „Debug logiem”

    Do przedmiotu na ziemi przypisałem skrypt „GroundWeapon”
    Do Gracza „GunsInv”

    Elementem 2gim w Unity [ustawienia skryptu pole inspektor] jest Rapier który leży na ziemi.
    El. 1 jest miecz który jest aktywny od startu

    Po podniesieniu miecz pojawia się w EQ.

    Czasami wyskakuje błąd

    Object reference not set to an instance of an object
    I skrypty z linijkami w których „błąd wyskakuje”

    • Możesz podać dokładną treść błędu?

    • Pablo111

      Błąd zniknął, ale wciąż po klikaniu 1/2/3 etc. nic się nie dzieje, zwracana jest mi wartość TRUE z każdej broni którą mam, w opcji gdy broni nie mam [mam np 1 i klikam nr 2] to nie pokazuje się nic [nawet False]

      Dodatkowo mam pytanie jak ustawić przedmioty z EQ tak aby po kliknięciu w okienko np z butelką owa butelka pojawiła się w ręce, bez opcji klawiszy

    • 1) Aby odpowiedzieć na pierwsze pytanie, będę potrzebował screeny panelu Inspector – dokładniej komponentu skryptów – dla obiektów zawierających skrypty, oraz panel Hierarchy z układem broni.

      2) Potrzebujesz modelu butelki z bronią, ustawionego w odpowiednim miejscu, który będzie ukryty. Po wybraniu butelki z ekwipunku, musisz ukryć wszystkie inne obiekty i wyświetlić ten z butelką. Raczej nie jest to sprawa jednej linii kodu, więc nie podam dokładnego rozwiązania od tak.

    • Pablo111

      Oto zdjęcia z widokiem na:
      1. Broń w hierarchy, podłączone są do Kamery Broni
      2. Skrypt i przedmiot leżący na ziemi

      Co do drugiego pkt.
      Czyli mając 200 przedmiotów muszę umieścić je wszystkie przy modelu, ukryć i aktywować tylko jeden spośród 200.
      Nie zatnie to gry, gdy będzie ona musiała przejrzeć 200 elementów aby aktywować jeden.

    • A skrypt inwentarza podpięty do gracza jak wygląda?

      Mój skrypt sprawdza się w sytuacji przewidzianej dla niego, czyli max 10 broni (0-9). Przy chęci wstawienia 200 przedmiotów do ręki, będzie trzeba pamiętać index wybranej rzeczy, żeby schować go bezpośrednio (zamiast przeglądać tablicę), a potem wyświetlić wybrany.

    • Pablo111

      Ogólnie skrypt który mam działa następująco:
      Po zmianie broni znika mi MODEL miecza w w grze z miejsca „Project” gdzie są pliki.
      Po włączeniu 2 broni model się pojawia, pozostaje sam dodatek Collidera czy coś takiego [szary model]
      Tylko to się pojawia i znika podczas zmiany broni

    • Czy cutter01 w skrypcie Inventory został przeniesiony z panelu Project czy z panelu Hierarchy?

    • Pablo111

      Z Panelu project.

      Teraz jak myślę że to jest różnica to wiem dlaczego znikał mi model broni w katalogu Project a nie w grze.

    • Panel project reprezentuje w sumie Twój dysk. Panel Hierarchy to co masz w grze. Więc jeśli chcesz działać na obiektach w grze, trzeba korzystać z panelu Hierarchy.

  • franek dolas

    witam, udało mi się rozwiązać kwestie podnoszenia amunicji, problem polegał na złym przypisaniu child’a do obiektu, co w sumie jest dziwne bo próbowałem różne warianty włącznie ze ścieżką, co do efektu sparks o którym pisałem wcześniej że wygląda u mnie jak różowa pikseloza nagle moje sparksy wyglądają faktycznie jak iskry po wystrzale a nic właściwie nie zrobiłem w tym kierunku, skąd nagle taka samoistna zmiana efektu? ale to tak przy okazji mój problem właściwie to:

    1. stworzyłem sobie Cube’a, ustawiłem mu tag Enemy ale kiedy do niego strzelam nie zależnie od Range’a, konsola nie wyświetla żadnego komunikatu więc nie wiem właściwie czy w coś w ogóle trafiam

    2. odnośnie 8 odcinka – Druga Broń – ustawiłem sobie drugi pistolet na mapie, kiedy podchodzę pojawia się info o naciśnięciu E żeby podnieść, wciskam = podnoszę, obiekt znika z panelu Hierarchy, wciskam 2 i lipa, nie ma drugiej broni, po wciśnięciu 1 też nic się nie dzieje, nie ma pojawia się żaden błąd/warning.

    jako drugą broń do podniesienia ustawiłęm jescze raz ten sam pistolet z tego względu że kiedy dodawałem na mapę MP5 to pojawiała się dziwna sytuacja tzn że model obiektu był dużo dalej niż jego hmmm jak to nazwać ten czerwono-zielono-niebieski Cube za który łapiesz i przesuwasz obiekty przez co Collider był dużo dalej niż faktycznie sam obiekt/model i po odpaleniu gry wyglądało to tak że wchodzę w MP5 i nic idę 2 metry dalej i pojawia mi się info Press E to grab, da się to jakoś scalić bo jest to trochę uciążliwe, próbowałem ręcznie zmieniać parametry w panelu Transform i w pozycji Collidera ale nie wiele to dało, dorzucam zdjęcie może będzie pomocne…

    • 1) Skorzystaj z funkcji DrawRay
      http://docs.unity3d.com/ScriptReference/Debug.DrawRay.html
      Aby zobaczyć jak wygląda faktycznie Twoja linia strzału. Może masz podany zły wektor strzału, albo punkt wystrzału.

      2) W obiekcie MP5, masz kilka zagnieżdżonych obiektów. Kilka pierwszych to zwykłe wrapery, które nic nie wnoszą, a sprawiają, że pivot jest w innym miejscu, przez co masz collider w innym miejscu. Musisz sobie zobaczyć, który child będzie miał dobrze ustawiony collider i ten obiekt trzeba wyciągnąć.

  • franek dolas

    witam dopisałem do skryptu Shooting.cs funkcje :

    Debug.DrawRay(transform.position, fwd, Color.red, 10.0f); i tak wygląda mój Raycast w oknie Scene i w oknie Game po włączeniu opcji Gizmos, tylko nie wiem co z tym dalej zrobić = jak to poprawić.

    Co do kwestii drugiej broni to przejrzałem wszystko co zostało zawarte w modelu MP5 i znalazłem child’a z „dopasowanym” piwotem i colliderem i zrobiłem tak: odpowiedniego dla mnie child’a po prostu zaznaczyłem, skopiowałem i przeciągnąłem z resztą zawartości jako child MainCamery, zbędną resztę modelu z tymi lipnymi wraperami usunąłem z Hierarchy, coś takiego miałeś na myśli pisząc „i ten obiekt trzeba wyciągnąć” ? Bo dalej nie zmienia mi broni na MP5. wszystko ładnie działa ale jednak coś nie tak, tylko nie mogę wyczaić co, odpalam grę, MP5 leży, podchodze pojawia się info „wciśnij E….” wciskam=podnoszę=MP5 znika z mapy i okna Hierarchy wciskam 2 i nie zmienia mi na mojego childa MP5 z MainCamery. zrobiłem taki teścik odznaczyłem checkboxa w oknie Gun i zaznaczyłem w oknie MP5 i po odpaleniu gry od razu startuje mi z MP5 „w ręce”, i wszystko ok, no po za faktem że wtedy nie mogę zebrać ammo z gleby ale zakłądam, że pewnie trzeba przypisać komponent do MP5 w AmmoPack.cs ale to na marginesie. wracając do drugiej broni nie pojawia się żaden błąd ani warning, a w ogole to w zmiennej Weapon Number w skrypcie GroundWeapon z poziomu Unity trzeba wpisać 2 lub jakiś inny parametr, bo też próbowałem i nic, dzięki za wcześniejsze odp.

    • 1) Jak widać promień leci ze złego miejsca w złe miejsce. Czyli pewnie źle określna jest pozycja wyjściowa oraz kierunek. Nie wiem też, jak udało Ci się tyle razy zduplikować linię. Tutaj muszę zobaczyć kod. (Proszę o wrzucenie przez jakiegoś pastebina albo coś).

      2) Na myśl przychodzi mi tylko brak deklaracji niektórych zmiennych publicznych. Tutaj przydałby się zdjęcia inskektora obiektu ze skryptem inwentarza oraz broni. Oraz same skrypty. Sporo, ale błąd może być w wielu miejscach.

  • W GunsInventory jako zmienne Gun i MP5 przeciągnąłeś te z panelu Project czy te z Hierarchy? Powinny być te z panelu Hierarchy będące broniami przy graczu. Jeśli przypisałeś inne, to nie będzie działać.