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

Dzisiejszy odcinek: Komponenty w UNet

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

Jakiś czas temu opisywałem jak tworzyć gry multiplayer z wykorzystaniem UNet na podstawie prostego sterowania. Taki projekt, był trochę wynajdywaniem koła na nowo, bo o ile chodzi o przemieszczanie graczy, Unity daje nam gotowe narzędzia. Więc żeby nie wynajdywać innych kół, postanowiłem opisać najciekawsze komponenty dostępne w UNet.

NetworkTransform

Jeśli przerabiałeś sobie moje poprzednie tutoriale odnośnie UNeta to wiesz, że robiliśmy tam system sterowania postacią dla gry multiplayer. Przy czym stworzony tam kod można prosto zastąpić komponentem: NetworkTransform.

NetworkTransform zapewnia nam synchronizację parametru transform obiektu na wszystkich komputerach.Tzn. jeśli przesuniemy obiekt o 10 i posiada on ten komponent, obiekt zostanie przesunięty na wszystkich klientach i serwerze.

Ważne jest tutaj, aby ustawić sobie odpowiednio NetworkIdentity. Ponieważ system dla klienta będzie dobrze działał tylko wtedy, gdy ustalimy mu bycie obiektem klienta. Jeśli UNet nie zostanie o tym poinformowany, to nie dokona synchronizacji.

Teraz aby zrobić to samo, co w poprzednich tutorialach, wystarczy dodać do obiektu gracza ten komponent i wzbogacić go o taki skrypt:

Jak widać, skrypt nie robi nic, po za dokonaniem lokalnego przesunięcia, po naciśnięciu przycisku. NetworkTransform synchronizuje pozycję gracza, ale nie tworzy kodu sterowania!

Zaznaczamy, że obiekt jest obiektem lokalnym (nie serwerowym).
Zaznaczamy, że obiekt jest obiektem lokalnym (nie serwerowym).

NetworkIdentity zostanie dodane automatycznie po dodaniu NetworkTransform. Natomiast parametry samego NetworkTransform to:

  • Network Send Rate – Czyli jak często w trakcie sekundy dokonywana jest synchronizacja pozycji. Dla obiektów, które nie muszą być synchronizowane po utworzeniu, takie jak pociski, dokumentacja zaleca ustalenie wartości tego parametru na 0,
  • Tranform Sync Method – Jaką metodę synchronizacji wykorzystać,
  • Movement Thresh – Jest to wartość, którą musi przekroczyć przesunięcie postaci, żeby nastąpiła synchronizacja,
  • Snap Threshold – Jeśli obiekt zostanie jednorazowo przesunięty o wartość większą od tego parametru, obiekt zostanie natychmiastowo przeniesiony na nową pozycję, zamiast powoli przesunięty,
  • Interpolate Movement Factor – Umożliwia interpolację przesunięcia,
  • Rotation Axis – Pozwala wybrać, w okół których osi ma być synchronizowana rotacja,
  • Interpolate Rotation Factor – Umożliwia interpolację rotacji,
  • Compress Rotation – Jak bardzo skompresować rotację (prawdopodobnie utrata dokładności, w zamian za szybkość przesyłu danych),
  • Sync Angular Velocity – Do interpolacji rotacji przesyła również velocity (prędkość).

 

NetworkStartPosition

Ten komponent jest prosty i bezparametrowy, a jego nazwa mówi wszystko. Zamiast kombinować gdzie gracz ma się domyślnie pojawiać, ustawiamy gdzieś NetworkStartPosition. Spawnowany gracz, pojawi się dokładnie w lokalizacji tego komponentu. Najlepiej przypisać go do pustego GameObjectu.

Przykładowe użycie NetworkStartPoint
Przykładowe użycie NetworkStartPoint

NetworkProximityChecker

Bardzo fajne narzędzie. NetworkProximityChecker określa czy gracz powinien widzieć inne obiekty sieciowe. Jako obiekt sieciowy rozumiemy taki, który jest synchronizowany pomiędzy komputerami, np. obiekty graczy. NetworkPorximityChecker posiada kilka parametrów, w tym najistotniejszy jest zasięg. Jeśli jakiś obiekt sieciowy jest w zasięgu, to zostaje wyrenderowany.

Taka rzecz jest dla nas przydatna z dwóch powodów. Po pierwsze możemy bardzo prosto zrobić sobie zasięg widzenia postaci. Np. możemy szybko określić, które jednostki w grze są widziane przez nasze jednostki. Druga sprawa, to optymalizacja łącza. Jeśli gracz nie widzi jakiejś jednostki, to nie musimy mu przesyłać danych o jego położeniu, rotacji etc. Tym samym oszczędzamy łącze. Jak wiemy z poprzedniej części kursu, Unity liczy nas za transfer, więc taka oszczędność łącza, to też oszczędność pieniędzy.

NetworkProximityChecker w UNet
NetworkProximityChecker w UNet

Co dają parametry?

  • Vis Range – Czyli jaki mamy zasięg widzenia,
  • Vis Update Interval – Jak często (w sekundach) ma być sprawdzane pole widzenia,
  • Check Method – Metoda sprawdzania zasięgu widzenia,
  • Force Hidden – Nie mam pojęcia, a dokumentacja tego nie opisuje.

Żeby go przetestować wystarczy dodać komponent do obiektu gracza i pochodzić sobie postacią. W pewnej odległości drugi gracz zniknie. Polecam tutaj ustawić Vis Range na 1, żeby szybko zaobserwować efekt.

NetworkMigrationManager

Kolejny bardzo fajny komponent wprowadzony wraz z wersją Unity 5.3. Załatwiam nam… migrację hosta. Jeśli gramy sobie w grę i gracz X jest hostem, ale z jakiegoś powodu straci połączenie, to wszyscy inni są wyrzucani z gry. Tak było do tej pory. Proste dodanie NetworkMigrationManagera, sprawia, że UNet orientuje się, że straciliśmy hosta. Wtedy podtrzymuje rozgrywkę i próbuje przywrócić połączenie z hostem. Ale każdy z graczy ma wybór opuszczenia rozgrywki, lub zgłoszenie się na hosta. Ze zgłoszonych osób UNet wybiera hosta i gra toczy się dalej. Co prawda bez tej jednej pechowej osoby…

Network Migration Manager
NetworkMigrationManager

NetworkMigrationManager oferuje własne GUI. Nie jest atrakcyjne, ale działa. Żeby go przetestować, wystarczy dodać komponent do jakiegoś obiektu, uruchomić grę dla 2 graczy i rozłączyć hosta.

NetworkTransformChild

Bardzo podobny do NetworkTransform z taką różnicą że dotyczy obiektów podrzędnych (childów). Jeśli nasz obiekt ma childy, to możemy do niego (nie do childów!) dodać NetworkTransformChild, który przypilnuje za nas synchronizację obiektów podrzędnych danego obiektu w całej grze.

NetworkTransformChild w UNet
NetworkTransformChild w UNet
  • Network Send Rate – Jak często synchronizujemy (w sekundach),
  • Target – Obiekt child, który mamy synchronizować,
  • Movement Treshold – Jest to wartość, którą musi przekroczyć przesunięcie postaci, żeby nastąpiła synchronizacja,
  • Interpolate MOvement i Interpolate Rotation – Współczynniki wykorzystane do kontroli interpolacji przesunięcia i rotacji,
  • Rotation Axis – Po jakich osiach można wykonywać rotację,
  • Compress Rotation – Dokumentacja tego nie opisuje, ale domyślam się, że możemy skompresować dane, zmniejszajć dokładność rotacji, ale oszczędzając transfer i przyspieszając przesyłanie danych.

Własny HUD

To już nie jest komponent, ale coś o co byłem pytany i uznałem, że warto o tym wspomnieć. Mamy co prawda NetworkHUD, ale jak on wygląda każdy widzi. Więc nasuwa się pytanie, jak zrobić własny HUD? Odpowiedź jest prosta, ale pewnie wielu osób nie ucieszy. Trzeba go napisać samemu. Unity udostępnia kawałek kodu, który ma mniej więcej funkcjonalność HUDa. Jest tam sporo kodu niskopoziomowego, do tego funkcję onGUI, które już znamy. Więc taki kod łatwo można dostosować do swoich potrzeb. No cóż, nie mogli za nas odwalić wszystkiego.

Poniżej kod, który rozwiązuje MatchMaking z prostym przesyłaniem komunikatów.

Podsumowanie

To już chyba ostatnia część dotycząca UNet. W najbliższym czasie raczej nie będę do tematu wracał, chyba że coś znaczącego się w temacie zmieni. Jeśli macie pytania, zachęcam do zostawienia ich w komentarzu, na pewno odpowiem.

Podoba Ci się? Udostępnij!