Problem z zapisem i wczytaniem UE4


#1

Dzień dobry. Aktualnie kończę swoją pierwszą grę w Unreal Engine 4. Jestem na etapie tworzenia systemu zapisywania i wczytywania. Wiem, że taki system powinno się robić na początku projektu, ale biorąc pod uwagę, że jest to mój pierwszy i niestety niemały projekt, to i tak jestem zadowolony (i zarazem lekko zdziwiony), że udało mi się zaimplementować (póki co częściowo) mechanikę Save&Load. Ale do rzeczy. Dodałem kilka funkcji które są odpowiedzialne za zapisywanie oraz ładowanie konkretnych parametrów:

  1. Menu Główne
  • Przycisk „New Game” -> funkcja która tworzy slot zapisu oraz ustawia w nim wartości na domyślne (w większość przypadków jest to wartość 0).

  • Przycisk „Continue Game” -> funkcja która wczytuje mapę główną.
  1. Mapa główna
  • Blueprint gracza (Actor)-> BeginPlay-> tworzone są wszystkie widgety powiązane z postacią gracza (PauseMenu, HUD, Inventory etc.)-> wywoływane są funkcje zadeklarowane w WBP_PauseMenu, odpowiedzialne za załadowanie wartości z pliku zapisu (w przypadku nowej gry są to wartości domyślne; w przypadku kontynuacji porostu ładuje to co zostało zapisane przy wychodzeniu z gry).

  • WBP_PauseMenu-> deklaracje funkcji do zapisu i wczytania.

  • Przycisk „Exit Game” w WBP_PauseMenu-> wywołuje funkcje odpowiedzialne za zapis.

Na tym etapie proces Save&Load wygląda w skrócie następująco:

Po uruchomieniu gry klikamy przycisk ‚New Game”. Gra zostaje załdowana z domyślnymi wartościami (0). Następnie podczas gry zdobywamy monety, bronię , fiolki etc. Wychodzimy z gry do menu za pomocą przycisku „Exit Game” i jednocześnie zapisujemy nasze postępy. W celu wczytania gry klikamy w menu głównym przycisk „Continue Game” i gra ładuje się z wartościami które zapisaliśmy przy wychodzeniu z niej do menu głównego.

Niestety zachciało mi się dodać do mojej gry sklep , który znajduje się na osobnej mapie. Więc przed załadowaniem - nazwijmy to mapy że sklepem - muszę zapisać wszystkie parametry. Robię to za pomocą przycisku, który znajduje się w widgecie WBP_Teleport, który z kolei jest tworzony w BeginPlay obiektu BP_Teleport. Jest to taka sama funkcja jak w przypadku WBP_PauseMenu (więc teoretycznie powinna działać). BP_Teleport znajduje się na jednej i drugiej mapie i stanowi swego rodzaju „drzwi” miedzy mapami.

Przycisk w WBP_Teleport odpowiedzialny za zapis oraz załadowanie nowej mapy. Przycisk w WBP_PauseMenu ( „Exit Game”) wyglada identycznie za wyjątkiem trzech ostatnich funkcji.

Funkcja wywoływana po zespawnowaniu postaci na nowej mapie i wczytanie wartości

W tym miejscu przechodzimy do właściwego problemu. Podczas ładowania mapy sklepu nie wczytują się zapisane przeze mnie wartości z pliku zapisu. Działa to również w druga stronę. Przy próbie „teleportacji” z mapy ze sklepem na mapę główną również teoretycznie zapisane wartości nie wczytują się. Siedzę nad tym od ponad tygodnia i nie mam już pomysłu co jest nie tak. Oto czego już próbowałem:

  • Wywołać funkcje z WBP_PauseMenu w przycisku teleportacji do mapy ze sklepem znajdujący się w WBP_Teleport.

  • Tworzyć nowy slot zapisu (bez sensu)

  • Wczytywać grę w Level Blueprint

  • Wczytywać grę w blueprincie postaci która spawnuje się na mapie ze sklepem (robić to podobnie jak w przypadku gracza w BeginPlay).

Jak już wcześniej wspomniałem, męczę się z tym od tygodnia (chciałem skończyć projekt do końca roku) i nie wiem gdzie jest błąd. Sam algorytm zapisu i wczytywania związany z teleportem jest napisany 1:1 jak ten z ładowania mapy głównej z poziomu menu głównego. Z mojej perspektywy wyglada to tak, jakby funkcja zapisu „zerowała” lub wczytywała domyślne wartości podczas ładowania mapy sklepu.

Jeżeli ktoś ma jakiekolwiek pomysły, wskazówki jak to można naprawić będę naprawdę wdzięczny.

Życzę miłego dnia
BushyAxis793


#2

Użyj debuggera/logów żeby dostać więcej informacji co się dziej kiedy i jakie wartości są nie tak.
Potestuj różne scenariusze typu save/load na tej samej mapie, save/load po zmianie mapy, wypisanie logiem wszystkich instotnych zmiennych moze slot name źle ustawiony, może nie ten branch ifa, może jeszcze co innego

Tak czy siak lepiej wyizolować na którym etapie która wartość jest inna niż powinna w teorii być


#3

Dzięki za odpowiedź. Poradziłem sobie w dość nietypowy sposób. Mianowicie cały cza spróbowałem wywoływać funkcję za pomocą referencji którą utworzyłem w Event Contruct w widżecie i to niestety nie działało. Spróbowałem więc wywołać funkcję za pomocą CastToPlayer z GetPlayerCharacter i zadziałało. Wszystko jest zapisywane i ładowane pomiędzy poziomami.

Niestety pojawił się kolejny problem i aby nie tworzyć kolejnego tematu opisze go tutaj, dlatego że też jest związany z systemem zapis/odczyt.
Mianowice poza zapisywaniem samej zawartości ekwipunku chciałby również zapisywać oraz wczytywać status przedmiotu tzn. Jeżeli jest wyposażony i zapisałem grę to po wczytaniu chciałbym aby broń zespawnowała się w ręce gracza. I tutaj pojawia się problem. Podczas zwykłego „wyposażania” broni jest wywoływana funkcja która sprawdza klasę przedmiotu i na tej podstawie dopiera pozycje , socket itp. I następnie spawnuje przedmiot oraz zmienia grafikę w ekwipunku na wersje „wyposażoną” i ustawia zmienna IsRightHandUsed na true. Podczas „chowania broni do ekwipunku” przedmiot jest usuwany oraz grafika zmieniana na zwykła i zmienna IsRightHandUsed ustawiana na false.
W celu zapisania statusu broni próbowałem zapisywać wartość IsRightHandUsed. Następnie podczas wczytywania ustawiałem wartość zmiennej z SaveGame na true i wywoływałem funkcję wykorzystywaną przy „normalnym” wybieraniu broni. Niestety nie działa. Nie bardzo wiem od jakiej strony do tego podejść. Podobna metoda dzisłała w przypadku ładowania przedmiotów do ekwipunku z pliku zapisu. Najpierw wczytałem wartości z tablicy, a następnie wywołałem funkcje za pomocą której dodawałem bronie do ekwipunku przy kupowani lub podnoszeniu. W tym przypadku to nie działa. Próbowałem sprawdzać stan IsRightHandUsed i na tej podstawie spawnować lub usuwać broń ale to również nie działa. Za jakiekolwiek wskazówki będę wdzięczny.

Miłego dnia
BushyAxis793


#4

Upewnij się że masz kawałki wyizolowane do jak najprostszych i testuj który kwałek nie działa.

Np zrób sobie kilka saveów testowych i jakieś funkcje typu wyspawnuj gołego gracza, spróbuj zaaplikować na niego equipment z savea.

Najlepiej jak masz savey tekstowe i możesz je edytować notatnikiem do testów.
Jak są binarne to trudniej zrozumieć co tam właściwie jest w pliku i co nie działa.