Archives Październik 2020

Poziomy 2D oraz Tile Maps

Mapy kafelków służą do tworzenia poziomów 2D na podstawie zestawów kafelków. W tym artykule użyjemy Unreal Editor w wersji 4.8, aby stworzyć poziom w oparciu o kafelki z poniższego obrazka, który został stworzony przez Silveira Neto 

Zaimportuj powyższy obrazek i zmień nazwę tekstury na „Tiles”. Kliknij teksturę prawym przyciskiem myszy i wybierz „ Sprite Actions -> Zastosuj ustawienia tekstury Paper2D ”. Następnie wybierz „ Create Tile Set”

Kliknij dwukrotnie „Zestaw kafelków”, aby otworzyć edytor zestawów kafelków:

W tym edytorze możesz zmienić rozmiar „Kafli”, domyślny rozmiar to 32×32. Możliwe jest również ustawienie płytek, które mają kolizję. Po prostu wybierz kafelek i kliknij przycisk „Dodaj pole” znajdujący się w górnej części edytora.

Po zdefiniowaniu płytek, które mają kolizję, zapisz i zamknij edytor zestawów płytek.

Kliknij prawym przyciskiem myszy „Tile Set Actions” i wybierz „Create Tile Map”:

Kliknij dwukrotnie „Mapa kafelkowa”, aby otworzyć edytor mapy kafelkowej:

Zanim zaczniemy edytować poziom, dokonamy pewnych korekt. Po prawej stronie edytora, w kategorii „Ustawienia”, wpisz 20 w „Szerokość mapy” i 15 w „Wysokość mapy”. Ponieważ rozmiar każdego kafelka wynosi 32×32, rozmiar mapy kafli będzie wynosił 640×480 pikseli.

Dodamy warstwy do tej mapy kafelkowej. Pozwala to na nałożenie płytek. Nasz przykład będzie miał trzy warstwy:

Poniższy obrazek przedstawia sposób wykorzystania warstw. Po lewej stronie zastosowano tylko warstwę 1, pośrodku płytki w warstwie 1 i 2, po prawej zastosowano trzy warstwy.

Aby edytować poziom, po prostu wybierz kafelek po lewej stronie, a następnie kliknij żądane miejsce na mapie kafelków. Edytor udostępnia kilka opcji:

Za pomocą przycisków powyżej możesz odwrócić i obrócić kafelek , usunąć kafelek lub wypełnić obszar wybranym kafelkiem .

Możesz wybrać wiele kafelków , po prostu klikając lewym przyciskiem myszy i przeciągając. Żółty prostokąt przedstawia dokonywany wybór:

Mój poziom 2D wyglądał tak:

Po zakończeniu edycji mapy kafelkowej zapisz i zamknij edytor mapy kafelkowej.

Przeciągnij mapę kafelków i zwolnij w dowolnym miejscu w rzutni edytora. Edytor automatycznie tworzy  „PaperTileMapActor”:


Źródło:https://romeroblueprints.blogspot.com/2015/07/2d-levels-with-tile-maps.html

Używanie struktur w Blueprints

W tym artykule dowiemy się więcej o „strukturze” (struct). Użyliśmy już różnych struktur w naszych Planach, nie wiedząc, czym one naprawdę są. W uproszczony sposób Schemat składa się z „danych”, „działań” i „komponentów”. Czasami jednak wystarczy zebrać w jednym miejscu kilka zmiennych. Zamiast tworzyć schemat zawierający tylko „dane”, możemy stworzyć strukturę .

Przykładem szeroko stosowanej struktury jest Vector. Wektor to struktura zawierająca trzy zmienne typu „float” o nazwach X, Y i Z. W następnych artykułach lepiej zrozumiemy matematyczną koncepcję wektora. Otwórz Blueprint iw EventGraph dodaj funkcję „GetActorLocation”. Zmienna „Lokalizacja” to wektor. Kliknij prawym przyciskiem myszy „Wartość zwracana” i wybierz „Podziel sworzeń struktury  ”:

Ta opcja utworzy pin wyjściowy dla każdego elementu konstrukcji:

Zmienne, które są częścią struktury, mogą mieć różne typy. Możemy również mieć struktury utworzone przez inne struktury. Przykładem jest struktura „Transform”, która ma trzy zmienne, które są strukturami. Zmienne „Lokalizacja” i „Skala” są typu „Wektor”, a zmienna „Obrót” jest typu „Rotator”, który jest również strukturą. Poniższy obrazek przedstawia funkcję „GetActorTransform” w jej normalnym formacie i ze strukturą podziału:

Możemy nawet oddzielić każdą ze struktur wchodzących w skład „Transformacji”, a wynik będzie wyglądał następująco:

Aby utworzyć nową strukturę, kliknij przycisk „Dodaj nowy” w Wyszukiwarce bibliotek, kategoria „Plany”, opcja „Struktura”:

Wpisz nazwę „ItemStruct” i kliknij dwukrotnie strukturę, aby edytować jej zawartość. Kliknij przycisk „Nowa zmienna”, aby dodać zmienne do struktury. Poniższy obraz przedstawia strukturę z trzema zmiennymi różnych typów.

Po prawej stronie możesz ustawić domyślne wartości zmiennych. Ta utworzona struktura będzie używana jako nowy typ zmiennej.

Utwórz nową zmienną w dowolnym Blueprint. Wpisz nazwę „Inventory”, typ to „ItemStruct”. Kliknij ikonę obok typu, aby przekształcić tę zmienną w tablicę . Zaznacz opcję „Edytowalne”.

Skompiluj plan. W kategorii „Wartość domyślna” zmiennej można dodawać elementy w tablicy. Każdy element zawiera zmienne zdefiniowane w strukturze:

Kiedy tworzona jest struktura, Akcje „Break” i „Make” tej struktury są dodawane do użycia w Planie. Akcja „Break” pobiera strukturę jako dane wejściowe i oddziela jej elementy. Akcja „Make” przyjmuje jako dane wejściowe oddzielne elementy i tworzy nową strukturę. Poniższy obraz przedstawia działania „Break” i „Make” struktury „ItemStruct”, którą utworzyliśmy:

Poniższy obraz przedstawia przykład użycia akcji „Break” i „Make”. Naciśnięcie spacji modyfikuje wartość Z pozycji aktora, która otrzymuje wartość 0. Wartości X i Y są zachowywane.


Źródło:https://romeroblueprints.blogspot.com/2015/08/using-structs-in-blueprints.html

Współrzędne Local oraz World

Przestrzeń 3D jest reprezentowana przez trzy osie: X, Y i Z. Istnieją różne sposoby organizacji tych osi. Unreal Engine wykorzystuje ten typ:

Można to zobaczyć w „Widgecie tłumaczenia” aktorów:

Kliknij, aby powiększyć

Dowolne położenie w przestrzeni 3D można przedstawić za pomocą zestawu wartości X, Y i Z, wskazujących położenie na każdej osi. Te wartości są przechowywane w zmiennej „Lokalizacja”  aktora i są znane jako współrzędne świata 

Nierzeczywista jednostka to jeden centymetr. Aby użyć wartości „Lokalizacja” w Planie, można użyć następujących funkcji:

Funkcja „GetActorLocation” zwraca bieżącą pozycję aktora. Funkcja „SetActorLocation” ustawia nową pozycję dla aktora. „AddActorWorldOffset” używa wartości parametru „Delta Location” do modyfikowania bieżącej pozycji aktora. Poniższy przykład dodaje 1000 cm na osi X aktualnej pozycji aktora i nie modyfikuje wartości osi Y i Z.

Istnieje inna koncepcja znana jako współrzędne lokalne. Aby zrozumieć tę koncepcję, użyjemy schematu, który zawiera dwa komponenty „Static Mesh”.

Utwórz nowy plan typu „aktor”. W zakładce „Komponenty” dodaj nowy komponent typu „StaticMesh” i nadaj mu nazwę „Baza”. Przeciągnij nazwę „Base” i upuść na komponencie o nazwie „DefaultSceneRoot”:

Zrobiliśmy to tak, aby pozycja „Base” StaticMesh reprezentowała pozycję Blueprint. Ten StaticMesh stał się „Rootem” Planu. Dla tego komponentu wybierz Static Mesh „SM_AssetPlatform” i jako Material użyj „M_Tech_Hex_Tile”, które są częścią „Starter Content”:

Dodaj kolejny komponent „StaticMesh”, nadaj nazwę „PowerPill” i wprowadź następujące ustawienia:

W zmiennej „Location” w „PowerPill” umieść wartość „70cm” na osi Z:

To położenie „PowerPill” jest odniesione do „Root”, który jest komponentem „Base”, więc kiedy przesuniemy „Base”, „PowerPill” będzie podążał za tym ruchem, ponieważ zawsze musi znajdować się w pewnej odległości  od „Baza”  70 cm w osi Z. To względne położenie jest znane jako współrzędne lokalne .

Możesz zobaczyć, jak stał się Planem na karcie „Rzutnia”:

Pozycję komponentu „PowerPill” można uzyskać na dwa sposoby. Możemy uzyskać jego położenie względne, które w tym przykładzie byłoby (X = 0, Y = 0, Z = 70), lub możemy otrzymać jego położenie na świecie, które będzie pozycją na świecie komponentu „Root” plus względne położenie elementu składnik „PowerPill”. Poniższy obraz przedstawia te dwie opcje:

Pozycję komponentu można również zdefiniować na dwa sposoby za pomocą funkcji „SetRelativeLocation” i „SetWorldLocation”. Funkcja „SetRelativeLocation” definiuje nową pozycję komponentu względem funkcji „Root”, a funkcja „SetWorldLocation” otrzymuje jako parametr wejściowy współrzędną światową i definiuje pozycję komponentu, tak aby suma pozycji elementu głównego z pozycją komponentu jest równa informowanej współrzędnej światowej.

Funkcji „AddRelativeLocation” można użyć do zmodyfikowania względnej pozycji komponentu:


Źródło:https://romeroblueprints.blogspot.com/2015/08/world-and-local-coordinates.html

Operacje typu Vector

Istnieje wiele operacji matematycznych, które można wykonać na wektorach. Zrozumienie tych podstawowych operacji jest podstawą manipulowania obiektami w przestrzeni 3D.

  • Dodawanie wektorów:

Suma dwóch wektorów jest tworzona przez dodanie każdego z jego elementów. Przykład:  V1 = (5, 0, 9) i V2 = (4, 0, 2) V1 + V2 = (5 + 4, 0 + 0, 9 + 2) V1 + V2 = (9, 0, 11)

Poniższy obrazek przedstawia operator Blueprint sumy wektorów:

  • Odejmowanie wektorów: 

Odejmowanie między dwoma wektorami odbywa się poprzez odejmowanie każdego z jego elementów.

Przykład: 
V1 = (12, 0, 14) i V2 = (4, 0, 8)V1 – V2 = (12 – 4, 0 – 0, 14 – 8)V1 – V2 = (8, 0, 6)

Poniższy obrazek przedstawia operator Blueprint odejmowania wektorów:

  • Długość wektora:

Długość lub wielkość wektora można obliczyć, korzystając z poniższego planu działania. Ta wartość może być używana do reprezentowania odległości między dwoma punktami.

  • Wektory normalizujące:

Używamy normalizacji wektorów, aby znaleźć wektor jednostkowy. Wektor jednostkowy ma długość równą 1. Jest często używany, gdy musimy tylko wskazać kierunek. W niektórych obliczeniach powinniśmy używać tylko znormalizowanego wektora.

  • Mnożenie wektora skalarnego:

Mnożenie wektora przez wartość skalarną odbywa się poprzez pomnożenie każdego z jego elementów przez wartość skalarną. Ta operacja zmienia długość wektora.

W przykładzie zobaczymy wszystkie te operacje używane razem. W tym przykładzie przeniesiemy Schemat w scenariuszu w kierunku losowego punktu. Kiedy Schemat dotrze do celu, ustawiany jest nowy losowy cel.
Moglibyśmy wykorzystać komponenty ruchu już zdefiniowane przez Unreal Engine, ale obliczmy ruch krok po kroku, aby zrozumieć różne zastosowania wektorów.

W obliczeniach ruchu użyjemy następujących zmiennych:

  • DeltaSeconds : ta zmienna przechowuje wartość przekazaną przez zdarzenie „Tick”, które reprezentuje czas, który upłynął od ostatniego „Tick”.
  • Speed : Przechowuje wartość prędkości Planu. Wartość domyślna to 100 (cm / s).
  • vDestination : wektor przechowujący pozycję, w której plan ma się przesunąć.
  • vDistance : Wektor wskazujący odległość od aktualnej pozycji BP do celu.
  • vDirection : wektor jednostkowy wskazujący kierunek, w którym Plan powinien podążać, aby dotrzeć do celu.
  • vVelocity : wektor reprezentujący prędkość i kierunek BP w cm / s.
  • vStep : Wektor z końcowym wynikiem obliczenia, który wskazuje ruch, który Plan powinien wykonać przy bieżącym „Tikku”.

Utworzono makro o nazwie „ SetRandomDestination ”, aby ustawić losowe miejsce docelowe. W tym przykładzie wartość osi Z jest ustalona na 300, a wartości osi X i Y mogą wynosić od -1000 do 1000. Utworzony wektor jest przechowywany w wektorze „vDestination”.

W tym przykładzie nie jest brany pod uwagę żaden rodzaj kolizji. Następnie test należy wykonać na obszarze bez przeszkód.

Aby ustawić początkowe miejsce docelowe, w zdarzeniu „BeginPlay” należy wywołać makro „SetRandomDestination”.

Poniższy obrazek przedstawia pierwszą część zdarzenia „ Tick ”, w której każdy z wektorów jest obliczany do momentu znalezienia wartości „vStep”. Wszystkie te obliczenia można było ujednolicić w jednym wyrażeniu matematycznym, ale każda część obliczenia była oddzielna, aby ułatwić zrozumienie.

W drugiej części zdarzenia „ Tick ” przesuń Schemat za pomocą akcji „AddActorWorldOffset” i sprawdź, czy Schemat dotarł do celu. Ten test jest wykonywany poprzez porównanie, czy aktualna odległość jest mniejsza niż wartość zmiennej „Prędkość”. Jeśli prawda, ustawiany jest nowy cel.

W moim przykładzie użyłem latającego stołu do przedstawienia mojego planu:


Źródło:https://romeroblueprints.blogspot.com/2015/10/vector-operations.html

Animacja 2D z flipbook

Flipbook to funkcja Paper 2D używana do tworzenia animacji 2D za pomocą Sprites. W tym artykule zobaczymy, jak używać kineografów do animowania wojownika.

Skorzystajmy z poniższego obrazka, który przedstawia Sprites wojownika wykonującego różne ruchy. 

Utwórz nowy pusty projekt bez korzystania z zawartości startowej i utwórz nowy pusty poziom. W Wyszukiwarce bibliotek utwórz folder o nazwie „FighterSprites” i zaimportuj powyższy obraz do tego folderu. Zmień nazwę tekstury na „Fighter”. Kliknij teksturę prawym przyciskiem myszy i wybierz „Działania Sprite -> Zastosuj ustawienia tekstury Paper2D”. Zapisz teksturę.

Wybierz opcję „Działania Sprite -> Wyodrębnij Sprite”:

W “Trybie wyodrębniania sprite’a” wybierz “Grid” i wpisz rozmiar sprite’ów  104×124:

Teraz stwórzmy kineografy z animacjami wojownika. Wybierz sprite’y o indeksach od 0 do 5 (Fighter_Sprite_0 do Fighter_Sprite_5). Kliknij prawym przyciskiem i wybierz „Create Flipbook”:

Zmień nazwę utworzonego kineografu na „IdleAnim”. To jest animacja, której użyje wojownik, gdy się nie porusza. Kliknij dwukrotnie flipbook, aby otworzyć edytor:

We właściwości „Klatki na sekundę” ustaw wartość 10. Należy to zrobić dla wszystkich kineografów, które utworzymy w tym artykule.
Musisz dokonać pewnych zmian w sekwencji sprite’ów „IdleAnim”. Animacja używa sprite’ów w tej kolejności {0,1,2,3,4,5,4,3,2,1}. Musimy więc zduplikować sprite’y od 1 do 4 i umieścić je w odwrotnej kolejności na końcu animacji. Aby powielić, kliknij prawym przyciskiem myszy na ikonie animacji i wybierz „Duplikuj”:

Następnie po prostu kliknij i przeciągnij duszki do właściwej pozycji. „IdleAnim” wygląda następująco:

W Wyszukiwarce bibliotek wybierz sprite’y z indeksami od 6 do 21 i utwórz flipbook o nazwie „WalkAnim”. Zmień opcję „Klatki na sekundę” na 10.

Wybierz sprite’y 34, 35 i 36 i utwórz flipbook „PunchAnim”. Sekwencja „PunchAnim” to {34,35,36,36,35,34}. Zwróć uwagę, że duszek 36 zajmuje dwie klatki animacji. Edytor kineografu pozwala zdefiniować, ile klatek animacji zajmuje duszek:

Flipbook „KickAnim” jest podobny do „PunchAnim”. Używa sprite’ów 37, 38 i 39, a sekwencja animacji to {37,38,39,39,39,37}. Teraz stwórzmy schemat wojownika. Będzie to typ „PaperCharacter”:

Wpisz nazwę „FighterCharacter” dla tego nowego schematu i otwórz edytor planów. „PaperCharacter” zawiera element flipbook o nazwie „Sprite”. Wybierz go i wybierz „IdleAnim” jako „Source Flipbook”:

Utwórz następujące zmienne logiczne:

Aby kontrolować zawodnika, będziemy używać prawej i lewej strzałki do poruszania się, lewego Shifta do uderzania i lewej Control do kopania. Poniższy obraz przedstawia zdarzenia wejściowe:

Animacje, których będziemy używać, mają różne cechy. Jeden będzie działał w odwrotnej kolejności, a niektóre pozostaną w pętli. Aby uprościć, utwórz makro o nazwie „ Play2DAnimation ” i ustaw następujące parametry:

W „Flipbook Komponent”  parametr  jest „Paper Flipbook Komponent”. Parametr „Animation” to „Paper Flipbook”.

Makro ma następujące akcje:

Akcje wojownika są obsługiwane podczas wydarzenia „Tick”. Jeśli wojownik atakuje, żadne nowe polecenie nie zostanie wykonane, dopóki animacja ataku się nie zakończy. Poniższe obrazy przedstawiają działania zdarzenia „Tick”.

 Blueprint „Fighter” można zdefiniować jako „Default Pawn” w „GameMode”. Jeśli to zrobisz, nie zapomnij umieścić „PlayerStart” na poziomie, aby wskazać, gdzie gracz zacznie.

„PaperCharacter” jest już skonfigurowany do automatycznego wykorzystywania grawitacji. Jeśli nie chcesz używać grawitacji, po prostu ustaw wartość „0.0” we właściwości „Skala grawitacji” komponentu „Ruch postaci”:


Źródło:https://romeroblueprints.blogspot.com/2015/07/2d-animation-with-flipbooks.html

Paper 2D Game: GameManager i GameMode

Zostaną również wprowadzone pewne poprawki w schemacie „EnemyCar” w celu interakcji ze schematem „GameManager”. Na końcu artykułu zostanie utworzony nowy „GameMode” do wykorzystania schematu „GameManager” jako HUD. 

  • GameManager

Utwórz nowy plan typu „HUD”. Wymaga to rozwinięcia opcji „Wszystkie klasy” i wyszukania hasła „HUD”:

Wpisz nazwę „GameManager” dla tego schematu.
Utwórz zmienne: „Score” (Integer), „Level” (Integer), „EnemyCarSpeed” (Float) i „Menu” (Boolean).

Gra może znajdować się w Menu, które wyświetla komunikat „Naciśnij ENTER, aby rozpocząć” lub działa. Jest to kontrolowane przez zmienną logiczną „Menu”. Zdarzenie BeginPlay przypisuje dodatnią wartość zmiennej „Menu”, więc gra rozpoczyna się w menu. Umożliwia również zdarzenia wejściowe do planu „GameManager”:

Po naciśnięciu klawisza Enter sprawdzane jest, czy gra jest w “Menu”, jeśli prawda, to wywoływane jest zdarzenie niestandardowe “StartGame”:

Niestandardowe zdarzenie „StartGame” przygotowuje zmienne i liczniki czasu dla nowej gry i tworzy instancję „PlayerCar” na pozycji (X = 320, Y = 1, Z = 100). Wartość osi Y wynosi „1”, więc „PlayerCar” znajduje się przed tłem, czyli Y = 0.

Zdarzenie „TimerCreateEnemyCar” jest początkowo wywoływane co 2 sekundy. Tworzy po prostu instancję „EnemyCar” w pozycji (X = 320, Y = 1, Z = 520), która znajduje się nad ekranem gry. W Blueprint „EnemyCar” została utworzona nowa zmienna, która zawiera odniesienie do „GameManager”. Tworzenie tej zmiennej pokazano poniżej w dostosowaniach „EnemyCar”.

Zdarzenie „TimerAddScore” jest wywoływane co 0,5 sekundy. Zwiększa punkty gracza zgodnie z wartością zmiennej „Poziom” pomnożoną przez 50.

Zdarzenie „TimerChangeLevel” jest wywoływane co 10 sekund. Oto niektóre z działań tego wydarzenia:

  • Zwiększa prędkość wrogiego samochodu w 25.
  • Zwiększa wartość zmiennej „Poziom”.
  • Odtwarza „TimerCreateEnemyCar” z niższym czasem w oparciu o bieżący poziom.
  • Sprawdza, czy jest na poziomie 5, aby wyłączyć „TimerChangeLevel”, ponieważ 5 to najwyższy poziom.

Wydarzenie „Receive Draw Hud” należy do klasy HUD . Służy do rysowania wyniku i poziomu na ekranie. Komunikat „Naciśnij ENTER, aby rozpocząć” jest wyświetlany, jeśli gra jest w menu.

Niestandardowe wydarzenie „Koniec gry” aktywuje menu, niszczy wszystkie wystąpienia „EnemyCar” i czyści wszystkie liczniki czasu. To wydarzenie zostanie wywołane przez „EnemyCar”, gdy gracz nachodzi na siebie.

  • EnemyCar

Zakończymy schemat „EnemyCar”, który rozpoczął się w poprzednim artykule . Musimy utworzyć zmienną odwołującą się do „GameManagera”. Zaznacz „Edytowalne” i „Ujawnij przy odrodzeniu”, abyśmy mogli przekazać odniesienie do GameManagera w momencie tworzenia „EnemyCar”, jak widać powyżej.

Zmień zdarzenie „Tick”  ,  tak aby korzystało ze zmiennej „EnemyCarSpeed” z „GameManager”:

Utwórz zdarzenie „ActorBeginOverlap”, które testuje kolizję z graczem i, jeśli wystąpi, powiadamia „GameManager” o zakończeniu gry.

Użycie powyższej akcji „Rzuć na” służy do sprawdzenia, czy Aktor, który się nakładał, jest „Samochodem Gracza”.

  • Tryb gry

Utwórz nowy plan typu „GameMode” i wpisz nazwę „GameMode2D”. Kliknij dwukrotnie schemat i zmień właściwość „Domyślna klasa pionków” na „Pion” iw „Klasie HUD” umieść „GameManager”: 

Wejdź do menu „Edycja-> Ustawienia projektu …”, kategoria „Mapy i tryby”. W „Default GameMode” wybierz „GameMode2D”, który tworzymy:

Tym samym zakończyliśmy realizację „Papierowej gry 2D”.


Źródło:https://romeroblueprints.blogspot.com/2015/07/paper-2d-game-gamemanager-and-gamemode.html

Paper 2D Game: Samochody

Wcześniej chciałbym pokazać opcję edytora, która jest często używana w tych Planach, czyli opcję „Podziel Pin Struct Struct”. Wiele Akcji Planu otrzymuje strukturę jako parametr. “Lokalizacja” jest przykładem struktury, która agreguje wartości X, Y i Z. Po kliknięciu prawym przyciskiem na parametr konstrukcji pojawia się opcja “Split Pin Struct”, która rozdziela strukturę na różne parametry. Poniższy obraz przedstawia akcję „Ustaw lokalizację aktora” przy użyciu lokalizacji i oddzielnej struktury:

  • Schemat samochodu gracza :

Zacznijmy od schematu, który reprezentuje gracza. Utwórz nowy schemat typu „Aktor” o nazwie „PlayerCar”.

Otwórz plan, na karcie „Komponenty” dodaj „Paper Sprite”:

Na karcie „Szczegóły” w „Paper Sprite”, we właściwości „Source Sprite” wybierz „PlayerCar_Sprite”:

Aby przetestować kolizję, dodaj komponent typu  „Capsule Collision”:

Na karcie „Szczegóły” sekcji „Kapsuła” we właściwości „Kształt” wprowadź następujące wartości:

W zakładce „MyBlueprint” utwórz zmienne „CarSpeed” (typ zmiennoprzecinkowy), „HorizontalDir” (typ całkowity) i „VerticalDir” (typ całkowity):

W zmiennej „CarSpeed” wpisz „200” jako „Wartość domyślna”. W tej grze jeden piksel równa się jednej Unreal Unreal (uu), wówczas wartość tej zmiennej oznacza, że ​​prędkość samochodu gracza wynosi 200 pikseli / sekundę.

Kliknij przycisk „Ustawienia domyślne klasy” na górnym pasku edytora schematów i na karcie „Szczegóły”, w kategorii „Dane wejściowe”, we właściwości „Automatyczne odbieranie”, kliknij pole kombi i wybierz „Gracz 0”. Służy to wskazaniu, że ten plan będzie otrzymywał polecenia wejściowe gracza.

Samochód gracza jest sterowany za pomocą klawiszy strzałek. Zdarzenia wejściowe modyfikują wartość zmiennych „HorizontalDir” i „VerticalDir”. Zmienne te mogą przyjmować wartości -1, 0 i 1. Służą one do obliczania kierunku, w którym porusza się samochód. Poniższy obraz przedstawia zdarzenia wejściowe.

Ruch samochodu gracza będzie się odbywał podczas imprezy „Tick”. Jeśli nie znasz zdarzenia „Tick” i parametru „Delta Seconds”, zapoznaj się z artykułem „ Tick ​​Event and Latent Actions in Blueprints ”. Treść imprezy Tick jest następująca:

Funkcja „Zacisk” służy do ograniczania „Samochodu gracza” na ulicy. W tym celu wartość X musi wynosić co najmniej 160, a maksymalnie 480. Wartość Z musi wynosić od 40 do 440. Zmienne „HorizontalDir” i „VerticalDir” są mnożone przez wartość prędkości. Na przykład, jeśli zmienna „HorizontalDir” ma wartość 1, to wynik będzie wartością dodatnią, która wskazuje, że samochód powinien poruszać się po osi X w prawo. Jeśli wynosi -1, wynik jest ujemny, co oznacza, że ​​ruch na osi X jest w lewo. Jeśli „HorizontalDir” ma wartość 0, wynikiem jest 0, więc nie przesunie się na osi X.

  • Schemat EnemyCar :

Utwórz nowy plan typu „Actor” o nazwie „EnemyCar”. W zakładce „Components” dodaj „Paper Sprite” i „Capsule Collision” w taki sam sposób, jak w przypadku „PlayerCar”. Użyj „EnemyCar_Sprite” we właściwości „Source Sprite”. Utwórz zmienną typu Integer o nazwie „Kierunek”.

„EnemyCar” rozpoczyna grę na górnym ekranie. Porusza się w dół, a jego ruch poziomy jest definiowany przez wartość zmiennej „Kierunek” (-1 = w lewo, 0 = środek, 1 = w prawo). Wartość zmiennej „Kierunek” zmienia się losowo w okresie od co najmniej 0,5 sekundy do maksymalnie 1,5 sekundy. Utworzono zdarzenie niestandardowe o nazwie „ChangeDirection”. Odpowiada za te zmiany wartości.

Funkcje typu „Random” zwracają losową wartość między określoną wartością minimalną i maksymalną. Używana jest funkcja „SetTimer_Delegate” do planowania następnego wywołania zdarzenia „ChangeDirection”. Parametr „Delegate” jest odniesieniem do zdarzenia, wystarczy połączyć mały czerwony kwadrat, który istnieje w przypadku zdarzenia, z parametrem funkcji „SetTimer_Delegate”. Zauważ, że timer nie jest z aktywną pętlą i będzie działał tylko raz. Każde wywołanie „ChangeDirection” aktywuje Timer z inną wartością czasu. Zdarzenie Tick jest podobne do „PlayerCar”. Jedna różnica polega na tym, że użyliśmy funkcji „AddActorWorldOffset”, która dodaje wartości przekazane jako parametry do bieżącej wartości lokalizacji:

Szybkość „EnemyCar” jest tymczasowo ustawiona na wartość „100”. W następnym artykule wartość ta zostanie dostosowana do aktualnego poziomu gry. Po zmodyfikowaniu pozycji „EnemyCar” wywoływane jest makro „TestLimit”, które sprawdza, czy „EnemyCar” dotknął boków ulicy lub opuścił pole gry:

Jeśli „EnemyCar” przekroczy dolną część ekranu, zostaje zniszczony. Jeśli „EnemyCar” dotknie boków ulicy, kierunek ruchu zostanie odwrócony.

Brakuje niektórych szczegółów „EnemyCar”, które można ukończyć dopiero w następnym artykule, kiedy stworzyliśmy Blueprint „GameManager”, który będzie przechowywał informacje o grze.


Źródło:https://romeroblueprints.blogspot.com/2015/07/paper-2d-game-cars.html

Paper 2D Game: Sprites oraz Camera

Paper 2D to system silnika Unreal Engine 4 służący do tworzenia gier 2D opartych na Sprites. Sprite to obraz przedstawiający obiekt w grze 2D.

Główne elementy wchodzące w skład Paper 2D to Sprite, Flipbook i TileSet / TileMap. Aby dodać te elementy do projektu, kliknij przycisk „Dodaj nowy” z przeglądarki treści i szukać „Paper2D”  kategorii : 

Flipbooki służą do sterowania animacją 2D opartą na sprite’ach. Mapy kafelkowe służą do tworzenia scenariuszy 2D przy użyciu zestawów kafelków.
Paper 2D może być używany na różne sposoby:

  • W tworzeniu czystej gry 2D; 
  • W grze 2D z trójwymiarowym tłem; 
  • Jako elementy 2D w grach 3D; 

W nadchodzących artykułach stworzymy przykład czystej gry 2D, używając tylko Sprites. Następnie pojawi się artykuł o kineografie i artykuł o TileSet / TileMap.


W tej grze gracz kontroluje czerwony samochód i musi unikać innych samochodów na ulicy. Poniższy obrazek pokazuje, jak będzie wyglądała gra.

Utwórz nowy pusty projekt bez korzystania ze “Starter Content:

Utwórz nowy poziom (New level) i wybierz „Empty Level”:

Zapisz poziom pod nazwą „Paper2dLevel”. Wejdź do menu „Edycja-> Ustawienia projektu…”, a następnie wybierz opcję „Mapy i tryby”. W „Default Maps” wybierz poziom „Paper2dLevel”.

Teraz zaimportujmy obrazy, które będą używane w grze. Pierwszy to obraz tła poniżej. Ten obraz ma wymiary 640×480 pikseli.

Zapisz obraz na swoim komputerze. Następnie kliknij przycisk „Importuj” w Wyszukiwarce bibliotek i wybierz obraz. Edytor utworzy teksturę, umieści nazwę tekstury jako „Tło”.


Kliknij teksturę prawym przyciskiem myszy i wybierz opcję „Utwórz Sprite” znajdującą się w podmenu „Działania Sprite”:

Zostanie utworzony Sprite o nazwie „Background_Sprite”. Kliknij dwukrotnie utworzony duszek, aby otworzyć edytor sprite:

Kliknij, aby powiększyć

Poszukaj właściwości „Piksele na jednostkę” i sprawdź, czy jest to „1,0”. Jeśli tak nie jest, zmień to. Zapisz, a następnie zamknij edytor duszków.
Poniższy obrazek posłuży do stworzenia dwóch Sprite’ów reprezentujących samochody w grze. Zapisz obraz i zaimportuj do edytora.

Kliknij prawym przyciskiem myszy utworzoną teksturę i wybierz opcję „Zastosuj ustawienia tekstury Paper2D” z podmenu „Sprite Actions”:

Następnie wybierz opcję „Wyodrębnij sprites” z podmenu „Działania spriteów”:

Redaktor spróbuje zidentyfikować Sprite na podstawie przejrzystości obrazu. Jeśli jest poprawny, po prostu kliknij przycisk „Wyodrębnij” w oknie pokazanym poniżej. Jeśli jest to niepoprawne, możesz zmienić właściwość „Tryb wyodrębniania spriteów” na „Siatka” i ręcznie skonfigurować rozmiar sprite’ów.

Zmień nazwę duszka czerwonego samochodu na „PlayerCar_Sprite”, a sprite’a niebieskiego samochodu na „EnemyCar_Sprite”. Otwórz te duszki w Edytorze sprite’ów i potwierdź, że właściwość „Piksele na jednostkę” ma wartość „1,0”.

Tło wzdłuż osi X i Z umieścimy w następujący sposób:

Rozmiar obszaru gry jest równy rozmiarowi tła, które ma 640×480. Granice ulic określają wartości X = 160 i X = 480.

Przeciągnij „Background_Sprite” i upuść w dowolnym miejscu w oknie roboczym edytora. Edytor automatycznie tworzy „PaperSpriteActor”. Zmień wartość „Lokalizacja” tła na (X = 320, Y = 0, Z = 240). Ta pozycja reprezentuje środek Sprite, tak że lewy dolny róg Tła pozostaje na początku (X = 0, Y = 0, Z = 0), jak na powyższym obrazku.
Kliknij prawym przyciskiem myszy w rzutni i wybierz opcję „Umieść aktora -> Aktor kamery”, aby dodać kamerę:

Ta kamera ustawi widok gry. Zmień wartość „Lokalizacja” kamery na (X = 320, Y = 500, Z = 240). Obróć kamerę o -90º w osi Z, tak aby wskazywała na Tło. Poniższy obrazek przedstawia kamerę w edytorze z podglądem sceny przechwytywanej przez kamerę.

We właściwościach kamery zmień „Tryb projekcji” na „Ortograficzny”. Ustaw „Szerokość orto” na 640 iw polu „Współczynnik proporcji” kliknij pole kombi i wybierz 640×480. We właściwości „Automatycznie aktywuj dla gracza” kliknij pole kombi i wybierz „Gracz 0”, aby była to kamera używana w grze. Ten obraz przedstawia właściwości aparatu.

W następnych artykułach stworzymy schematy, które są częścią gry.


Źródło:https://romeroblueprints.blogspot.com/2015/06/paper-2d-game-sprites-and-camera.html

Odtwarzanie dźwięków w Blueprints

Efekty dźwiękowe i muzyka muszą być w formacie „.WAV”, aby można je było zaimportować do silnika Unreal Engine 4. Aby zaimportować, po prostu kliknij przycisk „Importuj” w przeglądarce zawartości i wybierz plik „.WAV”. Po zaimportowaniu tworzy element typu „Fala dźwiękowa”, który można już wykorzystać w grze.

Aby tworzyć złożone dźwięki, które można dynamicznie modyfikować podczas gry, musisz stworzyć „Sound Cue”. Istnieje edytor „Sound Cue”, który ma wiele akcji, które pozwalają łączyć kilka „Sound Wave” w jedną „Sound Cue” z interesującymi efektami. Istnieje prosty sposób na odtworzenie dźwięku w Blueprints. Po prostu użyj akcji „Odtwórz dźwięk w miejscu”:

W tej akcji wybierz w combobox dźwięk do odtworzenia. Ten dźwięk może być „falą dźwiękową” lub „wskazówką dźwiękową”. W parametrze „Lokalizacja” można wykorzystać pozycję Aktora względem dźwięku. Wyobraź sobie, że powyższy przykład to schemat jakiegoś rodzaju materiału wybuchowego. Kiedy gracz dotknie materiału wybuchowego, dźwięk zostanie odtworzony w miejscu, w którym znajduje się Schemat.

Jako podkład muzyczny lub dźwięki poziomu możemy wykorzystać aktora typu „ AmbientSound ”. Jako przykład utworzymy podkład muzyczny za pomocą Sound Wave „Starter_Music01” z Starter Content, który znajduje się w folderze „StarterContent / Audio”:

Przeciągnij falę dźwiękową „Starter_Music01” i upuść w dowolnym miejscu na poziomie. Edytor automatycznie utworzy aktora typu „AmbientSound”:

W zakładce „Szczegóły” można zmienić używany dźwięk i ustawić, czy ma być używane „Przestrzenność” i „Tłumienie”. „Przestrzenność” pozycjonuje dźwięk w przestrzeni 3D. „Tłumienie” określa, w jaki sposób dźwięk słabnie lub zatrzymuje się, gdy odtwarzacz oddala się od miejsca, w którym znajduje się źródło dźwięku. W przypadku podkładu muzycznego nie jest konieczne „Spatialization” ani „Attenuation”.

Najlepszym sposobem na kontrolę nad dźwiękiem i muzyką jest użycie „ Komponentu audio ” w Planach. Jako przykład wyobraź sobie, że mamy dwie piosenki. Jedna to muzyka odtwarzana podczas gry, a druga to muzyka zwycięstwa, odtwarzana po osiągnięciu celu gry.

Aby dodać piosenkę, kliknij przycisk „Dodaj komponent” w schemacie i wybierz „Audio”. Utwórz dwa „komponenty audio” o nazwach „GameMusic” i „VictoryMusic”. Dla każdego z nich w zakładce „Szczegóły” wybierz w polu „dźwięk” utwór, który będzie używany i odznacz właściwość „Automatyczna aktywacja”, aby utwór nie był odtwarzany automatycznie.

Utworzono wydarzenie niestandardowe o nazwie „Zwycięstwo”, które należy wywołać, gdy cel gry zostanie osiągnięty. Poniższy obrazek przedstawia przejście między utworami:

„GameMusic” uruchamia się na początku gry. Po wywołaniu zdarzenia „Victory” używamy akcji „Fade Out”, aby stopniowo zmniejszać głośność „GameMusic”, aż do zatrzymania w ciągu 2 sekund. Akcja „Fade In” stopniowo zwiększa głośność „VictoryMusic”, aż do osiągnięcia normalnej głośności w ciągu 2 sekund.


Źródło:https://romeroblueprints.blogspot.com/2015/06/playing-sounds-with-blueprints.html

Akcje Blueprints w HUD

Ten artykuł jest kontynuacją artykułu „ Rysowanie HUD z UMG ”.
Dodajmy akcje do schematu widżetu „UMG HUD”, który został utworzony w poprzednim artykule, a także w schemacie „Sedan”, który przedstawia samochód sterowany przez gracza w szablonie „Vehicle”.

Otwórz schemat widżetu „UMG_HUD” i przejdź do trybu „Wykres”. W tym artykule utworzymy 3 funkcje, aby uzyskać wartości prędkości, biegu i paliwa. Utwórzmy zmienną odnoszącą się do odtwarzacza samochodowego i tablicę „pędzli”, aby zachować obrazy przedstawiające poszczególne biegi samochodu. Na końcu tego artykułu zakładka „MyBlueprint” w „UMG_HUD” wygląda następująco:

Zacznij od utworzenia zmiennej „PlayerSedan”. Należy do typu „Sedan”, który jest schematem stworzonym dla szablonu „Pojazd”. Zainicjalizujmy tę zmienną przy zdarzeniu „Construct” w „UMG_HUD” w ten sposób:

W trybie „Projektant” kliknij element tekstowy zawierający wartość szybkości. Na karcie „Szczegóły” kliknij przycisk „Bind” obok właściwości „Text” i wybierz „Create Binding”, aby edytor utworzył nową funkcję.

Zrobiono to w celu powiązania wartości „Text” z wartością zwracaną przez funkcję. Zmień nazwę utworzonej funkcji na „GetSedanSpeed” i umieść następujące akcje:

W Planie „Sedan” znajduje się zmienna o nazwie „Speed ​​Display String”, która zawiera wartość prędkości i litery „KM / H”.

Blok bez nazwy na powyższym rysunku jest konwerterem typu „String” na typ „Text”. Te konwertery są tworzone automatycznie przez edytor po utworzeniu połączenia między dwoma typami.

To wszystko, co należy zrobić, aby poprawnie wyświetlić prędkość. Teraz dokonaj niezbędnych korekt, aby wyświetlić bieg.


Utwórz zmienną o nazwie „GearBrushes” typu „Slate Brush” i kliknij ikonę obok typu zmiennej, aby przekształcić ją w tablicę . Typ „Slate Brush” został stworzony specjalnie dla UMG.

Na karcie „Szczegóły” zmiennej, w sekcji „Wartość domyślna”, dodaj 7 elementów do tablicy. Dla każdego elementu wybierz obraz przedstawiający jedno z kół zębatych. Te obrazy musiały zostać zaimportowane jako tekstury w poprzednim artykule . Użyj następującej kolejności:

  • 0: bieg neutralny;
  • 1 do 5: Użyj równoważnego sprzętu;
  • 6: bieg wsteczny;

W trybie „Projektant” kliknij element „Obraz” reprezentujący koło zębate. Na karcie „Szczegóły”, w kategorii „Wygląd”, we właściwości „Pędzel”, kliknij przycisk „Powiązanie”, a następnie w „Utwórz powiązanie”. Zmień nazwę utworzonej funkcji na „GetSedanGear”.

Użyjmy funkcji będącej częścią planu „Sedan” o nazwie „GetCurrentGear”. Ta funkcja zwraca wartość całkowitą reprezentującą bieżący bieg. Jeśli wartość wynosi zero, to bieg neutralny. Jeśli wartość jest ujemna, oznacza to, że pojazd jest na biegu wstecznym.

Funkcja „getSedanGear” ma następujące działania:

Utworzono zmienną całkowitą o nazwie „BrushIndex”, aby zachować pozycję w tablicy klasy Brush, która zostanie zwrócona. Jeśli wartość biegu jest ujemna to wartość wskaźnika tablicy wynosi 6, czyli położenie obrazu biegu wstecznego. Jest używana akcja „Get”, aby zwrócić poprawny obraz tablicy „GearBrushes” zgodnie z wartością indeksu „BrushIndex”.

Zróbmy więcej poprawek, aby móc uruchomić próbkę. Następnie dokonamy niezbędnych zmian, aby uwzględnić zużycie paliwa w grze.
Otwórz Blueprint „Sedan”, poszukaj zdarzenia „BeginPlay” w „EventGraph”. Na początku zdarzenia dodaj dwie akcje, które utworzą instancję „UMG_HUD” i dodadzą ją do widoku.

W edytorze poziomów kliknij przycisk „Ustawienia” znajdujący się na górnym pasku i wybierz opcję „Ustawienia świata”. W kategorii „GameMode” zmień właściwość klasy HUD na klasę „HUD” zamiast „VehicleHUD”. W ten sposób nie pojawi się stara wersja HUD utworzona przez szablon. Dzięki tym zmianom próbkę można uruchomić, aby zobaczyć, jak nowy HUD pracuje z prędkością i biegiem.

Zostawiłem paliwo na później, ponieważ wprowadzimy pewne zmiany w Blueprint „Sedan”. Będzie to świetna okazja, aby przećwiczyć różne koncepcje schematów, które widzieliśmy do tej pory.

Otwórz plan „Sedan” i utwórz nową zmienną o nazwie „Paliwo” typu „Float”. Zaznacz opcję „Edytowalne” i wybierz „Wyświetl” jako kategorię zmiennej. W ten sposób pozostaje razem z innymi zmiennymi używanymi w HUD. U dołu zakładki „Szczegóły” zmiennej „Paliwo” wprowadź domyślną wartość „1,0”, która reprezentuje pełny zbiornik. Poniższy obrazek przedstawia zmienną „Paliwo”.

Dzięki tej nowej zmiennej utworzonej w Blueprint „Sedan” możemy sfinalizować niezbędne zmiany w schemacie widżetu „UMG_HUD”. W trybie „Projektant” w „UMG_HUD” kliknij element „ProgressBar”, który reprezentuje wskaźnik paliwa. Na karcie „Szczegóły”, w kategorii „Wygląd”, we właściwości „Procent”, kliknij przycisk „Powiązanie”, a następnie w „Utwórz powiązanie”. Zmień nazwę utworzonej funkcji na „GetSedanFuel”.

Oto treść funkcji „GetSedanFuel”:

Powrót do planu „Sedan”. Stwórzmy funkcję o nazwie „UpdateFuel”. Ta funkcja otrzyma jako parametr wejściowy wartość „AxisValue” reprezentującą ruch do przodu i do tyłu w sterowaniu lub klawiaturze.

Funkcja ma parametr wyjściowy o nazwie „ThrottleValue”, który reprezentuje przyspieszenie pojazdu. Ta funkcja odpowiada za zmniejszenie ilości paliwa. Jeśli nie ma już paliwa, wartość „ThrottleValue” będzie wynosić zero, uniemożliwiając samochodowi jazdę.
Utwórz nową funkcję o nazwie „UpdateFuel” w planie „Sedan”:

W zakładce „Szczegóły” funkcji „Aktualizuj paliwo” utwórz parametr wejściowy „AxisValue” typu „Float” i parametr wyjściowy „ThrottleValue” typu „Float”.

Otwórz funkcję „UpdateFuel” w edytorze. Zwróć uwagę, że w zakładce „Mój plan” pojawia się nowa kategoria o nazwie „Zmienne lokalne”. Zmienna lokalna istnieje tylko w funkcji, w której została utworzona. Utwórzmy lokalną zmienną o nazwie „Throttle” typu „Float”, aby pomóc w logice funkcji „UpdateFuel”.

Funkcja „UpdateFuel” ma następujące działania:

Jeśli wartość parametru „AxisValue” wynosi zero, oznacza to, że gracz nie naciskał kontrolki ani klawiatury, aby ruszyć samochodem do przodu lub do tyłu. Funkcja sprawdza, czy wartość „AxisValue” jest różna od zera, a zmienna „Fuel” jest większa od zera. Jeśli to prawda, następuje normalne przyspieszenie i paliwo spada. W przeciwnym razie przyspieszenie wynosi zero. Ta funkcja będzie nazywana każdym tikiem . Umieśćmy wywołanie tej funkcji w zdarzeniu „InputAxis MoveForward” planu „Sedan” poniżej.

Zdarzenie „InputAxis MoveForward” z funkcją „UpdateFuel” stało się:

To była ostatnia modyfikacja wymagana do ukończenia nowego interfejsu.


Źródło:https://romeroblueprints.blogspot.com/2015/04/the-blueprints-actions-of-hud.html