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 |
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) |
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
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