Jakie składowanie danych silnika gier 2D top-down shooter?

Jakie składowanie danych silnika gier 2D top-down shooter?
dawciobiel
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 66
0

Tworzę open-source silnik do budowania gier 2D top-down shooter. Nie jest to gra o konktetnych ściśle określonych wymaganiach. A więc musi być tworem w pewnych granicach uniwersalnym.

Przyjmuje za niezmienny pewnik taki model podstawowy:

WEAPON

  • AMMO_BOX
  • PROPERTIES

AMMO_BOX

  • PROJECTILE
  • PROPERTIES

PROJECTILE

  • PROPERTIES

Po co w tym cały dobrobycie AMMO_BOX?
Magazynek na podstawie swoich właściwości generuje pocisk. Silnik przemieszcza pocisk z uwzględnieniem jego właściwości. W momencie kolicji z innym obiektem podejmowane są odpowiednie decyzje.
A więc to nie PLAYER zabija, tylko PROJECTILE ma właściwość damage która jest wykorzysywana przez silnik do zmian właściwości obiektu przy kolicji.
Da się planować fabułę, że magazynek typu "bateria" może być używany przy różnych broniach energetycznych (Rail Gun, Plasma Gun).

Właściwości obiektu
Jest ich wiele a każda gra na tym silniku może dodawać własne, więc będzie możliwość rozszerzania funkcjonalności samego silnika.

Ideowy przykład:

Kopiuj
{
    "name": "M9 Pistol",
    "allowedAmmoCategories": ["9MM"],
    "stats": {
      "speed" : 500,
      "fireRate": 0.3,
      "spread": 2.0,
      "magazineSize": 15,
      "isAutomatic": false,
      "recoil": 0.5
    }
  }
}

Opis problemu
W docelowej grze właściwości obiektów nie są znane. Obecnie używam struktury katalogów które zawierają konfigi oraz zasoby (grafika, audio). Konfig obiektu to pojedynczy plik .json.
Problem w tym, że im więcej różnych klas obiektów tym więcej zasobów oraz konfigów. Zaczyna się koszmar aby to wszystko ogarnąć, utrzymywać jednakową strukturę i odpowiednio dobrane dane.
Obecnie używam JSON Schema, odpowiednich skryptów do generowania szkieletu konfigów.

Jak to wszystko ogarnać?
Zastanawiam się nad użyciem innej techniki składowania danych.
Pomyślałem o SQL. Na początku brzmi to nieźle jednak dość szybko okazuje się, że nie wnosi to korzyści względem JSON.

Gdzie trzymać konkretne właściwości obiektów?
a) W tabeli encji PROJECTILE kolumna typu BLOB lub JSON która przechowuje różne właściwości.
Nie widzę zalet tego rozwiązania w porównaniu z konfigiem w pliku .json.

b) Stworzenie dodatkowej tabeli PROPERTIES która określa wszystkie właściwości dla każdej klasy obiektu w grze.

Kopiuj
CREATE TABLE property_def (
    id              INTEGER PRIMARY KEY,
    name            TEXT NOT NULL UNIQUE,      -- np. "damage", "weight", "caliber"
    data_type       TEXT NOT NULL,             -- "int", "float", "string", "bool"
    default_value   TEXT
);

Zalety:

Kopiuj
+ Wszystko w jendym miejscu
+ Brak plików konfigów w drzewie katalogów na dysku.

Wady

Kopiuj
- Brak możliwości szybkiej walidacji właściwości obiektu.
- Zarządzanie/edycja możliwe tylko za pomocą zapytań SQL i odpowiednich narzędzi.
- Brak możliwości szybkiego podgądu bez użycia dedykowanych narzędzi.
- Katalogi z zasobami w dalszym ciągu obecne na dysku, tyle, że bez kofnigów.

c) Problem ze składowaniem i edycją właściwości przerzucić na autora gry.


Czy znacie gotowe narzędzia do tworzenia obiektów w tego typu grach?

dawciobiel
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 66
0

Dochodzę do wniosku, że SQL nie ma sensu. Jest to przenoszenie problemu do wnętrza tabeli. Optymalne i skalowalne rozwiązanie:

Format

  • JSON
  • JSON Schema

Struktura

  • Jeden folder = jeden asset [1]
  • prefab / extends [2]

Runtime

  • loader - buduje obiekty
  • registry (weapon/ammo/projectile)

Dodatkowe narzędzia które trzeba stworzyć lub dostosować istniejące

  • prosty editor (Qt)
  • skrypty (python, bash) tworzące szkielet dla pojedynczego asset-u
  • walidator CLI

[1] Dziedziczenie / prefab

Zamiast powielać JSON użyć dziedziczenia właściwości i nadpisywać tylko wybrane:

Kopiuj
{
  "extends": "base_pistol",
  "stats": {
    "speed": 300
  }
}

[2] Komponenty zamiast sztywnej struktury

Zamiast:

WEAPON -> AMMO_BOX -> PROJECTILE

rozważam:

Entity

  • WeaponComponent
  • AmmoComponent
  • ProjectileEmitterComponent

Co prowadzi do ECS-lite.

Komponenty

Kopiuj
Entity (broń)
 ├── WeaponComponent
 ├── MagazineComponent
 ├── ProjectileEmitterComponent

A pocisk:

Kopiuj
Entity (pocisk)
 ├── TransformComponent
 ├── VelocityComponent
 ├── DamageComponent
 ├── CollisionComponent

Oczywiśćie prośba o komentarz.

LukeJL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 8528
2

Zwróć uwagę na to, że format, w jakim tworzysz/edytujesz te dane, to niekoniecznie musi być ten format, z którego korzysta gra. Np. możesz wziąć JSON i przekonwertować do jakiegoś innego formatu (np. binarnego). Albo odwrotnie - możesz zrobić jakiś edytor graficzny, żeby użytkownik mógł edytować wizualnie i JSON generować z automatu itp.

Sam JSON możesz też generować programistycznie np. w JS jako zwykłe obiekty, więc masz dostęp do całej logiki języka programowania i np. zamiast robić w silniku wsparcie dla "extends", możesz to zrobić na etapie konfiga po prostu kopiując właściwości z jednego obiektu do drugiego:

Kopiuj
const base_pistol = {
   kind: "bullets",
};
const super_pistol = {
    ...base_pistol, // zamiast "extends": "base_pistol",
    damage_bonus: 2,
}

a potem dopiero konwertować to do JSON. Czyli też unikasz "inner platform effect". Bo jak masz config w JSON i edytujesz w JSON, to zaraz może ci przyjść ochota np. na dorobienie dziedziczenia, pętli, warunków, importów z innych plików itp. A tak masz to na poziomie builda, a silnik nie musi o tym myśleć.

Tak samo, jeśli do czegoś byłoby potrzebne ci SQL, to też może to być detal implementacyjny, a niekoniecznie użytkownik musi sam ten SQL pisać.

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10297
4

Jeśli mogę Ci dać radę, nie twórz silnika "na pusto". Tzn nie pisz go i nie wyobrażaj sobie jak to będzie użyte. Niezbędne jest, żeby zrobił sobie testowe gry przy użyciu tego silnika które są integralną częścią projektu. Mogą być pewnego rodzaju "demo" Twojego silnika. Takich gier demo może być oczywiście więcej. Moim zdaniem każda jedna funkcja czy opcja w Twoim silniku powinna mieć jakąś demo grę która to wykorzystuje.

Chronisz się w ten sposób przed tworzneiem rozwiązań które są niepotrzebne albo takich które wręcz działają źle.

dawciobiel
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 66
1
Riddle napisał(a):

Jeśli mogę Ci dać radę, nie twórz silnika "na pusto". Tzn nie pisz go i nie wyobrażaj sobie jak to będzie użyte. Niezbędne jest, żeby zrobił sobie testowe gry przy użyciu tego silnika które są integralną częścią projektu. Mogą być pewnego rodzaju "demo" Twojego silnika. Takich gier demo może być oczywiście więcej. Moim zdaniem każda jedna funkcja czy opcja w Twoim silniku powinna mieć jakąś demo grę która to wykorzystuje.

Chronisz się w ten sposób przed tworzneiem rozwiązań które są niepotrzebne albo takich które wręcz działają źle.

Zgadzam się z tobą. Musicie jednak widzieć, że treść tego wątku w momencie zakładania była bardzo mocno ograniczona celem zapytania tylko o konkretną kwestie merytoryczną. Co do tego silnika to prawda jest taka, że on de facto już działa od jakiegoś czasu jako całość [1]. Jednak w pewnym momencie tworzenia dochodziło do mniejszych bądź większych refaktoryzacji kodu. Potrzeba poważnego przebudowania modelu danych wiązała się zarówno z

  • koszmarem dziesiątków plików konfiguracyjnych w drzewie katalogów
  • organizacją architektury wyświetlania obiektów

Co do konkretnych testów funkcjonalności to tworzę odpowiednią mapę która ma testować funkcjonalność.
Oczywiście mapy również są zaprojektowane aby to konfig decydował. Czyli de facto przy tworzeniu silnika wyszedłem z założenia, że aby zbudować gre z jego udziałem wystarczy skonfigurować "kilka" konfigów. I tak to obecnie działa. Dochodzi oczywiście do tego kwestia textur dla poszczególnych obiektów. Ale wymyśliłem obejście tego problemu:
a) jeżeli nie ma tekstur to da się w konfigu obiektu włączyć opcje aby był on przez silnik rysowany (jako kwardrat, trójkąt itp.)
b) jeżeli jest tekstura to za pomocą odpowiedniego przełącznika w konfigu obiektu silnik ma wyświetlać tekstury.

Co do opcji b) jest też da się to rozbić na dwa podpunkty. Wyświetlany obiekt może mieć tekstury (jeden bądź więcej plików graficznych) ale może mieć te pliki również opisane jako "atlas". Z atlasem związane są kwestie techniczne, że podnoć tak jest szybciej, lepiej, tere fere... . Ale jednak taki atlas trzeba wygenerować. Więc też się zastanawiam nad docelowym rozwiązaniem.

Wiesz, muszę to w sobie przegryźć i się zastanowić dłużej nad kilkoma kwestiami oraz jak je pogodzić. Wyjść z łatwości tworzenia mapy/obiektu dla docelowego odbiorcy czy raczej podejść do problemu aby zrobić to na wyższym poziomie technicznym. Na przykład docelowo można by zaprojektować aby poszczególny obiekt to była skompresowana paczka z hierarchią własnych zasobów w środku. Albo najlepiej stworzyć edytor zasobów dla tego silnika. Edytor sam docelowo eksportował by twór do odpowiedniej paczki. Przy tym rozwiązaniu do tworzenia obiektu można by użyć dostarczonego edytora ale równie dobrze jak ktoś woli - to sobie tworzy paczkę sam według odpowiedniej konwencji.

[1] Obecnie dość mocno refaktoryzuje całość ale jeżeli się uda to postaram dzisaj wystawić jakąś prezentacje lub wersję demo do pobrania i uruchomienia. No, co prawda z dość mocno kiepskimi (darmowymi) teksturami ale jednak. Co prawda mam pewną fajną paczkę tekstur dla "potworów" ale.. jest w niej zastrzeżenie, że ona jest darmowa dla użytku ale tylko do tworzenia mod'ów innej istniejącej grze. Co prawda chodzi mi pogłowie lekka ich edycja celem "zalegalizowania" użytku jako własne - no ale zobaczymy z czasem jak to wyjdzie.
A działanie od "jakiegoś czasu" to z tego co widzę, to repozytorium założyłem 12.kwietnia. A więc efekt działania widać było troche później.

LukeJL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 8528
2
dawciobiel napisał(a):

Albo najlepiej stworzyć edytor zasobów dla tego silnika.

No to możesz zrobić edytor wizualny, który by zapisywał dane do folderu z plikami JSON (pozwalając również na ręczną ich edycję) oraz zasobami, natomiast silnik mógłby korzystać bezpośrednio z tych plików, ale mógłbyś zrobić też krok pośredni np. serializację do jakiegoś formatu binarnego przyjaznemu silnikowi albo cokolwiek innego.

W sensie, że format edytora to nie musi być format silnika.

Chociaż wtedy miałbyś dodatkowy krok builda, a jakby ktoś tweakował coś w edytorze, to potem konieczność czekania na zbudowanie by spowalniało użykownikowi feedback, bo później by zobaczył zmiany.

Ale jednak taki atlas trzeba wygenerować. Więc też się zastanawiam nad docelowym rozwiązaniem.

Użytkownik może widzieć to jako ileś obrazków i tak zapisywać, natomiast edytor mógłby tworzyć jeden duży plik graficzny i rysować tam te obrazki i zapisywać.

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7083
2
LukeJL napisał(a):
dawciobiel napisał(a):

Ale jednak taki atlas trzeba wygenerować. Więc też się zastanawiam nad docelowym rozwiązaniem.

Użytkownik może widzieć to jako ileś obrazków i tak zapisywać, natomiast edytor mógłby tworzyć jeden duży plik graficzny i rysować tam te obrazki i zapisywać.

Brzmi jak obsługa atlasów, która jest już do dyspozycji w Unity:

@dawciobiel: mógłbyś oprzeć swój silnik o inny silnik, który ma już wypracowany dev-friendly workflow.

Twoje obiekty w Unity mogą mieć własne edytory, albo skorzystać ze standardowej edycji pól klasy wyprowadzonych na zewnątrz.

Obiekty można ze sobą łączyć. Prefab (gotowy obiekt z komponentami) albo ScriptableObject (same dane/parametry) można podpiąć do innego obiektu i w skryptach tego obiektu się do takiego Prefaba odnieść. To daje dużą elastyczność w pracy z silnikiem i stwarza możliwości, które w dotychczasowych poczynaniach nie były takie oczywiste.

Ja np. mam w grze pocisk, do którego podpinam skrypt poruszający pociskiem. I może to być linia prosta, albo też samonaprowadzanie. Nie muszę tego zapisywać nigdzie jakoś specjalnie, po prostu przesuwam plik C# z "linear moverem" na prefab pocisku. Ten mover może mieć pole, w którym ustawiamy prędkość pocisku.
Taki workflow tworzenia pocisku udokumentujesz i masz sprawę załatwioną.
Bez tworzenia jakichś sztywnych ram, w które twórca musi się wpasować.

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12312
2
LukeJL napisał(a):

W sensie, że format edytora to nie musi być format silnika.

Dokładnie, choć IMO nie tyle nie musi, co wręcz nie powinien.

Edytor korzysta z innych formatów plików niż sama gra. Po pierwsze, dzięki temu edytor może w plikach przechowywać metadane, które są przydatne dla samego edytora, ale gra ich nie potrzebuje do niczego. Po drugie, edytor może przechowywać pliki projektu w taki sposób, aby każdy zasób był osobnym plikiem (co ułatwia implementację edytora), natomiast gra może operować na pliku zbiorczym.

Np. edytor przechowuje każdy dźwięk w formie osobnego pliku, tak aby można nim było wygodnie zarządzać (przenosić, usuwać itd.) oraz odpalać w zewnętrznych aplikacjach (np. Audacity), natomiast na potrzeby gry, wszystkie pliki dźwiękowe pakowane są do jednego, zbiorczego pliku, ze słownikiem offsetów do buforów konkretnych dźwięków. To samo w przypadku tekstur (luźne pliki PNG dla edytora, bulk file z atlasami dla gry), modeli, światów (map) itd.

Zalety zbiroczych binarek:

  • brak metadanych, których gra i tak nie używa,
  • brak konieczności parsowania danych tekstowych, co bezsensownie ssie CPU,
  • mały rozmiar, maksymalnie przyspieszający czas ładowania danych do RAM/VRAM,
  • mała liczba plików instalacji gry,
  • bonus: utrudniony data mining, kradzież assetów, niechciane modowanie (jeśli na tym ci zależy).

Tego typu podejście sam stosuję, czyli edytor (IDE) operuje na pojedynczych plikach i zapisuje mnóstwo metadanych, natomiast gra operuje na małej liczbie binarnych plików amorficznych, zawierających całe zestawy danych — po jednym pliku dla zestawu fontów, kursorów, tekstur (atlasów), dźwięków, map, modeli, animacji itd. Gra ma zapierdzielać i używać jak najmniejszej ilości danych, edytor może być wolniejszy i operować na dowolnie dużych zbiorach plików i metadanych (byle się w RAM-ie zmieściły).

dawciobiel
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 66
1

Tak w bardzo mocnym skrócie i uproszczeniu, a do tego dość ogólnie to tak to się przedstawia jak napisałem poniżej. Zaznaczam, że bardzo mocno staram się skracać i pisać ogólnie. Przy czym poza kodem tworze jednocześnie dokumentacje, konfigi, grafikę, itp. itd. Dlatego dość długo się schodzi. Tym bardziej, że .. eh no zacząłem refaktoryzacje renderera, potem trzeba poprawić kwestie konfigów, potem trzeba jednak stworzyć profesjonalny config loader, potem ... - no i się schodzi. Ale dzięki temu, że mam dość ambitne podejście do tematu myśle, że nawet nieźle to wychodzi. Niestety na chwile obecną nie chce jeszcze udostępniać kodu źródłowego ze względu na to, że wprowadzam sporo poprawek i zmian w architekturze.

Jeżeli chodzi o silnik to wybrałem podejście ECS Lite.
Silnik posiada konfigi:

Kopiuj
ls -1 assets/data/configs/

engine.toml
game.json
input.json
input.md
physics.toml
rendering.toml
session.toml

Gra posiada konfigi:

  • gry

  • wielu map

    • mapa posiada rozmieszczenie obiektów (prefabs)
      • Każdy obiekt na mapie to de facto nazwa prefarb-u wraz z właściwością "role" która może być np. ( PLAYER | ENEMY | NEUTRAL | AMMUNITION | OBJECT` | .... )

    I teraz każda taka encja to konfig typu component który jest zapisany w .json . Dla jednej encji może to jeden konfig lub kilka ze sobą powiązanych. Ze względu na logiczny podział elementów (cechy obiektu, parametry dla renderera, itp.).

Konfigi wczytywane są za pomocą specjalnego serwisu. Który to wczytuje konfig, parsuje, mapuje, ładuje wskazane przez konfig zasoby, tworzy obiekt Java.

Wracając do map. Mapa to defacto odpowiedni katalog z podkatalogami (zasoby) oraz konfigami. Konfigi mapy to:

Kopiuj
config.json -  parametry mapy (name, description, ...) oraz właściwości (difficult level, ...)
map.tmx - właściwa mapa składająca się wielu warstw (background, obiekty typu collidable, obiekty z gry, triggery). 

Obiekt w map.tmx to tylko:

  • name of prefarb (np.: "enemy/zombie/runner", "character/soldier")
  • "role= { PLAYER | ENEMY | NEUTRAL | AMMUNITION | OBJECT | .... }"
  • współrzędne startowe X:Y
  • i być może jakieś dodatkowe parametry których na pamięć nie znam.

A więc silnik wczytuje mape gry, z jej konfiga "map.tmx" wyciąga listę obiektów których konfigi wczytuje, przetwarza.... i tworzy z nich obiekty.
Sam plik mapy "map.tmx" tworzę z użyciem gotowego, zewnętrznego edyora Tiled Map Editor. De facto za jakiś czas stworzę taki edytor do tworzenia obiektów w tej grze.
Ten konfig oprócz obiektów zawiera oczywiście rozmieszczenie ścian itp.

Oczywiście do całego projektu podpięty jest logger (SLF4J + logback).

Config Loader.
Konfigi w grze mają różne formaty zależnie od zastosowań. Bo jak poszechnie wiadomo zarówno ".toml" jak i ".json" mają swoje mocne i słabe strony.
Zwykłe konfigi (engine.toml, renderer, ...., session.toml) - są jako TOML. Tutaj ma być jasna, czytelna dla człowieka struktura, możliwość występowania komentarzy.
Konfigi od encji (poszczególnych obiektów) to już JSON. Przy JSON za pomocą pewnych zabiegów da się wstawiać komentarze ale... ale i tak później z takimi komentarzami mogą być problemy. Nie chce zaczynać dyskusji na temat dlaczego ale chodzi o serializacje/deserializacje/mapowanie.
Do konfigów tworzę jednocześnie JSON Schema - aby jasno określić co każdy rodzaj konfiga musi i co może zawierać.
Poza tym tworze też skrypty (python, bash) które są walidatorami konfigów. A te walidatory (python) można podłączyć na GitHub pod CD/CI - więc.... jest dobrze.

Oczywiście tworzę też "docs/tasks.md" - czyli listę zadań do wykonania.
Jest plan aby tą liste zamienić na listę zadań z wykorzystaniem Issues na GitHub Issues. Ale z racji, że na chwile obecną jestem jedynym developerem tego projektu to nie miał bym korzyści z przejścia na Issues list.

Hm... co tam jeszcze. Aaaaa przedmówca wspomniał już dwa razy o kwesti:

  • kompilacji textur, animacji

Faktycznie, da się to zrobić. Być może nawet w przyszłości będzie to wprowadzone. Jednak na chwile obecną odkładam temat na dalszy plan.

  • atlas tekstur
    W poprzedniej wersji (sprzed obecnie wykonywanej refaktoryzacji) jeden obiekt ("role=ENEMY, prefab=spider_robot/yellow") miał nawet atlas zrobiony, zaimplementowany i to nawet działało.
    W czym jednak problem, że nie każdy obiekt używał atlasu? A no w tym, że dla każdego obiektu trzeba poświęcić:

    • znalezienie tekstur
    • przegranie tych tekstur i zmiana nazwy poszczególnych plików na nazwy zgodne z konwencją. Wiem, w konfigu można by podawać nazwy oryginalne no ale.. jednak w konwencji jest potem znacznie czytelniej. A do tego skrypty tworzą gotowe konfigi z poprawnymi śćieżkami do zasobów. No! Z czasem powstanie edytor obiektów to problem przestanie istnieć.
    • stworzenie struktury podkatalogów na zasoby (he he, bez paniki do tego też jest już gotowy skrypt)
    • znalezienie odpowiednich dźwięków w formacie .wav - a do tego z konkretnymi parametrami, bo jak się okazuje jednak zdarzają się problemy.
    • umieszczenie dźwięków w podkatalogach i zmiana nazw plików na nazwy wg konwencji.
    • Wygenberowanie konfiga oraz późniejsza jego edycja
  • Kwestia tworzenia paczek, gdzie:
    jedna paczka = pojedyncza mapa z zasobami
    jedna paczka = jeden obiekt z zasobami

Fajna sprawa taka paczka tylko.. po co? Jeżeli gra taka jak na przykład Quake 1-3, Diablo, Starcraft skłąda się z tysięcy plików to wtedy paczka jako jeden plik zawierający w sobie wszystkie zasoby - ma sens. Ale tutaj? Jeden obiekt na chwile obecną to około 10 - 40 plików.
Ręczne tworzenie paczki faktycznie oraz implementowanie jej użycia przez silnik jest faktycznie przerostem formy nad treścią. Jednak jeżeli stworzył bym edyor obiektów no to wtedy miało by to może jakiś sens. Chociaż.. też niewielki. Bo po co ktoś miał by z kimkolwiek kopiować i wymieniać się takimi paczkami obiektami/mapami? Bez sensu.

Troche się z tym schodzi.

Konfig od obiektu może być w różny sposób skonfigurowany. I zależnie czy obiekt ma być "rysowany" przez silnik czy renderowany za pomocą tekstur (pliki lub atlas) - wszystko można skonfigurować.

W skrócie mówiąć wszystko da się skonfigurować, sparametryzować.

Oczywiście jest kilka kwestii które jescze muszę zaprojektować, a które nawet nie są zaczęte.
Na przykład:
Gra składa się z wielu map.

  1. W jaki sposób nastepuje przejście między różnymi mapami w grze?
  2. Czy silnik ma umożliwiać łatwe tworzenie w grze fabuły?
  3. Tworzenie dialogów z postaciami w grze
  4. Tworzenie interakcji w grze. Obecnie zaimplemenotwałem to na zasadzie triggerów. Czyli gracz wszedł na obszar mapy, albo gracz znajduje się na obszarze mapy i nacisnął przycisk "AKCJI".

Dobra, idę zapalić... przypomnę sobie o czym jeszcze miałem wspomnieć, a jak wrócę to ponownie przeczytam wasze komentarze bo na pewno zapomniałem do czegoś nawiązać w mojej odpowiedzi.


@Spine

Obiekty można ze sobą łączyć. Prefab (gotowy obiekt z komponentami) albo ScriptableObject (same dane/parametry) można podpiąć do innego obiektu i w skryptach tego obiektu się do takiego Prefaba odnieść. To daje dużą elastyczność w pracy z silnikiem i stwarza możliwości, które w dotychczasowych poczynaniach nie były takie oczywiste.

Ja np. mam w grze pocisk, do którego podpinam skrypt poruszający pociskiem. I może to być linia prosta, albo też samonaprowadzanie

Przewiduje możliwość dołączania zewnętrznego skryptu (.lua) z logiką dla obiektu. Ale nie zastanawiałem się szerzej nad zastosowaniem.

Kopiuj
tree -C  assets/entities/characters/template/player/

assets/entities/characters/template/player/
├── animations
├── audio
│   ├── death.wav
│   ├── hit.wav
│   └── idle.wav
│   └── shooting.wav
├── data
│   ├── config.json
│   ├── PROCEDURAL.json
│   └── SPRITE.json
├── particles
│   └── blood.json
├── scripts
│   └── ai_logic.lua
└── sprites
    ├── death.png
    ├── idle.png
    └── walk.png
    └── shooting.png

@Spine
Unity / Edytor
Jak znajdę chwile czasu spróbuje rzucić okiem.

@flowCRANE, @LukeJL
Ten pomysł z edytorem obiektów aby miał własny format przechowywania danych, a do tego różny od formatu przeznaczonego dla silnika - jest faktycznie istotny. W ten sposób edytor eksportował by gotową paczkę w formacie zrozumiałym dla silnika. To słuszna droga.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.