Hi. I feel rather stupid asking something that is likely going to be trivial but, for the life of me, I can’t figure this out…
So I have a blueprint in which I placed 6 different meshes, scaled and rotated accordingly since the base static meshes were all of different sizes and orientations. My goal is simply this:
When you get to “level 2”, set the visibility of the second mesh to visible and the others to hidden. Same with level 3 etc etc.
So I created an ActorComponent class and in there I placed a static mesh TArray but this wants me to select meshes from the project, not from the children in the blueprint. So how do I tell my array “The static mesh called Level0 is the first entry in this array. The static mesh called Level1 is the second entry in the array” etc?
If I hold soft references to assets in the project then I am going to have to manually load them into this blueprint, scale and rotate them, write the values down in Notepad, delete the mesh, add those values to 2 variables and then when I spawn them at runtime manually rescale and rotate to once again match what I did manually. That seems super redundant when all I want to do is change the visibility of meshes already in a blueprint
What am I doing wrong here? Am I just going about this problem the wrong way or…? How can I achieve this very simple goal?
The idea here is that a player selects a spot on the map, click on “buy”, select an object to place there then “poof” this prefab spawns there with the mesh specified as level 0 visible. From there they can click on upgrade and poof, the next mesh is visible.
So the sort answer is that the blueprint will be spawned in the scene and then the ActorComponent class needs to function on it from there.
Think of any tower defense game to give you an idea of what I’m trying to do. You spawn a turret here, then another one there. Soon you have 50 instances of the blueprint spawned and need to upgrade each one individually.
I noticed someone recommending you add tags and search for scene objects by tag but, like I just said, I need to upgrade them individually so tags are not gonna be of any help since that will find the blueprint and I don’t need that. I will select the blueprint by clicking on it in the scene. Then I just need to tell it “Hey, upgrade, please” from the popup menu I will spawn at it’s location.
That is the goal here. It sounds like it should be super simple but, yeah, I am stuck on this part of the puzzle.
Thanks for the assist. Greatly appreciate it.
P.s. So I originally had it as an array of Static Mesh and that let me search for meshes in the project. I then changed it to Static Mesh Component and that gave me some weird options. It looked like it was letting me choose classes rather than components. I selected Static Mesh and inside that it then gave me plenty of sections including one where I can select a static mesh from the project again.
You can go both ways with one static mesh component and multiple meshes from an array or with multiple mesh components that you make visible when needed.
Lets say we go for the single mesh component as i think its a bit better.
You will have an array of static meshes and an integer to keep track of what mesh is currently active.
Each time you upgrade your “level” you add 1 to the index, select the corresponding mesh in the array using the updated index, and set the static mesh of the component to whatever is returned there.
…but in C++ and, hopefully, not as ugly as “Find root component and then find each child then loop through all the children then test by tag if this bla bla bla”. I am looking for a way to say “If my int is at value 2, set Meshes[2]->Visiblity to visible”.
The question here is how to do I populate the array at design time or is that not possible?
I cant drag and drop something from the blueprint onto the actor component in the component because dragging selects the item i am dragging.
I can’t select the mesh from the project because they need to be custom scaled and rotated at design time
I can’t select components of the current blueprint them from a dropdown in the blueprint because they simply don’t appear in any dropdown.
I am hoping that I am just selecting the wrong type for the TArray and by changing that to something proper the child elements will appear in there (touch wood). Just waiting on someone to tell me “Use UThisOrThat” (touch wood it’s that simple)
Alternatively, should I manually tag each individual mesh with a unique tag then during begin play find all child components and evaluate their tags, hard coding them into array slots and then say “There, my array is populated”. Is that really the only way?
@JansenSensei You are looping through your components in your last picture.
You can do it with multiple components as well but let me keep my original example:
Have 1 static mesh component in your BP. Only 1.
Then, add an array of static meshes as a variable. Add meshes to it from the editor at design time, in order of “level”. So for the mesh at index 0, pick the mesh that you want for level 0 (or 1), and fill the array with this order.
Now, in your upgrade event, you dont need to loop through anything. Grab your one and only mesh component and set its mesh to whatever is in the array at the level you just upgraded to.
Sorry i just realized that you want them custom scaled.
So, you can solve that in a few ways: have various static mesh scaled as you want, set position in code during the upgrade event.
But if you want to have multiple sm components already scaled and positioned and just toggle their visibility (watch out for doing so also on collisions though), you can do it:
Add your N sm components with their mesh. Set only 1 to be active and visible. Then you can recognize them by tag (component tag = “1”, “2”, etc. Or just define a mapping in the bp graph. So when you upgrade, you check which level you are upgrading to and you reference directly the corresponding component in the graph.
Id still try to do it with the single component though if possible.
Find all SM the way I did in the example I posted and add them to an array at runtime based on their tag values
Then I can reference them via the array directly at any point after that
So you are saying it is impossible to set the array at design time
That was my conclusion also but I thought “surely there must be a way?”
Oh well, so be it. Your answer is the only answer so far so I have to assume nobody else has a better solution.
I was really hoping this would not be the case. I am busy creating a sample project demonstrating something else and this was just a visual representation of what I was demoing. I was hoping to publish this project for free and give people a simple starting project. This messing around with tags per mesh vs just adding them into an array is gonna mess up the whole “simplicity” of everything.
I am wondering if I shouldn’t reimagine my entire approach instead Hmmm…
Anyway, before I stat rambling, thanks bru! Appreciate the assist!
You can setup a mapping at design time. This is a very simple thing but i feel with words it seems harder. As soon as I have a moment later today I’ll set up something similar and post some video or pictures here.
I setup a sample here. I’m circling through the levels with a button event I setup in the level BP. The “design time” boils down simply to assigning the meshes you want to the SM components you add to your BP. Although…I am still not sure why you need to edit each mesh Transform inside the BP. I’d just adjust the whole BP actor transform. Then again, depends on your use case so you decide on that. 2024-11-08 14-07-20.mkv (6.5 MB)
I read through this very quickly so may not be applicable but from a glance you might want to give each mesh it’s own actor blueprint. You can have 1 main static mesh blueprint that has a static mesh as a variable. Then create child blueprints and change the static mesh. Then put those in your world. If you want each world to have it’s own layout of static mesh blueprints, look into Level Streaming. Level Streaming may be another solution for what your trying to do.
The assets were not made for the purpose I am using them for (most asset packs on Fab won’t be). They were made to be placed anywhere in the level by hand. I want to force them to fit into a grid so I need to slightly tweak some meshes while rotating some and ever so slightly move some slightly off center.
In the example pic I posted above I am trying to upgrade two sticks with a rope between them to a small wooden fence then to a large wooden fence then, finally, to a brick wall. In another example I want to upgrade a pot into a cauldron. A small pile of hay into a large pile of hay then into a stacked pile of hay bales… the list goes on.
This is where your solution fails. The system I am trying to create here should be able to handle any number of meshes from any asset pack. Say I create 3 blueprints: One can be upgraded once, the other twice and the other 5 times. Your solution seems hard coded to n levels per blueprint so it is not ideal as i would have to hard code that for every blueprint I create. Ideal would have been to add those meshes to an array and then use the array length as the indicator to determine if the level can go up or not and to access only the mesh I want without having to hard code level 1 to be the cube and 2 to be the pyramid in the current blueprint etc.
Having said that, this entire example is merely the latest in a series of cases that have cropped up over time where I wanted to access child components on a blueprint and had no idea how. I see you used “Get Components By Class” to fetch the meshes. I think THAT is the answer I was looking for! Ideal would still be to do what I originally asked for which is to somehow place the child components into an array at design time but, at least this can get me going.
Add a tag to each mesh, use GetComponentsByClass to fetch them all and sort them into an array during BeginPlay. At least then I will be where I wanted to be. Still find it strange that there is no way to do this in the editor But hey, at least I can move forward from here…
But then id go back to have a single mesh component and an array of static meshes to choose from. You should just make sure that your meshes are already scaled and pivoted correctly. You can do it quite easily in editor with the modeling tools (shift-5). Check the section X-Form and you can bake new transform and also edit the pivot.
This allows me to do what I want while also giving me the option of having child SM on some of the levels (like my brick wall having 2 meshes stacked on top of each other)
This is working perfectly now. Thanks for all the help!