I have a generic blueprint (parent) for any interactable object (which will be the child components).
These child components can be of 2 types of meshes: static or skeletal.
I understand I can leave the parent component without adding a skeletal nor static mesh and then add them in the child components.
The problem is that according to the logic of my blueprints, I have to reference both the skeletal mesh and static mesh from my parent blueprint, since that’s where the logic is set up.
Edit: I have the logic in the parent blueprint, but I need to use the static meshes and skeletal meshes from the children so that the logic affects these components from all the children. Hence, I need the skeletal meshes and static meshes in the parent component. If I add them here, I have the problem explained in point 1 down below.
I have thought of two ways to fix this:
1- Create static and skeletal mesh in parent blueprint. In the child blueprints deactivate the one that that child should not use (by deactivate I mean set it to no collision, and uncheck the start with tick option so that this component does not tick). I don’t know if this will cause problems both in the logic and in performance, since we have an extra component that’s not used in each child.
2- From the parent blueprint, create 2 child blueprints that will be one with static mesh and the other with skeletal mesh, and use these 2 child blueprints as parents to the instances of each type of mesh. But if I do this, I’ll have to change all the logic of my blueprints (interfaces mainly).
Which option do you think it’s better? Do you know of any other way to do this?
That’s a bit of a problem, but not one you need to solve.
Interactable objects vary way too much to use a common parent class. Use an interface on the objects instead. Make a solver and add it to each player.
The objects themselves would handle the range and relay that to the solver(s), and the solver(s) would choose which object is the interaction target based on distance.
For me I’ve set it up such that interactable objects just add themselves to an array in the solver that records them as in range. Then I just iterate through those every frame to find the closest one, call the interface asking if they’re able to interact at this time, and then highlight the chosen one.
You could also make the solver a per-player subsystem if you like CPP
Sorry but what are you referring to as “solver”? Do you mean IK solver form the control rig?
In my case interactable objects will not vary that much.
I will basically have: melee weapons, ranged weapons, clothes and miscellanious (food, random items, etc.). The last one will not stay in hand but rather go to an inventory.
I’m using a raycast to detect these items and based on the type some logic or another applies to them. For example attaching to hand, attaching to hip, etc. The problem is that I have to use “set collision response to channel” that need a reference to the static or skeletal mesh. If it was just one type of mesh, I could just add it to the parent, since all children would inherit it, but since I have two types, it’s more tricky, as I explained before.
I’m following these tutorials (I’m right now in the second one). The only difference is that he uses only skeletal mesh weapons, while I have both skeletal mesh and static mesh.
And to use an interface on the objects what do you mean? Right now i’m using enums to define pickup object types (melee, ranged, clothes, misc.) and the list of objects (all items instances). Then with a blueprint structure I define variables and finally with a datatable I relate the objects with the types.
I need a “set collision response to channel” for each type of object (in the switch). Now I can do it because I have both the meshes that will be used for one or another child blueprint (since some use static and some skeletal). I don’t know if this will bring me any problem later on.
Then in each child blueprint I select the type of mesh that fits the object’s mesh (skeletal or static) and I set the other to no collision and to not tick.
The other option would be to go to number 2 of the original post.
Ahhhh. When I said solver it was more of a term meaning a custom manager for every player- that would just end up being a component.
But if all you need is to set a collision response to channel, that’s easy. SetCollisionResponseToChannel is a function for PrimitiveComponents.
static mesh and skeletal mesh both in some way inherit from primitive component, so we can treat both types as a UPrimitiveComponent
The most scalable option would be to have a function in the parent blueprint that returns a primitive component. Realistically you’ll probably want to make this return an array of primitive components since it’s unlikely you’ll have only one mesh for every interactable.
One question. Is it better to have intermediate parent blueprints to capture the common component that would be the static mesh or skeletal mesh or just override the function in each child?
Maybe this makes it clearer:
Now I have a master parent blueprint that has as child all the rest, no matter if skeletal or static meshes. Your function works just fine like this, but I have to override it in every child.
Another way to do this is: from the master parent blueprint create two childs: one with a generic static mesh and the other skeletal mesh. Override your function in these two blueprints. Then from these two blueprints make childs for each object, depending on if they are static or skeletal mesh respectively.
I still really dislike the idea of using a common parent class instead of an interface, but you’ve already gone this far.
My latest thesis…
With this method, you don’t need any intermediary classes. Intermediary classes for something like this would be really really bad- you’d literally have duplicated code. The whole reason functions exist is so we don’t have to do that.
It’s a good idea to have a common parent that handles it, but only to the point it makes sense. Them sharing a component isn’t enough justification. Don’t create a parent class that a beach ball and sword both inherit from just because they both use a single static mesh. That just adds unnecessary complexity to your project and clutter to your content browser.
You should have one shared class for every weapon using a datatable for everything, but that might be a bit much too much to explain at this stage.
You don’t want to call the parent function in any of these. You would connect “StaticMesh” in this case using the make array node. As a side note, you shouldn’t leave components with their default names- ie “StaticMesh” should probably be called “SwordMesh.”
You can do the exact same that you’ve done in here, or if they’re exactly the same just with different meshes, then you can have them inherit from a parent class and just not override the function in anything but the parent class.
Keep in mind that the parent BP doesn’t care EVEN THE SLIGHTEST who inherits from it. It alone will do the exact same thing no matter who inherits- absolutely, no exceptions ever. None.
But we’re not spawning the parent BP, we’re spawning a child that inherits from it.
Any given object is only a single class. Say we have a class hierarchy that goes something like:
Bow → RangedWeapon → Weapon
Say we have a function [DoStuff] in Weapon that prints out “I’m a weapon”
In RangedWeapon, we completely override it to teleport us up 500 meters
(completely override as in we override but don’t call the parent, unlike what you did)
In Bow, we completely override it to delete every enemy on the map.
If we spawn Bow and call [DoStuff] then every enemy will be deleted. We won’t teleport, and we won’t print anything. It doesn’t matter that the parents do other things, we’ve overridden the function to ONLY delete every enemy.
If we spawn RangedWeapon (which would be an abstract class so we wouldn’t actually spawn this or Weapon directly) and call [DoStuff] then we will teleport. We won’t delete anything, and we won’t print anything.
If we spawn Weapon and call [DoStuff] then we will print. Nothing else.
That was assuming we’ve completely overridden, following the provided definition. If we instead override and call the parent function [DoStuff] as well (as you did in the GetActivePrimitiveComponent example) in all the children (RangedWeapon & Bow) it’ll be a bit different.
If we spawn Bow and call [DoStuff] then every enemy will be deleted, we’ll teleport, and we’ll print. We’ve overridden the function, but we’re calling the parent function (RangedWeapon’s DoStuff) and that parent is also calling it’s parent function (Weapon’s DoStuff) so all of it is executed.
If we spawn RangedWeapon and call [DoStuff] then we will teleport and print. This exact same stuff would happen if we spawned Bow but didn’t override [DoStuff]. Since we didn’t override it, the parent function is what’s called.
If we spawn Weapon and call [DoStuff] then we will only print. Nothing else. It doesn’t matter what the inherited children have overridden the function to- we aren’t one of those children, so nothing has been overridden.
I’m still reading (and trying to understand) your answer.
For now, you said that it would be better to use a BP Interface. Could you please elaborate? How would that be better and how could I implement it? If you know of any video tutorial, or article, etc. for reference.
Edit: I think I would be able to set a BPI for one object only, that’s how I had it before I followed this video above, but in order to generalize it for many pick up object types and many objects inside each type I am having problems understanding the process.
Edit2: for many types I mean for example: longswords, shorswords, bows, crossbows, food, clothes. And for many objects inside the types I mean that for example for longswords we could have many variations of it (rusty sword, good quality sword, etc.) and each would have different stats.
The player has a solver component and calls an event on that solver when they press a key.
Both of the actors in the interactable folder implement the CustomInterface_Interactable interface. Two of the methods are events, one is a function- you can see the function in the interface dropdown.
The solver is easily the most complicated part, but it’s still simple once you’ve realized what it does.
As a side note, the 'CanInteract?' interface event is called every frame, so keep it lightweight and try to cache what you can.
This also only works for singleplayer purposes- I could make it multiplayer if you'd like, but that'd take a bit longer
My game is singleplayer. Okay, now I understand what you meant for solver component. I was misinterpreting that it could be a preset component and I didn’t recall anything like that. Now I see it’s a custom component.
In your blueprint I see that you use the tick component, while I would rather trigger the object detection logic by pressing a button, so that it does not run at runtime (right now you use an overlapping event at tick I think but I have to hold E to inspect objects through tracing and receive info about them and upon releasing E the interacion logic triggers and the
last collided item is the one picked up). I prefer it like this than proximity, also I think it’s simpler. What do you think? Maybe for NPCs your system is better, as I said before I have not looked into NPCs yet.
In your previous comment you said “(completely override as in we override but don’t call the parent, unlike what you did)”
Do you mean I should delete the brown node?
Also, do you think it’s possible to just have one interact logic in the parent blueprint (or a component) and use this logic to play different montages depending on the type of object that has been interacted with (open door, pick up weapon to go to sheathe, pick up miscellaneous item to go to inventory, etc.) instead of making one component per type of interactable object?
Still I have the question: is using components more performance friendly than using inheritance? I plan on adding many NPCs in my game (maybe using Niagara for far away enemis) that will be using this component, is it better to add the solver in each character blueprint or should I just add it in the parent blueprint and let the rest of character blueprint instances inherit from it?
I just want to reiterate this after writing the post just how much you should use an interface. The proximity setup and interface are mutually exclusive- you can have one without the other.
Yes, for a first person project it would be better to use a trace. Proximity doesn’t care which way you’re looking, but that matters a lot in a FP game.
Same case with interacting with NPCs- traces are better. As for the NPCs interacting, they wouldn’t use any type of sensor- you just tell them to walk to a place and interact with the thing, you don’t use the systems built for the player.
The tick logic is for a prompt, you’d need tick for a prompt/outline no matter the interaction method.
That line was just for the examples below it, but yeah with that system you’d want to delete the brown parent node. I was just referencing what you did so we were on the same page.
You can ignore the solver, but absolutely use the interface.
It’s possible, but you shouldn’t do it. Each interactable should handle it’s own logic. Unless you have dozens of interactables that solely play a unique montage with no other logic, it’s not worth the smell.
I’m not sure what you mean by this… neither system requires making a unique component per interactable type…
I strongly recommend you look into inheritance unrelated to Unreal Engine. It’s extremely important that you fully understand it.
Inheritance doesn’t have overhead.
But more towards the purpose of the question, don’t use either. Use an interface- I cannot stress how much better that they are for this.