Where would you suggest we go from here? My guess would be to set all saved variables to my “SaveAllData” function in the game instance, and then load and set all of those variables in each actor which needs variables set (so we aren’t casting to any item other than the game instance), but I would like to verify. In order to load, would I maybe create an interface with everything needing to be saved and add a function on there? I’m not sure how I’d call each actor to load their own data without casting to them, though. And this whole time we’ve been tackling the save system for the level data, but right now that isn’t working either. Is there anything that needs to be added to any of the blueprints I sent in the past to make it work as it did when I came here for the question for the first time (except, of course, with ALL items saving that they all destroyed.)
did this image not work for you? for a simple game this is literally all you need.
- loop over existing save actors and destroy them (use GetAllActorsWithInterface) to find them
- SpawnActors from SaveData and call load interface
Strangely, I’m not seeing any image sent /:
I’ve had this script for a while here (coming from here), but I’ve changed some things up. I don’t think I was calling everything that I needed to, and the slot names weren’t always consistent. It’s still not saving the data, but I think I’m closer to it doing so. The code works up until the ‘get actors with interface for each loop’ on “load all data”. Which means items aren’t being destroyed or added, which is why it doesn’t appear to save. But I don’t know why that is, why it stops after the “loop body.” It stops in between that and the ‘is valid’. Not sure why. If I can figure that out I may be able to fix this for real this time.
Also, unfortunately, my inventory isn’t saving either. I feel as if it should have something to do with the Save inventory function here.
what calls LoadGame? just need to make sure the world is ready. for testing put it on a input in the player controller.
with you Save ObjectData use ADD not ArraySet.
other than that it looks closer. if you have any more errors you may have to use printstrings/breakpoints to find out what isnt working exactly
The main menu buttons to load and create new game are what calls LoadGame,
I replaced the add with arrayset here, do you think I should change all of the other parts of the inventory system to use ADD instead of Arrayset? Arrayset is what Ryan used in the tutorial, I’m not sure if I should replace all of the system with ADD. For example, here’s one of my other blueprints using ArraySet.
Here’s my test to load the game through the player controller, but it only functions after because the input mode is UI only during the main menu.
The Load All Data still isn’t executing any part of the first loop (shown here). Taking a deeper look, my parent item did implement the interface, but the two child items did not, and the parent item wasn’t in the world, therefore there was no data to loop when it came to actors with the interface. I recreated my item blueprints from scratch and tried to replicate everything, but now they can’t pick up the seashells.. I’m wondering why. Here are the related blueprints.
Pick Up (from BPI_Interact)
Called here
Is there any reason they’d be excluding the new seashell item from being picked up if it’s part of the right interfaces and has the same code inside of it that the original parent item? I’ve also set it to be the item class in the data table, instead of the previous seashell. I feel as if I may be missing setting something.
I apologize if I’m throwing too much at you, and if I’m not doing enough myself. I’m trying to do what I can (,:
so the MainMenu is likely in a different level, if you load there you’d be loading the wrong level at the wrong time.
it make sense for the GI to handle saving/loading but for now call the load function in the GI from the GM Beginplay + 0.2 delay (temp)
it depends on the situation but if you use ArraySet you have to set the index which you had hard set to 0 in you first pic
again this is likely because its in the wrong level (main menu)
children inherit parent interfaces so dont worry about that
All of my other ArraySets do have the index filled- so for now I’ll leave them instead of replacing them with add.
I’m sorry, I’m not following. If I load it on the game mode, it creates a new save on the main menu. To make that actually matter, I’d have to remove the new game/load game button’s functionality, which means I’m not sure how I’d load my game.
And if I load the game level, I can’t add code after the load level because the code will be destroyed (as you mentioned below)
So I’m not sure how to load the level and then load the game, to make sure it’s the correct level (NOT the Main Menu). I need to do it after so the player can chose new or load game.
Children and parents are tricky, I tried making the items all under the same parent, but whenever I created a new item under the parent, it wouldn’t work. Regardless, I’ve returned to the older iteration that I hadn’t changed the parents of the items in.
you can call functions from anywhere, but it makes sense for the function to exist on the game instance.
just like you can call functions from your widget thats fine, but when you change level everything not persistent will be destroyed so any code after the call could fail, depending on garbage collection.
GameMode BeginPlay means the world has loaded so you can use that to call Load but, world loaded doesnt mean everything is fully set up, that just depends on your game. hence the temporary but slight delay.
Ok, so I call the function from the game mode as the main menu? Like so?
I don’t have any code after the level opens. Right now, I believe the problem may still be within the save inventory. I don’t know why, but it still doesn’t recognize any items of the BPI Item interface.
However; When I do this on an event begin play, the items with the interface are printed. How is it that one place recognizes the items in the interface, and others do not?
it depends where you call the function from
so here, it looks like you’re loading level before you open the level. which wont work because the level doesnt exist yet.
imagine you have 2 levels. MainMenu and GameLevel.
when you press StartGame in the MainMenu the GameLevel doesnt exist yet.
to keep things simple try your load functions in the GameLevel, GameMode, BeginPlay with a delay for safety
Okay, I think I understand where my confusion was coming from. I was under the impression the game mode begin play was the begin play for the entire game, meaning it’d load like that on the main menu.
This is what I’ve changed
| Game Mode | Main Menu Start Game |
This still seems to be a problem, though, if you have any ideas of where it could be going wrong (:
the GameMode is very wrong,
Never put a delay in a loop, the delay should be at the start. (right after begin play and also keep in mind this is a temporary thing for testing) also youre calling LoadGame on the loop, i assume you either want load object data there or just a single call to loadgame.
the code looks fine, so where is this called? use the same examples above, is it the right level, is the level still loaded etc
Oh my bad, I meant to put the delay and load game on completed, not in the loop. The delay causes the mouse to not show up on the main menu which is quite peculiar.
Okay, I’ve updated the Main Menu, Main Menu Map, and Game Mode a bit. I needed to communicate some things between blueprints that wasn’t happening yet, and the level was being loaded after a lot of the important parts. Now, the destroy actor loop is working, though no actors are respawning after the ‘loop completed.’ (At least I think the destroy actor loop is working, now the save inventory is having the issue, causing the game to not save to any slot, so every game I do now is a new game.) This is due to the fact that there are no structs saved to object data. All existing items should be saved with the Save Inventory function (which is called when you hit the save button or keyboard shortcut). This is another time where it doesn’t recognize anything inside of the BPI_Item blueprint- I fixed it for the load all data, but it’s a problem again here. I’m not sure what I did to change it before.
| Game Mode | Main Menu | Main Menu Map | Save Inventory |
so what is your savegameslot name?
mostly the code looks fine now, i’d have to see your save/load functions.
for an inventory it makes sense to have a unique slot.
originally you were using level name as slots which is fine for the level but the inventory persists between levels.
In short use levelname for levelsavedata and maybe a playername as playerstate save data. this also means you may have 2 savegameobjects, one for level data and one for persistant data
Right now my slot name is just Slot1 for simplicity.
From previous conversation, I had thought I’d need to save all variables into one savegameobject, so I had merged them into one (below if you recall)
(Save All Data is called by clicking the save button or hitting Q)
| Save All Data | Load All Data | Calling Load Game | Load Game |
I’ll create a new iteration of the game with the separate savegameobjects. I think what’s confusing me is I thought we could only have one save game object, but maybe you meant I can only have one SLOT per save game object within a single game. So you can have multiple slots, but you can’t load more than one at a time obviously, but you CAN load more than one save game object at a time?
Update blueprints using two savegameobjects:
| Save All Data | Load All Data | Calling Load Game | Load Game |
Doing this has made me realize the Load All Data for the first iteration (first set of links) sets the inventory content variable to inventory content when it should be setting the content variable from the inventory system to the inventory content data. I’ll be fixing that in the first iteration as well, then.
My actor removed and actor added variables aren’t used anywhere except for this, which I’ve disconnected because it caused the following error-
Blueprint Runtime Error: “Accessed None trying to read property As Save Data Level”. Node: Add Unique Graph: EventGraph Function: Execute Ubergraph BP Base Parent Item Blueprint: BP_BaseParentItem
Blueprint Runtime Error: “Accessed None”. Node: Add Unique Graph: EventGraph Function: Execute Ubergraph BP Base Parent Item Blueprint: BP_BaseParentItem
Not sure if that is relevant to the issues, I don’t recall deleting anything unless we’d changed them out.
It also looks like I’m not spawning the right thing in the Load All Data, I would want to spawn all items BUT the actors removed, not object data, right? Or have I missed doing that somewhere else in the code?
its getting too complicated to follow so ill just lay it out.
OnLoad
- GM BeginPlay calls load function.
- Load function checks if data is found, if true destroy all savegame actors and spawn actors from savedata.
- on complete load player inventory data.
OnSave (called manually by player)
- GetAllActors with interface, call save interface, add data to savegame object (might need to clear existing data)
- GetPlayer inventory save to savegameobject.
that should be all you need so lets get that working first.
you’ll probably need a different slot for levels (levelname) and playerdata. this is because if you level data is level specific but you playerdata exists on any level
Yeah, I apologize for the complicated nature of my set-up, I definitely think part of the problem is me overcomplicating it.
One question about the save and load, what does the Object Data variable do? I can’t figure out where to load it into. It’s a Save Item Struct Array.
I attempted to do so!
New Blueprints:
| Game Mode | Load Game | Load All Data | Save All Data |
I’m unfortunately getting the following error now, I think because once again, it’s reading that there are no actors with the item interface, which I know isn’t the case. Not sure how to fix that.
Blueprint Runtime Error: "Accessed None trying to read property As Save Data Level". Node: Set ActorsInScene Graph: Save All Data Function: Save All Data Blueprint: BP_GameInstance
Blueprint Runtime Error: "Attempted to assign to None". Node: Set ActorsInScene Graph: Save All Data Function: Save All Data Blueprint: BP_GameInstance
Blueprint Runtime Error: "Accessed None trying to read property As Save Data Player". Node: Branch Graph: ForEachLoop Function: Save All Data Blueprint: BP_GameInstance
Blueprint Runtime Error: "Accessed None". Node: Branch Graph: ForEachLoop Function: Save All Data Blueprint: BP_GameInstance
Blueprint Runtime Error: "Accessed None trying to read property Inventory System". Node: Branch Graph: ForEachLoop Function: Save All Data Blueprint: BP_GameInstance
I think I did the code correctly for the most part for these 4 blueprints though.
on load game your not saving the SaveGameObject as a variable so LoadAllData will be Null
you cannot save ActorObjectReferences (ActorsInScene) thats what the GetSaveData is for.
on save you dont need all the loops, just Clear and Set
Okay, so I’m understanding why loading the game needs to be saved as a variable- as it currently is, the variable type of the ‘load game from slot’ is just SaveGame, so I can’t set it to the ‘As Save Data Level (or Player)’ . I can however set the new variable to be As Save Data Player, but I don’t think that’s helpful when AsSaveDataPlayer is null. Shown in this video. I’m wondering if I’m meant to change the variable type to Save Game or if there’s something else I’m meant to do.
Alright, I’ve changed the ActorsInScene to an array of struct variables. Here’s the new blueprints.
| Load Game | Load All Data | Save All Data |
For the last part, I honestly have no idea why I did those loops, my bad that was a serious oversight on my part.
One question: I’m having this error, and I’m pretty sure it’s because I’m trying to clear the null variable ActorData in SaveAllData- but later in the game, when I have to override the data, I need to clear it. Unless in the loop later, when I make the SaveItemStruct, can be changed to a set array (if it’s possible, I’m not sure how to go about it). So not sure how to resolve the error.
Blueprint Runtime Error: "Accessed None trying to read property As Save Data Level". Node: Set ActorData Graph: Save All Data Function: Save All Data Blueprint: BP_GameInstance
Blueprint Runtime Error: "Attempted to assign to None". Node: Set ActorData Graph: Save All Data Function: Save All Data Blueprint: BP_GameInstance
Blueprint Runtime Error: "Accessed None trying to read property As Save Data Level". Node: Add Graph: Save All Data Function: Save All Data Blueprint: BP_GameInstance
you have to cast it to your class and save it as your variable, this is error you get
AsSaveDataLevel is null because you havent actually set it when you create/load game from slot. you need to save it when you create it too