That is once an actor is destroyed , and the game is saved and loaded again , that actor does not reaspawn on load. I’ve seen some talk mention Fgameplay tags or give actors a unique ID or name and add it to an array in the savegame function. But though I can see what they’re saying , I don’t know how or where to do these things or how to implement them.I’m still somewhat newer to UE4. I thought I could add an “is destroyed” Boolean after my array in the save/load functions , then use “set actor hidden in game” or “destroy actor”, but it don’t seem to work. thanks for any help.
Any tutorials for when actor is destroyed , keep it permanently destroyed when a savegame is loaded?
this is the save and load setup in the character BP, where the data is circled between the nodes. It all saves good but I can’t figure out how to keep those actors destroyed after a save game and reload, as they keep respawning.
Hey @razmaz51 ,
There are many ways to do this, but the easiest way would be to save an array of destroyed actors. You can either store a unique ID or a reference to the actor. A unique ID is probably better in case you spawn enemies during runtime.
Here’s how you would do it -
-Create an enemy base class if you can - call it BP_EnemyBase. In this class create a Name variable called ‘UniqueID.’ This will serve as each enemy’s unique ID in the game.
-Now all enemies will be children of this BP (so they all inherit the UniqueID variable)
-Assign a unique ID to each enemy - this can be done manually or programatically
-Now create an Array variable called DeadEnemies of type Name. This variable will hold the list of all destroyed enemies. You should put this variable inside your Game Instance BP so it keeps this data across maps
-When an enemy is destroyed - before dying cast to your Game Instance and add the enemy’s uniqueID to the array
-When you are about to save the game, save this array as part of your save file
-When loading your game, load this variable and set it to you Game Instance
-Then run a function that gets All Actors of Class [BP_EnemyBase]. Then do a For Each loop and for every actor cast to class BP_EnemyBase and get the value of UniqueID. Then see if this value is part of the DeadEnemies array (use node Contains). If true, Destroy that actor, otherwise do nothing.
This function is basically going through all enemies in your level and checking if their UniqueID is part of the DeadEnemies array. If true, destroy them again. Run this function on Begin Play when the level starts.
Hopefully this gets you on the right track
thanks for reply. So in project there is third person enemy AI character BP. in which there is another BP based on that BP called enemy presets. from there each enemy is placed on the level. Can I create the Unique ID variable in one of those BP’s? Do I need to create the Unique ID variable(or at least a unique name) on each and every enemy placed in the game? Or is this ID variable an array I can add names to? I’m pretty new at this , you wouldn’t have any BP pictures lying around ?LOL I can understand the concept but do not know how or where to put all these things.
Very similar, but to save spawning and destroying unwanted objects and using “get all actors of class”, you could create a spawner blueprint controlling groups of non-permanent objects.
This spawner BP would spawn an array of objects containing location and ID info, upon destruction this ID is saved to a save game object file as an array of id refs or similar (I like arrays of structs containing maps), and upon restarting level the spawning blueprint first loads the removal list and removes the destroyed objects from the spawn array, then spawns remaining objects.
Using the spawner BP idea would also allow you control of when assets are spawned, to allow player to begin sooner, by only spawning assets in the same building, randomizing numbers etc
This would allow you to add functionality to allow the player to either replay same area with exact same setup, or choose a different experience, more enemies less ammo, more objects in the way.
Easy,medium and hard modes etc.
I’ve never used a Spawner bp, how is this different than placing actors on the level? all my enemies and pickups , etc… are placed on the levels. is this all spawned at runtime?that’s why I’m looking for a tutorial. or some pics at least. I understand the concept but not how or where to do all these things. thanks for reply
so I created the UniqueID variable and gave each pickup and enemy a unique ID(which was no small feat , as there are hundreds), I then created the DeadEnemies array(I take it this array stays empty for now) , and put it in BP_GameInstance. Is there any illustration for the next steps ? since I am not sure how to do those or where to put them. Thanks
When your enemies OnDestroy add their uniqueID to your array, and then in your loading blueprint you loop through that array and destroy them before letting the player start. You could probably have generated those unique IDs programmatically in your construction script.
It’s definitely more of a hammer than a scalpel but should accomplish your task.
I get what your saying , but I don’t know how to do it , like what sequence of nodes and where to put them. Thanks
Rough example, many ways to do it, this is using a map instead of an array, this way you can store both the ID and location and reference each.
create a struct containing a map of INT and Vector, saves time later.
The save game stuff I have included to try to make it easier to follow, I would normally have it located in a master Save system blueprint, side issue.
basically have a default map of ID’s and locations, with whatever number of objects you require, then load up the destroyed items, run through the map(think of it as an array that can hold 2 different types of variables) remove destroyed objects, them spawn whatever is left, feeding the id and locations into the objects, when objects are destroyed they would send this info back to the spawner blueprint which would be in charge of holding info on all objects it spawns, which have been destroyed, updating save games and adding new objects at random locations etc, possibilities are endless.
thanks for help. though I never put a map in a struct so I’m not sure how to do that. Also all my pickups and enemies and things are “hand” put on the levels. Is that compatible with a spawner bp? Those nodes you show , do they go on my character bp? normally with the way things are set up , I put things to save in the areas shown in the pics above in OP (in OnSaveGameSave between those nodes and then in
( “restore the savegame” areas, those setups are on my character bp.i’m using the Menu Starter Kit plugin and it creates those functions on the character bp. so its not really put where the " create save game " and “load game to slot” areas are. In the pics its hard to see where its at because its cropped.
My apologies, the best thing I can recommend is for you to start with the basics, watch the learning videos and read the documentation linked in the header bar above, The very first step in any project is organisation, setting up the structure of your game framework. What goes where, which blueprints hold and control specific items etc.
I am not a professional but here is my attempt at explaining:
A destructible object in the world doesn’t really fall under the pawn BP or Player-controller BP, you could place it under several other blueprints,
>Create a trigger to initiate the whole process of spawning objects, depends on what you want, spawn on level load? or player entering area, or timed?
In either level blueprint, game-instance(persistent between levels during a running game, so very handy), game state or some other trigger state like player entering building, initiate the above “spawner BP” to work. Alternately you could place spawnerBP in world and run event from begin play in the spawner.
I prefer controlled serial processes, A triggers B etc, and avoid using “begin play” when practical.
Create an actor BP as above, we will call him “Spawner” with a function to spawn the required destructible objects as per picture, or if it requires delays or timing considerations use a custom event.(functions don’t do delays)
With save systems that deal specifically with player variables you can place them directly on Character BP/PC controller BP or as actor components attached to the character, or PC controller,
Once you start saving world variables not directly relating to the player condition then creating a save system in a more global place is more fitting, game-state, game instance or custom blueprint. you can place the logic functions directly within these blueprints or set them up to be initiated/controlled by them and the save system a separate BP.
Also a major consideration is avoiding creating a Character Blueprint or PC controller containing to much content, as your compile times every time you change anything will increase, nothing worse than taking minutes to compile a BP just to check if a small tweak works.
Most importantly, learn the fundamentals, any node you don’t understand, research,
Mathew Wadstein youtube channel is very helpfull
Also not a professional, but if I understand correctly you are looking for Game Instance.
As Basement Bob said above, setting up the game framework is very important, this with
understanding the hierarchy/order of things in the engine, what comes first, what continues
though levels and what does not.
This vid is worth the watch. https://youtu.be/0LG4hiisflg
Thanks i will check them out, i got everthing saving , i just need destroyed actors to stay destroyed. Seems quite complicated for such a straightforward thing. And i seen so many different ways it is done. Last one i watched was using an independant save game object calked “SaveGameManager” , which was completely independant from others.
When an enemy is destroyed - before dying cast to your Game Instance and add the enemy’s uniqueID to the array " ---------------------------------any know how to do this step? I mean is it saying just before the destroy actor node , cast to the game instance ? and how do I add the enemies unique id to the array? Am I adding just the UniqueID name variable?
NOTE: In the tutorial, he uses an array of name references rather than an array of Actors. I don’t think he explains it in the video, but this is an important decision, because if you create an array of Actors you’re about to destroy, they’ll eventually become empty references and then you end up with all sorts of problems.
I know I appear out of nowhere, but the cleanest solution would be just to use an array of the type you want to keep destroyed.
So when you destroy, add that destroyed item to the array then save the array. On next load up, you can load the save game and run a for each loop and destroy every actor in that array. That way it will automatically destroy every picked up item.