I usually avoid hard references like the plague. But in a recent project, I have a player controller blueprint which needs to spawn a particular actor and subsequently call some functions on that actor from time to time. So, inside the player controller blueprint, I dropped in a Spawn Actor of Class node, stored its result in a variable and moved on. This got me thinking as to when a hard reference might be ok and was interested in anyone else’s thoughts on the topic.
My logic is that this actor in question will only ever be spawned once by the player controller. It will always belong to the player controller and be exclusively used by it. It must always exist with the player controller (therefore will always be loaded in) and this player controller will only ever be used in levels where this actor is also required.
What do you think? Would you refactor just for purity’s sake or are some hard references okay?
P.S. I’m aware that some are unavoidable, but I’m talking here about one’s that can be avoided but may not necessarily need to be.
Hey there @wilberolive! So the way I think about it much of the time, is that a hard reference to something is not actually that bad in certain situations. If you are only going to spawn one ever, it has no chance of ever being null (or if you can handle it being null), and you aren’t being extremely tight on memory (which most indie games aren’t), it’s not that big of a deal. It’s definitely dependent on your use case still, but by no means is it an instant refactor if you can’t foresee any problems with it.
Does this thing get re-instantiated when your character dies/failstate?
Okay. I think the same way and agree with you. I’m just sanity checking myself with other people’s opinions as my instant reaction was to refactor like I always do to eliminate every hard reference possible. But then I realised, in some situations it is probably just fine.
To answer your question, it is a player controller that can never die. It exists as long as the level exists. I suppose there could be a fail state where it fails to spawn, in which case so would the hard referenced actor, since it spawns on Begin Play in the player controller.
If it’s something that will always exist, then hard reference to your heart’s content. If it may or may not exist, use an interface. That’s pretty much the only rule. Stuff like player pawn classes, player controllers, game instances, etc can be hard referenced if super modular or portable code isn’t a concern, but never hard reference ephemeral stuff like pickups, weapons, collectables etc unless they are always a part of your character (like your character always has the same sword for example).
Hard references can be okay in certain situations, but it’s always best to use soft references whenever possible to maintain loose coupling between objects. In your specific case, if the actor in question will always belong to the player controller and be exclusively used by it, and will always exist with the player controller, then using a hard reference is acceptable. However, it’s always good to be mindful of the potential drawbacks of using hard references, such as increased memory usage and potential errors if the referenced object is destroyed or changes unexpectedly. If you’re unsure about the design, consider discussing it with other team members or seeking advice from experienced developers.