11 listopada 2024

Popsułem grę ...

Trochę popatrzyłem w  kod i podczas implementacji podnoszenia przedmiotów (w kontekście realizacji questa) zacząłem analizować w jaki sposób mój bohater wykrywa kolizję z przedmiotami w grze. No i wyszło mi, że coś dziwnie. Stąd wyłączyłem kolizyjność  na poszczególnych warstwach oraz maskach (czymże są krok dalej) i nie potrafię jej teraz poprawnie włączyć!

Aktualnie postać przenika przez ściany, nie umie już otworzyć drzwi, pułapka inicjuje się na warstwie do której nie należy. Totalnie poplątałem warstwy kolizji i maski kolizji, a teraz mozolnie próbuję to naprawić. 

Trochę teorii

Model kolizji w godot opiera się na warstwach. Mamy warstwy, w której przedmiot z którym możemy wejść w interakcje istnieje w grze czyli tzw. CollisionLayer oraz warstwę, z którą przedmiot powinien kolidować tzw. Collision Mask. Do wyboru są możliwe 32 warstwy (!) stąd wynika, że ta funkcjonalność może być niebywale skomplikowana. 

Tak wygląda to w oknie edytora

Przykładowa kolizja ze ścianą

I teraz, aby nasz bohater potrafił kolidować np. ze ścianami, musi posiadać w definicji węzła CollisionShape2D dopasowane maski CollisonMask odpowiadające za CollisionLayer warstwy ścian. 

Dla ścian definiujemy iż są w grze na pierwszej warstwie kolizyjnej CollisionLayer :  

Warstwy kolizji można samodzielnie nazywać stąd też WALL

A nasz bohater (poniżej) musi mieć odpowiednio zdefiniowaną CollisionMask:

Aby kolidować ze ścianą w ramach CollisionMask wybieramy warstwę pierwszą. Zaznaczona
CollisionLayer o numerze 2 to warstwa na której znajduje się gracz

Tyle teorii

W ramach sprawdzenia napisałem projekcik gdzie postać po prostu łazi i koliduje. Okazało się, że czasem dziwacznie reaguje na zdefiniowane na ekranie obszary pewnie przez moją niewiedzę. Cóż walka o zrozumienie tematu trwa ponieważ dotyczy to całej rozgrywki, a nie chciałbym aby postać kolidował z każdym elementem na ekranie i każdy ekran zawsze był aktywny jako kolidujący z wszystkimi warstwami.

Tutaj kilka przykładów jak działają kolizje.

Gracz (CharactedBody2d) nie jest przypisany do żadnej warstwy kolizyjnej (CollisionLayer) ani nie sprawdza warstw z którymi może się zderzać (MaskLayer) - trzeba przyznać że dupne to nazewnictwo ale nie przeskoczę tego.

Efekt widać poniżej - 

Gracz (postać w ciemnym kolorze) wpada POD postać NPC 

NPC ma CollisionLayer w warstwie 5 (warstwę opisałem jako NPC)



Odznaczamy CollisionMask na 5 warstwie dla postaci gracza... 

I gracz traci możliwość wejścia za NPC


Teraz podobnie dla ścian - gracz nie koliduje ze ścianami (warstwa 1 w CollisionLayers) dla TileMap


Gracz przenika ścianę


 W edytorze to warstwa MaskLayer = 1 opisana jako WALL


Po odznaczeniu maski dla warstwy ścian (widać odznaczony checkbox na ekranie) gracz przestaje przenikać przez ściany


Ale za to pojawił mi się problem z wykrywaniem kolizji z użyciem tzw RayCast2D czyli promienia który powinien wykrywać kolizje z poszczególnymi warstwami. I o ile wykrywa kolizję z warstwą MUR  lub NPC ... to nie wykrywa mi kolizji z elementami, które są niby tak samo zdefiniowane a podpięte są pod węzły o typie  Area2D posiadające węzeł kolizyjny CollisionShape. I nie wiem dlaczego. Cóż posiedzę nad tym i może na coś wpadnę.


A bohater miał tylko podnosić przedmioty, a teraz to ... szkoda gadać


p.s.

Już wiem dlaczego RayCast2D nie wykrywał kolizji z Area2D ... ma na to specjalną opcję do odklikania nazwaną Areas. Bez niej nie wykrywa takich obszarów. Poniżej widać ją niemal na samym dole zrzutu ekranowego


I teraz przykład co było nie tak


RayCast2D ze źle zdefiniowanym wykrywaniem kolizji - mimo tego, że w konfiguracji powinien kolidować z tzw. GROUND_AREA (moja nazwa dla warstwy 4 CollisionLayer  na której umieściłem Arae2Dkolizji jednak nie ma.


I tutaj poprawna sytuacja - RayCast2D wykrył kolizję na warstwie 4 z elementem Area2D po odklikaniu opcji Areas w konfiguracji promienia. Widać to po tym jak świeci się na czerwono.





Brak komentarzy:

Prześlij komentarz

Tu możesz wstawić swój komentarz