Autor Wątek: Gotowy silnik czy pisanie od podstaw gry do wydania.  (Przeczytany 9622 razy)

Offline koirat

  • Użytkownik

# Czerwiec 28, 2015, 15:37:04
// z tego co piszesz, to ty nie chcesz serializować świata gry, tylko cały stan aplikacji w danym momencie. Wg mnie takie rozwiązanie to overkill, i to niezależy od silnika którego używasz.z
Niech się serializuje chociaż świat, z resztą jakoś sobie poradzę.

Osobiście moim zdaniem każdy engine gry powinien mieć taką funkcjonalność jak zapis i load.  Nie wiem co dla ciebie znaczy overkill jeśli ilość zajętej pamięci przez taki save, to uważam że to nie problem. Pierwsza sprawa to przecież nie musimy umieszczać mediów w pliku (chyba że zechcemy - powinna być taka opcja), Druga to że powinniśmy móc wykluczyć niektóre dane z procesu serializacji jak nie chcemy ich serializować, albo utworzyć dla nich surrogaty jeśli te dane możemy w jakiś sposób odtworzyć. Na koniec można dane spakować żeby zajmowały mniej miejsca.


Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline laggyluk

  • Użytkownik
    • http://laggyluk.com

# Czerwiec 28, 2015, 16:59:34
UE4 niby ma wbudowany save, ciekawe jak bardzo bo od czasu do czasu strugam grę z fizyką..

Offline koirat

  • Użytkownik

# Czerwiec 28, 2015, 17:37:52
W Unity3d dawałem jakoś radę zapisać fizykę, UE4 z tego co wiem też używa PhysX więc nie powinno być problemów. Ale sam jestem ciekaw jak to w UE4 działa.

Offline Kos

  • Użytkownik
    • kos.gd

# Czerwiec 28, 2015, 19:00:49
Anyway, dla większości gier takie rozwiązanie jest błędne - zamiast tego powinno się trzymać cały gamestate jako czyste dane, klasy, które mają dane typu pozycja, typ jednostki itd, ale nie są gameobjectami Unity tylko zwykłymi klasami. Takie klasy możesz serializować od ręki, i później na ich podstawie odtworzyć całą scene. Wtedy też kod logiki gry operuje na czystych danych, i nie masz typowego mojo jakie tworzą początkujący userzy Unity, gdy piszą wszystko w gameobjectach i mieszają wartwy logiki z prezentacją itd.

Wow, srsly? W 'poważnym' unity radosne korzystanie z gameobjectów się nie sprawdza i należy wszystko pisać samemu? Jestem nieco zaskoczony.

Dziwię się też że nazywasz to 'mieszaniem warstwy logiki z prezentacją'. Znaczy co, całe Unity to prezentacja, a własny kod to logika? Myślałem że o to chodzi w podejściu komponentowym, że podział odpowiedzialności jest jakby w inną stronę - jedne komponenty od wyświetlania, inne od logiki, a GameObject spina wszystko w całość.

Offline laggyluk

  • Użytkownik
    • http://laggyluk.com

# Czerwiec 28, 2015, 19:12:42
no to żaden sekret że z unity wychodzą takie kwiatki po jakimś czasie użytkowania nie mniej powoli idzie ku lepszemu :P

Offline koirat

  • Użytkownik

# Czerwiec 28, 2015, 20:32:37
Niestety jeśli gruntownie nie przerobią core, co niestety się nie zapowiada, to powolne podążanie w dobrą stronę utknie w minimum lokalnym.

Offline lukaszsa

  • Użytkownik

# Czerwiec 29, 2015, 10:38:20
To jak juz poruszyliscie ten temat to pytanko.
Czyli zapisywanie stanu gry to moze byc jakis duzy problem?
Bo to bedzie po czesci jak w Terrari kafelki beda mialy swoje wlasciwosci, postac rownierz, w grze bedzie rownierz opis sytuacji zwiazanej z oczekiwanym zdarzeniem do ktorego moze byc odliczany czas. Pewna "maszyna stanow relacji NPCow do postaci"... itd.

Offline laggyluk

  • Użytkownik
    • http://laggyluk.com

# Czerwiec 29, 2015, 10:42:59
jeżeli jesteś w stanie sobie wyobrazić mechanizm zapisu i odczyty z pliku stanu owych obiektów to nie :P poprostu unity nie ma wbudowanej magicznej funkcji 'save game' która zrobiła by to za Ciebie

Offline koirat

  • Użytkownik

# Czerwiec 29, 2015, 11:24:11
Zależy jak masz grę zaprojektowaną. Ale zakładam że poza danymi obiektu trzeba jeszcze odbudować relację pomiędzy obiektami, np gdy jeden obiekt przechowuje referencję do drugiego. Jeśli korzystasz z wątków to również trzeba zdawać sobie sprawę że może być to dodatkowy problem.

Zresztą już od pewnego czasu chodzi mi po głowie jak sensownie to rozwiązać, mowa o uniwersalnym systemie zapisu, i przyznam że nie jest to trywialne zadanie.

Offline lethern

  • Użytkownik

  • +1
# Czerwiec 29, 2015, 14:18:00
(na moją wiedzę) Problem z zapisem najpewniej pojawi się przy m.in. wskaźnikach i referencjach - nie da się zserializować wskaźnika, trzeba serializować jako identyfikator, a przy loadzie umieć zamienić go na obiekt. Niby proste, ale ten obiekt musi istnieć, więc problemem może być odpowiednia kolejność loadu lub kolejność tworzenia. Jeśli obiekt A wskazuje na obiekt B, a ten wskazuje na obiekt A, to albo mamy problem (bo nie możemy zalinkować ich ze sobą w czasie konstrukcji - jeden nie będzie istniał gdy tworzymy drugi), albo rozdzielamy wczytywanie-konstruowanie obiektów od wczytywania-podpinania wskaźników (żeby nie mieć problemu z kolejnością ani z wspomnianymi "pętlami"). Dalej, problem wskaźników dotyczy czasem i bardzo prostych rzeczy - małych struktur czy klas, które są dynamiczne i  akurat są wskazywane w kilku miejscach - nie chcemy zapisywać ich wartości, tylko wskaźnik (identyfikator). Jeśli nie mamy automatu, który serializuje zawartość obiektu, jak i "transformuje" wskaźniki na identyfikatory i z powrotem, to może to być sporo roboty. Dalej temat zahacza o dynamiczne funkcje / delegaty / lambdy (jak je zapisywać / identyfikować). Dalej są jeszcze nie-nasze obiekty (3rd party), przy których możemy nie mieć dostępu do środka, żeby móc je zapisać (i nie należy tu myśleć o jednej konkretnej klasie z silnika, możemy potrzebować zapisać stan różnych klas, z różnych bibliotek)
« Ostatnia zmiana: Czerwiec 29, 2015, 14:22:08 wysłana przez lethern »

Offline laggyluk

  • Użytkownik
    • http://laggyluk.com

# Czerwiec 29, 2015, 14:23:29
no tak ale jest to wciąż raczej zagadnienie wspólne dla różnych silników niż konkretnie unity. poprawcie mnie jeśli się mylę i save jest w każdym innym frameworku którego nie próbowałem

Offline komorra

  • Użytkownik
    • Blog naszego teamu (o grze Voxelfield)

# Czerwiec 29, 2015, 15:22:08

Offline lukaszsa

  • Użytkownik

# Czerwiec 29, 2015, 20:38:19
Dziękuję za wyczerpujące odpowiedzi i ciekawą dyskusję.

Qrcze jeszcze długa droga przede mną dopiero jestem w połowie pisania Dokumentu Projektu Gry(język polski jest piękny).

Offline koirat

  • Użytkownik

# Czerwiec 29, 2015, 21:56:18
Można referencjować po unikalnym ID: http://docs.unity3d.com/ScriptReference/Object.GetInstanceID.html
Do identyfikacji podczas zapisu używałem tego RuntimeHelpers.GetHashCode w przypadku własnych obiektów również. Nie ufam niczemu co wydobywa się z silnika Unity3d ;) , między innymi funkcji zwracającej HashCode dla obiektów z UnityEngine która jest  overridowana i zwraca z tego co pamiętam  GetInstanceID (cokolwiek ma ono oznaczać).

Toć to się aż prosi o jakąś kolizję w przypadku użycia słownika.
Jak można pokusić się o zmianę HashCode dla typów referencyjnych jest dla mnie zagadką.

Najgorsze jest jednak to że nie wiem czy przypadkiem nie nastąpi gdzieś sytuacja w którym Unity3d utworzy dwa różne obiektu .NET udające ten sam obiekt, czyli odnoszące się do tego samego obiektu w enginie.

Offline komorra

  • Użytkownik
    • Blog naszego teamu (o grze Voxelfield)

# Czerwiec 29, 2015, 22:04:04
Ale GetHashCode jest haszem, używanym głównie przy wyszukiwaniu właśnie, słownikach, itp. Natomiast GetInstanceId powinien zwracać unikalne ID obiektu (żadne dwa różne obiekty nie mogą mieć tego samego instanceId). Dlatego przy odtwarzaniu referencji hasz nie powinien być używany - bo właśnie są kolizje, a instanceId.

GetInstanceID (cokolwiek ma ono oznaczać).

Unikalne ID obiektu, zapewne inkrementowane za każdym razem gdy wywoływany jest (wewnętrznie czy zewnętrznie) konstruktor UnityEngine.Object. A jak wiadomo prawie wszystkie klasy silnika po nim dziedziczą.

Ewentualnie można sobie GUIDami radzić jakoś, ale C# powy GUID string - to string więc szybkość jego przeszukiwania i operacje mogą być pewnie wolniejsze, niż porównywanie intowych instanceID.