Logowanie w Unity

Ostatnio popadłem w lekki marazm. Przerobiłem większość tematów z Unity, nawet rzeczy związane z 3D (za którym nie przepadam): proceduralnie generowane mesh’e i shader’y. Te ostatnie będą niedługo prostsze w obsłudze, gdy na dniach wyjdzie wersja 2018.1 zawierająca Shader Graph. Nie mogąc znaleźć nic nowego do nauki, postanowiłem pobawić się pisaniem kodu sieciowego. Sprawa jest dość skomplikowana i na pewno nie dla początkujących. David Brevik na swoim wykładzie Diablo: A Classic Game Postmortem opowiada jak musieli przepisywać Diablo na nowo, bo po napisaniu gry okazało się że nie ma ani jednej linijki kodu sieciowego.

Pierwszy problem u mnie pojawił się w momencie podłączenia klienta do serwera. Każdy klient tworzył dwóch nowych graczy – tymczasowego i właściwego – zamiast jednego. Debugowanie gier jest ogólnie ciężkie, bo aktualizacja wykonuje się kilkadziesiąt razy na sekundę. Dodajmy do tego możliwość debugowania tylko jednego środowiska: klienta albo serwera. W Unity nie możemy mieć otwartego tego samego projektu w dwóch instancjach środowiska. Rozdzielenie ich na dwa projekty rozwiązałoby ten problem, ale spowodowałoby kolejny. Większość materiałów wykorzystywana jest w obu projektach i trzeba by zmieniać rzeczy w dwóch miejscach…

Zdecydowałem się na użycie logger’a. W podstawowej wersji mamy do dyspozycji Debug.Log, który w zupełności wystarczy do prostych gier. Ja potrzebuję czegoś obsługującego poziomy logowania, np. NLog. Dzięki niemu mogę sobie puścić osobną ścieżkę Trace do prześledzenia całego ruchu sieciowego, a standardowe zdarzenia obsłużyć w Debug, Warn i Error. Dodatkowo całość nasłuchiwana jest przez sieć i dzięki temu otrzymuję historię od kogo były wysyłane komunikaty, jeden po drugim.

Podstawowy tutorial znajdziemy na GitHub – NLog – Flexible logging for C# and Unity. Pobieramy najnowszą wersję z Releases. Dorzucamy do naszego projektu 3 foldery:

  • NLog
  • NLog.CommandLineTool
  • NLog.Unity

Teraz wystarczy przeciągnąć prefab NLog z folderu NLog.Unity na scenę. U mnie to nie zadziałało. Musiałem utworzyć nowy pusty GameObject i dodać mu dwa skrypty – N Log Config oraz Client Socket Appender. Zmieniłem też domyślny port na 9999.

Drugim etapem jest użycie logger’a w skrypcie. Standardowo wygląda to tak:

Dla klienta zmieniłem trochę inicjalizację, żebym wiedział kto do mnie mówi:

W folderze NLog.CommandLineTool znajduje się plik NLog.exe. Mój antywirus go zjadał i dodawał do kwarantanny, dlatego musiałem utworzyć wyjątek. Ten plik odpalamy w konsoli poprzez komendę „słuchaj portu”:

Standardowa konsola jest mało czytelna. Git Bash jest kolorowy, ale nic nie było w nim widać, a nie chciało mi się bawić kolorami. Cmder rozwiązał sprawę od ręki i wygląda to mniej więcej tak:

Pora wracać do pracy.