Has anyone found a solution to blueprint classes that do not need to be actors?

For the love of all that’s holy, has anyone found a way to just write some generic classes that can be instantiated as objects but do not contain all the overhead of actors? This has become a bit of a nightmare for trying to do any kind of complex game logic in pure blueprints. This one thing impacts so many others. Epic, come on guys. Dev’s have been begging for this for well over a year. Throw us a bone. All the shiny graphics in the world don’t mean squat if your core mechanics have to be hacked and patched together.

Here are a list of things which, with the briefest glance at these forums you could find your devs begging for this functionality for:

Inventories
Skills
Abilities
Spells
Behaviors
Affects
Character Classes
Global Constants that span levels (since Game Objects can contain objects/components.)

Empty actor don’t create much of overhead, the main diffrence between normal object and actor is a component system and as long there no scene component actor won’t exist physically in world and won’t be even tried to be rendered. Engine it self uses Actor for non physical things and eventually you will be force to use them anyway, Info classes (GameMode etc.), Controllers (needed for AI) are all actors, UE3 inventory system was all so all actor, 0 objects, because from actor it’s easier to operate world.

But if you really want to use objects, there other work around then using Structs, it is components other nice way to do managers, technically component system can work as a inventory it self.

Also Epic node to instantiate object in blueprint: https://github.com/EpicGames/UnrealEngine/pull/1060

Actually, Ominic, they are not all the same thing, nor are they always structs, or even normally, structs because they will often have associated unique code that goes with them. Take a skill for instance, how is an array of structs going to handle something like a tracking skill, without any additional code to determine whether the target is valid, get the targets location, draw path or push a notification of direction to the player. How could the same code for that be used for say, a crafting skill?

If you want a good, readable understanding of how these things are often done, go download the CoffeeMUD package and look. Classes and subclasses, not structs.

And yes, I am aware that objects can not contain components. What I am not aware of is WHY they added this limitation in. Any object should be able to handle a component.

The overhead is just part of the problem, Shadoriver. Even if the overhead for a single Actor is not much, what about when you get to 20… 100… 1000+ actors? Because that is exactly what using actors for skills/abilities/inventories and such would lead to. When I learned to program(and I am dating myself here) 1mb of memory was a lot, so things had to be really efficient. Waste not, want not. Just because we are spoiled for resources doesn’t mean we should lose that mentality because if you can do more with less, then you can do more overall.

Another part is sheer clutter. I’ve done the inventory using structs/actors. It’s clunky. The blueprint version of structs is, and has been since at least 4.1, rather prone to bugs and pretty clunky. The make/break/set nodes are very prone to error, and have caused loads of headaches. Actors, on the other hand, even if they don’t get rendered, do start to show up in your scene editor and they aren’t organized. So if you have 8 stats, 12 skills, and 20 inventory items (plus component managers) you will have upwards of 45 actors clumped under your player character, which makes finding anything a pain in the neck. When was the last time you played a game that had skills, but only had 12, or had items but only had 20? If you add abilities on to that (they are different in the context of my game), then add behaviors, then add affects, etc, i hope you can see how unwieldy that would become, and quickly. Now, extrapolate that out to even a limited multiplayer game (say 10 players) with 20 mobs in a level. Now instead of 45 actors per character, you are up to 90, and 90x30=2700 actors in your level at once and you haven’t even started acounting for scene objects,

Omni and you both mentioned structs, which is great for containing data, and I do use them extensively, but the blueprint versions contain no logic which makes them unsuitable for the sole repository for skills/spells/abilities/etc.

the “unique functional code that goes with the item” is a waste of memory for the purposes of an inventory/skilltree/abilityList/SpellPage/StatusAffectsScreen/QuestList/ScoreBoard/LevelSelectScreen/MultiplayerLobby/etc…

an inventory screen doesn’t care how to track an enemy, it just cares whether you have collected an item or not.
the actual tracking functionality can just be a function in an actor that your playerController owns, which checks your inventory to see if you have collected the tracking item, to decide if it will allow you to use the function.

to be efficient, you shouldn’t store a list of objects for an inventory, you should store a list of structs or ID numbers explaining what the object is, not how it works.

so if you want the player to collect a double jump, don’t put the double jump logic inside the collectible, keep it in the movement component.

in other words, an inventory does not hold skills, and neither do collectibles, they just hold licenses to use skills, in the form of ItemIDs or Item Structs.

the actual skills are handled by a manager actor, referenced by the player controller or player character. you could make it directly in the player controller, but its nice to separate it so you can reuse the same skillManager for an AI character.

the movement component contains a bunch of skills, like walking, running, crouching, jumping, swimming, flying, etc… if you use c++, you could have a separate targeting component, and crafting component, or you can combine them into a single skill component, which would handle all of your skill functionality, augmented by your skill structs in your skill inventory.

All games i played with since UE1 bearly used Object for gameplay code, with you disable tick (And you need actor for tick btw) actor is complitly removed from rutine. But whatever, i give also solution for Object :slight_smile:

& Omnicypher,

Both of your answers are workarounds that I have tried with varying degrees of success. Unfortunately, they have not proven to be a good fit solution for my project. Some of it is, admittedly, a lack of coding experience on my part, some of it is limitations of the engine. For example, if I could pass a class name as a string as a parameter to create an actor at runtime, Omnicyphers method of an inventory would make much more sense.

If I the skill/abilities/behaviors actors didn’t need to be loaded the majority of the time, making them structs and only instantiating them when needed might also make sense. So, guys, please don’t think I am being argumentative just for the sake of arguing. Most of my code for these things doesn’t need the tick event, nor does it need the other components that are native to actors. They are unnecessary overhead.

However, you two did put me on to a design model that I haven’t tried using fewer actors and more components. I will get back with you and let you know how that works out. For the mean time, I am going to leave this marked as unanswered though, as the question of whether or not we can or will be able to instantiate objects has not been answered. I know it is available in C++, so it is a mystery as to why it is not available in BP. The quote in the link you sent said it has not been implemented yet, but I am not sure which version of the engine that was referring to.

Thank you again.

you can pass a class name to spawn an actor. (although this might only work in the play in editor and the asset might not get packaged with your game unless its referenced, so it may not work in stand alone shipping. )

lets say you have a unique integer ID for each collectible in your game, and each collectible item has a custom class it needs to spawn. you could make an inventory that is an array of ItemIDs, and use a datatable to relate those IDs to a class reference, which you can use to spawn an actor.

alternatively, you could make the inventory hold a struct that contained both an ItemID and a class reference, but it would waste way more memory than just storing a single integer for each collectible. the only items that need to be stored as structs are RPG randomized drops, which can have custom stats. if its a standard item that always does the same thing, it only needs to be stored as an ItemID, and it can use a datatable to look up its stats when it needs to be spawned in the world or displayed in a menu. if you have an inventory of 1000 items, and you only show 10 items per page, you only need to look up the datatable display data for those 10 items, and you don’t need to spawn them at all, so its very efficient to load more data as you scroll down the list.

but an even more efficient solution is to have every object use the same generic pickup class to spawn from. so when you drop an item, you don’t spawn a specific actor for each item, you spawn a generic pickup class, and set its ItemID and RPGstats to the stats of your inventory item. its begin play event can update its mesh/icon/animation based on its ItemID, inside the pickup class.

if you drop a sword, the sword doesn’t need to know how to deal damage to an enemy, it just needs to know how to be picked up or dropped. it never needs to know what it does, only what it is. the player character is the one who needs to know how to attack with a sword, so that’s where the functionality for the sword attacks belong.

I did end up using actors, even though I am not crazy about it. What you are describing here is similar to what I ended up going with. I have an ability component attached to the player class that contains arrays with IDs for Active & learned abilities. It only instantiates the nodes for the abilities that are currently active. When the node is deactivated, it will either disable or destroy the actor after offloading any relevant information. I have another array that contains struct data for the abilities that is needed to initialize them, since there are some things in the initialization that are character specific. The rest of the info is contained on structs in the ability actor.

Part of the way I am saving overhead is by isolating certain behaviors/affects into their own components, so things like burning/freezing behaviors and DoT/Poison/Etc affects are managed outside the actual ability implementation. I am trying to limit the amount of functionality actually coded into the Actors. hopefully I will get it down to the point where they are a data only class, which means the could be abstracted to a prototype and generated based on table data.

Thanks for the feedback.