Hi, I’m new to Unreal Engine so I’m not very familiar with blueprints. I was trying to create an on-screen display that tells me what day it is and the hours and minutes within the game while also using a day/night cycle. However, every time I reopen the game this timer resets and the sun is also always in the default starting position. How can I save the position of the sun (I rotate it on the y axis) and the day, hour and minutes? Thank you.
You need to save the data to a save game object, that can then be saved when exiting, then loaded when opening. You should read through Epic’s documentation on this:
Also, it’s wasteful to utilize the tick function for this type of functionality. I don’t think this needs to run every frame, so you should also look into utilizing Timers and having it run once or twice a second (depends on how incremental the change is in time and the sun rotation).
But do I have to create a “SaveGame” class? Can’t I do this directly in the main class? And if I have to create it, how can I get data from my main level (for example the degree of rotation of the sunlight)? Sorry for the probably trivial question.
I haven’t succeeded yet. If it helps, I’m using the free “CropoutSampleProject” template and wanted to modify it to test. This is the code I wrote in the “village” layer:
I’ll mention, you really should be handling save information in the game instance class, rather than the level blueprint because then it would be accessible by all other classes (utilizing the Get Game Instance node and casting to the appropriate game instance class).
I’m pretty sure it isn’t working because you aren’t creating the Save Game object prior to loading the data. You can put a print string node on the “Cast Failed” execution pin to verify the cast is failing. I think the “Does Save Game Exist” node checks if there is save data in the particular slot, not if there is a Save Game Object created that can be used.
Remember, when you create a Save Game Object it starts with the (default) variables/values you set in your SaveGame class. You then need to change those variables in the object itself, before saving in order to be able to load those values later.
So in my example, when the map starts it creates the object, and checks if the save game exists. If so, it loads from slot, casts to the SaveGame class, sets it to the BP_Save_Ref variable (so you can access it later), then pulls the sunLightPos variable from the loaded save game reference.
If there isn’t a saved game in the slot, it simply saves one with the default values from your SaveGame class. Assuming the map default for the sun’s rotation is the same as the default in the SaveGame class, nothing more needs to be done.
Now, when you leave the map or need to save the game, you reference the BP_Save_Ref (Save Game Object) and set the sunLightPos variable to the current rotation, then save the game to slot using that same BP_Save_Ref reference. I think this is the piece that you’ve been missing, which is why when you reload, it isn’t changing from the default value.
Does this make sense?
It is helpful to create individual functions for saving and loading, so those actions can be easily called.
I have done this for now but I don’t understand why my Sun Light Pos set does not have the target to be connected to the BP_Save object.
Also, if you notice any other errors, let me know.
Blueprint code:
“I don’t understand why my Sun Light Pos set does not have the target to be connected to the BP_Save object.”
Not sure I’m understanding this one. Which node are you referring to?
You definitely don’t need to copy the events I created, I just did that as a placeholder and to help explain the function. You’ll need to make sure in the “Map_Quit” event, you are getting the actor location of the SunLight actor (as you had in the previous images), rather than the actor location of the level itself.
As for level blueprints; just be careful with how you structure your code. Using level blueprints should really only be used for logic that is specific to that individual level and isn’t something that needs to be used anywhere else. If your project calls for multiple levels, this logic will need to be duplicated in each level blueprint (compared to only doing it once in the Game Instance class, that then has global accessibility).