Instance Static Mesh Component?

Hello, I have this conveyor (Image Attached) that has multiple “pins” that I would like to rotate. Now I added maybe, 30-40 conveyors in my game and had them each rotating all their pins, but noticed a huge performance drop. Now, I know there are animated materials however the pins are octagonal so having an animated mesh wont look right.

So the other option was to use instance static meshes however I haven’t found a video explaining how to do that with components of a bp. But now if I go this route, is it better than just having them as static meshes?

I understand you must be new at this.
rotating vericis in a material is exactly the same rendered effect of rotating an object in game.

It costs less to perform simply because the calculations are happening on a GPU instead of happening on both the CPU and the GPU.

That said.

Your conveyor belt probably needs to function with some sort of localized action unless it’s powered - in which case it should probably be a mat, rather than a roller.

Normally, rollers like those you created are free to roll and only actually rotate as something slides over them…

That could indeed be a pain to achieve but it doesn’t have to be by using a proper material and a properly setup mesh.

first, you need to set up the mesh.
each roller needs to have a pivot point you can use to rotate the roller in the proper axis.
you can use Vertex Pain and simply paint each roller with the normalized value of its x/y/z (r/g/b) location of the pivot.

That makes it possible to isolate and rotate individual rollers via a material.
I would use the Alpha as a mask to apply/block the effect btw.

Next up, you need to axis in which the rollers roll. That’s mesh dependent so you need to cross object rotation with whatever the axis of the mesh (looks to be X, your red arrow points).
that produces a localized value of the axis which changes in real time.

Bring in a Rotate About Axis.
plug time into the rotation angle.
The axis from above as the axis. (Cross should already be normalized I think)

The solved pivots.
Vertex paint r/g/b x mesh size (because you normalized their value). transform vector -> local to world space.

and absolute world position ad the default.

That should get the rollers to all spin.

localizing this effect is a bit tougher.

you have to use some kind of a mask that triggers the behavior On and Off only when the pivot itself is marked to be activated.

I would suggest a material parameter collection with a location value of an object. But then you couldn’t support multiple objects.
So render targets become your best friends.

How you generate this matters for performance.
You have 2 options.
Draw to render target, or scene capture 2d.
drawing is usually for 1 object or a limited number.
scene capture 2d can handle almost anything (at a cost. You are rendering).

With either pathway, you have to localize a world aligned texture (converted to parameter to which you assign the RT result).
usually something like world position / 1/2 of texture size. There’s tons of ways to map it. Just need to use one that makes sense for all the objects or the whole room.

Then you need to sample from that RT. What is active and what isn’t.

Because you already have the pivot this become somewhat trivial.
take the pivot output, divide it by the texture size, and use the return value in a lerp (or IF) in which you either trigger the rolling effect on, or keep it off.

if it seems like a lot, it’s because it is.
But the cost of it is cheap as dirt, given I have at least 20 similar effects running across different things.
water interaction, flow maps, grass interaction, spiderwebs etc.

​Any time you don’t need a collision response, you can leverage a material vertex offsets.

Should you really want to have actual collision on each roller…
may I suggest a skeletal mesh?
it would be a lot easier to have the rollers act independently via a PHAT asset. Obviously you will hit performance limits with too many meshes in the level. But at least they don’t all overload the CPU because the simulation is local.
mind you the physics will glitch like crazy and the objects on the belt are liable to fly out of the room.

Thanks for the well detailed response however, I forgot to mention something about my design. As of right now in my game I am going for more of mechanics rather than looks, once the game runs as it should I will go back and add actual textures, more stuff in the models, in this case, I plan on a way of adding a way to give it power.

So, in this case, I dont want the rollers, to actually be the thing moving the object, rather, in the image I sent, there is a box collision that adds an offset to any object in the collision which then moves it along. What I’m trying to do is make is so that it looks as if the pins are moving the objects.

The above applies to “just the looks”
Actual movement of the objects would have to be handled differently and captured either via variables in a material parameter collection or in a render target.

if all the rollers roll at the same time, then the first half of the post still applies.
Except you could make all the rollers the same instance, and then ofc use HISM component inside the roller frame BP to instantiate 10000 instances.

Im trying to get some of this stuff set up in the material but some of the stuff said makes no sense. Is there possibly a video explaining this or screenshots?

which parts make no sense?

x2 speed for better enjoyment :stuck_out_tongue:

That helps much more. I am more of a visual learner so seeing things for me is much better than reading. So I made a video as well explaining how my game will work, where in your video you were showing how you had what looked to be an array type system that could expand the amount of the conveyors you have where in my game each conveyor is its own separate thing. So linked below is my video showing how it will work.

In my eyes, if I use HISM for the pins on the conveyor BP, and just made the mat, it should run much better but I dont really know.

https://streamable.com/zv4xrn

Definitely use the hierarchical instanced static mesh component.

But the reason your game speed was reduced with 32 conveyors is the fact you are using OnTick on all of them all the time.

First… that’s not “right” in terms of best practices for a lot of reasons. You saw it yourself as you had issues setting up the objects that can move vs those that cannot.

You should change it so that a BP interface is used on the objects.
When they collide with the conveyor belt, they will look up the direction to move and move them-mself via timeline.

This will reduce the load from 35 tick events always running to however many items need moving. Only when they need moving.

Another suggestion.
setup the base mesh as a hierarchical instance too, and when items snap together, remove the item, span an extra instance…
the way you have it now you’d have to duplicate the collision box too. I would actually just use the pin collision like I had it running on my end, so its completely modular.

that’s about it. Removing the on tick will probably already get 120 fps without the HISM. But think big :wink:

Wow, I though about doing the spanning of the conveyor but never realized how. So, I guess the next problem is, my placement system, which moves the object your holding to the location where your looking and then I use the function VectorSnappedToGrid which is what essentially gives it that snapping effect, so I would have to figure out how to know if the object it being place next to is of 2 things, a conveyor, and pointing in the same direction, if those are both true, then extend the one that is already placed.

In the code of the base class, I have a bool variable that is set true when the object is placed. When you left click to set the object your holding placed, check to see if there is a conveyor on one of the fours sides, check if its variable is placed, if it is, and its direction is the same, remove the object I just placed, grab the conveyor that was already placed, and extend that one.

What do you think?

Few things to look out for.
needs an even ground.

You Can actually spawn and rotate instances, so the whole thing could be the same BP with more instances. You just have to set the correct rotation on each instance.

I would suggest a box collision trace to detect nearby items, and decide how to place it.
Thsi can expand to turns, cross sections, splitters, sorters etc. Even if you aren’t building Factorial from scratch :stuck_out_tongue:

I would set the spawn up as an event call with pins. So you can just make the call, and pass the parameters form anything that can “reach” the actor programmatically.

Nice. The current problem is as you said, the ground. The terrain in my game will be uneven and have noticed that at some points the placement system will place the object halfway through the ground however I dont know how to make it so that it doesnt do that, because at some points they are floating a little which Im fine with. Now since I use the vector snapped to grid function, I dont know if there is a way to detect if the hologram is inside the terrain, and if it is, just raise it up like 1.1m so that it goes into the next grid.

Possibly a line trace or even the same box trace can check for terrain collision.
how you Hanke it is the hard part.

You could also make it so it can only be placed on floor tiles, ARK style

I see. The problem with only doing it with floor tiles is that in my game there are miners that will mine for resources like stone and iron. So I guess the thing with that is maybe the miner has to be placed on a certain foundation that has a hole in the center for the drill to go through.

Its hard because there are very little videos on this type of placement system but have seen it used before.

if thats the case, why not just deform the frame programmatically and allow the rollers to place with a fixed z distance from the floor? At build you need to run a trace for each roller.
only becomes an issue if you trace over 1000 items at a time.

For adjusting the frame you could either make it a spline with a segmebt each roller. Or a segment each meter so it matches the default landscape.
same for the rollers one trace per meter should do if they snap to the world grid.

To keep the frame going as a hism you could change it to be just the legs, and spawn a new instance for the final spot every meter or similar.
won’t look as nice, but it will easily conform.

I dont want the rollers to be to a set height. How the player places the the conveyor and other stuff in game is how its going to be, the problem is that sometimes the object is placed in the ground, so far where only the rollers are shown and not the frame.

The problem you get is the possible disconnect between rollers.
if you need to provide them as a feature that helps the player by moving stuff (ore?) From inside a cave to their work area, then they definitely do need to conform to the terrain in order to generate a continuous path that the object can slide on…

Sharing, just for fun really.

You guys peaked my interest so I put one together using the Rotating Movement Component.

Demo has 96 conveyors. Each conveyor has 6 rollers (576 RMC’s).

The conveyor prop would be a single mesh with a panning material for the rollers. The roller mechanic is an actor class with a capsule collision scaled to the pin w/ RMC. It also has a box mesh to trigger/control RMC.

Begin play I spawn a roller for each pin and add a reference to an array.
On begin overlap of the box (pawn, pawn capsule etc) I loop the array an update RMC (set active = true).
On end overlap of the box (pawn, pawn capsule etc) I loop the array an update RMC (set active = false).

Only issues I’ve run across is when on the conveyor, RMC has a tendency to rotate the character as it pushes you along. Once rotated perpendicular to the movement direction it stops.

Surely it has to do with the collision.
You can’t use the same method I use for the box on a character - And even in my case - because each pin has separate collision, the tendency of the box is to stop moving when you activate sweep.

the RMC is a nice alternative, but you’ll eventually run into issues when scaling up instance count in the thousands.

Since the effect is really only local, I’m even considering placing a “camera distance” check on the actor managing rotations to better preserve performance. On a shiny roller you can’t tell if the rotation is happening past 10m or so anyway, so that’s something to consider.
Perhaps you could limit your RMC in a similar fashion as well.

Past that, the only performance limit would be the number of non instanced meshes. And usually you can have billions of tris before it starts to be a problem.
ok well, maybe billions is a bit of an exaggeration. But you get my point.

I’m banking on auto instancing, culling, occlusion and that only one conveyor block (6 rmc rollers) is active at a time per moving item. Not bad for a quick poke at it.