I have some actors that get destroyed and recreated quickly and was working on disabling them temporarily instead.
However disabling an actor is turning out harder than I thought since there’s no easy way to do it like there is in Unity for example. HiddenInGame and CollisionEnabled work on the whole actor but then there are sounds, particle systems, physics, etc…. My game is turning into somewhat of a buggy mess when I’m trying to properly disable an actor.
It also makes me think is it better to just destroy actors and quickly create new ones if it’s this hard? Maybe unreal is good with reusing memory? I kind of doubt this though since a lot of work goes into spawning an actor and even destroyed actors can be referenced with pointers in memory and are marked as destroyed/invalid.
However there seem to be side effects to leaving actors in the world since it’s not easy to truly be sure they’re disabled in every way. There might be some game ticks running you forgot about, or some other random things like behavior trees.
i can’t answer the technical implications but I am disabling actors in my game and I just disable tick for those actors and that seems to cover pretty much everything. Stops physics, stops overlaps. Besides that I just disable collision.
But I keep pretty much everything outside of the actor class itself - its more just like a hull that additional functionality is bolted onto. All my sfx and such is handled in manager-like systems, and all AI behaviors only run if the actor is held in an “active enemies” array. If most functionality is in actor components you can just remove the components to disable the actor, in addition to remove collision, disable tick.
I don’t know that my particular way is normal or would make sense in professional, team-based project. You might take a look at Lyra and see how they handle spawning of AI bots.
There is an actor pooling plugin on the marketplace. Perhaps you could get in touch with author and ask if maybe they’ve done some testing to know when it becomes a concern.
If you consider the first person demo/starter project that comes with the engine, the gun in that fires a projectile that spawns an actor (the projectile). When the projectile hits a cube, it destroys itself.
You can fire this like a machine gun, spawning/destroying over and over hundreds of times. The engine is built for this type of thing and Epic has spent years making it better and better under the hood.
So I think you would be fine spawning and destroying them and let the engine sort it out. If you can give specific examples (with screenshots) of why you think it would be a problem it might be easier to comment.
Imagine I’m doing a reloading animation and my character puts the magazine away and takes out another. I have a breif moment where I hide the actor and need it again. Or imagine I’m equipping a gun and put it away but take it out again.
There are times like these where I need the actor very soon after not needing it.
I already have this somewhat complex system in place for managing all of this and it can set actors to disappear for some time. If the timer runs out they get destroyed for real which is something like 10 seconds later. It helps manage all the actors I’m constantly spawning during weapon animations. It works really well if I just destroy and recreate actors but I keep finding weird bugs when I reuse an existing actor.
I’m wondering if it’s more trouble than it’s worth. I even had to debug why my gun was offset incorrectly in my characters hand but only if reused. Turns out Attaching children returns early if they’re already attached, and my hidden actor stayed attached to the guys hand. I was attaching with SNAP_TO_TARGET but it wouldn’t snap to target due to returning early. So every time it reappeard it’d offset by a few units because I would adjust its relative transform after attachment to make things line up. Just random annoyances like this that keep appearing so I’d bolt on fixes like, OK when deactivating actor make sure it’s detached. Make sure physics are disabled so it doesn’t fall out of the world. Make sure particles are disabled. Make sure Sound is disabled… Make sure all ticks are disabled on every component… Make sure to undisable the ticks only if they should be. Etc…
For me this fits into the “Don’t work on performance issues that don’t show up yet”.
I would destroy and create the actor. Then, if you see performance issues later, do more work.
The thing you are fighting right now is the thing you did to improve performance before you had a performance problem.
I have done that many times myself and try to remember not to pre-solve non-existing problems unless I “know” it is going to be a problem - and even then I prove it is a problem before solving it.
If you really want to know if destroying and creating the actor is an issue, make a debug change that allows the character to holster and equip the weapon 2-3 times per second over and over without any action from you. Then go to lunch while it is running. When you come back, run /stat unit and see what your game and frame thread look like. My guess is they will be unchanged.
Here’s a good document on optimizing your game, looking at it from the planning stage - it has some very good tips, like reducing nested components and pooling commonly used actors, quoting:
Unreal engine Spawn can be very slow. Using it on things like projectiles or explosions might put too much stress on the garbage-collector, and cause hitches. It’s a very good idea to make Projectiles, and other very commonly respawning objects, use an object pool. Robo Recall has an implementation you can check as an example.
in the tip he says to optimize enough to keep the game running at ~80% of target FPS during most stages of development. That doesn’t mean optimize non-problems. The same principle still applies that its not a good idea to fix something until you can prove it is broken.
everybody might know that already, just pointing out the nuance as I see it. I’m not making a case for or against the pooling - just I took a read of that and didn’t see anything contradictory between it and post above.
Agreed that you can take things too far, especially if it’s one of your first projects. After a number of projects though, you do start to see what types of routines are shared by all of them and can tackle them right from the start to make things easy. The author of that document has obviously been involved in many projects.
Regarding the actor pooling - I’ve used pooling in most of my projects over the years for optimization, so it’s common sense to have that in a simple to use package that can be used in any project. More than once I’ve stripped out routines for actor manipulation (both in UE and other software that had “actors”) and replaced with pooling systems.
As far as optimization goes, here’s a graph of actor spawning vs pooling:
Yeah I agree with optmization is the root of all evil kind of thing. And it’s possible I’m trying to optimize something I shouldn’t even be optimizing.
I’d be very happy to not worry about this issue at all because it’s easier and just destroy, create actors whenever without thinking about it. It just seemed like something that you naturally could want to optimize so I’m trying to figure out if I should or not. It’s common to think about pools of objects for things like this to avoid destroying and creating new ones to often.
I know I’m also going to have things like shell casings and decals and that’s on a whole another level of needing a pool of actors and optimization.
If Unreal can do this for me without me thinking about it that’d be amazing.