Im doing a project with lots of units. I came accross an issue that might not have a solution, and the explanation might be, “Thats just how it is”.
But i need to know that to make sure before advancing.
What happens is that moving instances of the same HISM is incredibly cheap.
But the moment you have included more HISM of different types. It gets ugly very fast when and only when moving their instances.
So if your game has only 1 HISM with units running around. Then it will be fine. You will be able to move many many of them around.
But the moment you include more unit types (so more HISM’s are needed).
Then the iteration through them will become 10x more expensive.
So basically 1 HISM component with 100k units moving all at once, may be better than 40 HISM with 200 instances each, and moving just 3 of them per HISM.
So one HISM is great. But nobody makes a game with just 1 HISM. You need more HISM for other unit types, like spearmen, swordsmen, archer, etc…
And that will cut a lot in FPS.
I made an example project that represents the issue. You have 1 actor with 1 HISM of cubes. And each one of them will Vinterp 3 instances. Thats not many. And you will see a considerable drop in FPS like 60.
Whereas if you have them all as one instance you can move many many more.
Is there something obvious im doing wrong here?
I tried profiling it. And i was told to profile it. But honestly i cant get anything out of it, and dont see the use of it here, since the issue is well isolated.
Thanks for the answer.
The code is visible at the end of the second posted video where i filmed all the code in the project.
But i will post it in screens here:
Yes I get the same drop. I moved it over to my c++ rdInst system and that is much faster, so it has to be the fact it’s Blueprints (I’ll keep experimenting a little longer)
I changed the Tick Interval in yours to 0.0333 (=30fps) and that helped a lot…
I first had this system in C++. Made this small sample project just to show the problem using blueprints. But in C++ its happening the same thing.
The issue is related to having more HISM of different types rather than just one with many instances.
Basically if having more actors with HISM, then moving them becomes a problem.
And this is very limiting because my project requires different HISM for each different unit type.
Is this a normal occurrence? Is there anything we can do to improve this issue.
It just feels like something isn’t right. But maybe there’s no way around it.
I planned my whole project assuming that more HISM of different types would not be an issue, and was always more concerned with the number of instances.
Of course HISM is an amazing system. But to do an rts i need units of different types.
Change your tick time to 0.0333 - at the moment you’re setting their transforms 300-500 times per second, each - its a lot more performant only doing it 30 times per seconds.
I think that is all you will need to do.
I’ll reply with more information about the c++ side of things soon, once I’ve worked out why it’s faster in my routines… (Edit - it was faster because the framerate was locked to 120fps)
I see it drops a little less. Though its still is weird that these few instances vinterping cost so much just because they are coming from different HISM.
In fact if you try and have just one actor with one HISM and thousands and thousands of instances moving it wont be an issue.
Its really just for the fact its different HISM containing the few instances moving. Thats the only difference i can tell.
Reducing the tick is helping a bit. Thank you.
Though i think its weird that so few instances would cause this drop just because they are in different actors.
Yes it has to be the setup cost of the instance transform - having it only redraw on the last element (mark redraw) is probably the clue - if you only have one ISMC it’s only doing it once per “frame” - now it’s doing one for each ISMC there.
Static Mesh Instances weren’t really designed for moving around a lot, more for things like trees and foliage which don’t change transform - so I think it’s going to be a matter of using it sparingly…
You may find writing a routine that removes (or move’s to a hidden place) the meshes you’re wanting to move from the HISMCs and add Actors in their place - move those, then add them back as Instances afterwards is worth while.
Yes it has to be the setup cost of the instance transform - having it only redraw on the last element (mark redraw) is probably the clue - if you only have one ISMC it’s only doing it once per “frame” - now it’s doing one for each ISMC there.
Well, that occurred to me before, and so in the project i have included another blueprint that does exactly that.
It has only one tick event, it iterates through an array of all the HISM components, marks the render state dirty in the last instance of the last HISM component.
You can delete all the BP_ISM_Move_Single and drag and drop the BP_ISM_MoveByArray in the level.
You may find writing a routine that removes (or move’s to a hidden place) the meshes you’re wanting to move from the HISMCs and add Actors in their place - move those, then add them back as Instances afterwards is worth while.
How would this work? So temporarily replace the ones that need to be moved as actors? Wouldnt an actor be more expensive to move than an instance?
I think maybe this issue is normal, and there is no way around it.
Though a lot of the material we see around about having a lot of units give us this impression that we can make an rts with tens of thousands of units, because it shows 1 HISM type with lots of instances.
The reality is that no RTS will be made with one HISM type only.
But i think i can still do this with some smoke and screens and some hacky ways.
edit:
Oops there is just one mistake there.
Make the last instance == to the number of instances you are testing/moving.
Its 19 but it should be 2 to correspond to the instances looping:
Strange! That test always returns false (edit: sorry, overlapped) (index only gets to 3 so will never == 19) - I just tested it with MarkRender set to False - and then set to True - it made no difference to the frame rate (but it did update) so I’m wondering if it’s always forcing it to true…
Changing that tick rate down to 0.0333 made it so the drop was only about 30fps on my computer.