Im trying to optimise some of my bigger blueprints by doing some bits in c++ instead and was noticing when looking at stats in the Frontend that just plain component transforms are taking a lot of time. Just things like SetWorldLocation and SetRelativeRotation.
These seem to be mostly StaticMeshes.
Does anyone know if it is possible to speed these up?
If I wrote those nodes in c++ wouldn’t it be the same as the Blueprint nodes already are?
EDIT: I had a thought do you think the numbers reflect the calculations that are connected with feeding into the transform values?
Ie not just the transform setting itself but also the math I have leading up to it, that are not executed. Mults etc?
Its possible to speed this up yes. without knowing much about what bottleneck you are hitting, you could likely be running into child component transforms needing to be updated. At any rate a simple list of items:
Avoid calling these things: Instead of using that->SetWorldLocation(that->GetWorldLocation() + Offset), first check that Offset is not zero or that the GetWorldLocation does not match what you are setting it to. ( I would’nt suggest getting the location every time however ). Also specific to this example, use AddWorldOffset. When you call these functions its likely that all child scene components that are relative to it are updated before the return of SetXLocation / Rotation.
Take number 1 and applie it to the pair of rotation and location, if you determine both need to be set use SetComponentTransform instead. I’m unsure if the implementation of these optimize for that case on all component types but it can be assumed they should if they do not already.
Take a look at documentation for FScopedMovementUpdate
If you’re still having issues, tinker with the idea of detaching components and reattaching them later.
I’m still getting into the engine, so someone may have more specific advice.
You wouldn’t get much performance benefit just writing out the nodes in C++ to be honest (unless you’re doing a lot of these each frame, but even then the blueprint overhead isn’t going to be the main factor). The calculations that create the transforms might be faster in C++, but that’s hard to say without seeing what you’re doing.
Make sure you’re not calling Pure nodes too often, cache the results and use those. This is a common error in Blueprints.
Realistically start by trying to reduce the number of Scene Components that need a transform update. Combine some meshes if you can. I’ve seen a lot of cases where people add scene components to blueprints just to change the orientation of something (don’t do that you animals, fix your pivots!) - which just results in unnecessary transform updates.
As mentioned above, FScopedMovementUpdate can be useful if you’re potentially moving a parent component lot’s of times per-frame, which has child components attached (child transform updates are applied after the movement update struct is destructed)
What I mean is don’t do stuff like this, because it results in the Pure node being called twice:
To my knowledge, using the nativizer doesn’t solve this problem either.
EDIT: This is a bad example because ‘Branch’ is just a macro, but if you have the outputs of a Pure node hooked up to multiple ‘Callable’ nodes, they’ll get called for each callable node.
I have to check out the thing you say about ‘Pure’ BP functions as I wasn’t aware of that distinction. Very useful to know that your example there gets called twice as I’m sure I do quite a lot of that. It’s just so annoying to having to add more variables to the global Event Graph, I suppose I can make a function but now I’m probably converting to c++ anyway.
Here is an example of a ‘transform’ that is ‘slow’ it gives me two times ~0.15ms which is slow for me as I’m doing vr and need to pack it all into 11ms. This is in Tick and so executed 90 times a second.
I have given up on the Nativizer it doesn’t work for me since I added Gamesparks and have lost enough time trying to get it to work. I’ll just spend the time converting to code instead it seems a more sure and future proof bet.
EDIT: Oh and I’ll definitely look into the ‘FScopedMovementUpdate’ thing as well as that sounds very relevant. Many of my setups like these are VR/Motion controlled character animation rigs so I am calculating different things in sometimes fairly complicated hierarchies to make it all work.
All blueprint pure nodes, since they don’t have an execution wire, are called every time you ask them a value. In your example, you are using 4 times the result of the Make Transform Node, this means that this node must be executed at least four times, since it does not cache its result. To make things worse, this happens in cascade: each time your Make Transform node is called, it relies on values computed by other blueprint pure nodes. Therefore, they must be executed as well.
So, worse than having pure blue print nodes and not caching its values, is having blueprint pure nodes using other blueprint pure nodes, that are using other blueprint pure nodes, and so on…
I wanted to revive this thread to ask if anyone knows of any easy(ish) to understand implementations of FScopedMovementUpdate?
I tried a few things but even packing up all the pre-calculations for the transform into c++ hardly got me any speed improvements at all.
For some actors I tried doing Actor transform instead of the component-parent transform but no gain there either.
I find it strange that simple transforms with not many (eg 2) sub components should be so relatively slow.
But I also have some main actors with many sub components that are being transformed in complicated ways. Think a separate robot animation rig.
That’s where I would like to test this scoped movement method.
Does anyone know of any such code?
I scanned the UE engine source and had a quick look but I couldn’t really make sense of it. Maybe if I spent a long time on it but I was hoping maybe someone knew of a clearer to fathom use?
Scoped movement is for if you are moving something possibly multiple times a frame (ie: characters, they take a lot of movement tests over a tick), it delays the physics update and the final overlapping check until the ScopeMovement goes out of scope.
To do it with something with sub components you would
{ // Start of scope
FScopedMovementUpdate(ComponentPointer, EScopedUpdate::DeferredUpdates);
// Run complicated multi movements here
} // Here the component actually updates to the physics thread and checks for final overlaps
Those final overlap checks and physics thread updates are fairly costly.
You can also nest them, scoped movements find their parent scoped movement and don’t update if it is deferred as well.
Thanks. Hmm so could I write a blueprint node to be placed at the beginning of my characters Tick that started/opened the scope up.
Then do the majority of transforms as usual in Blueprints.
And then finally close/execute the scope with another c++ blueprint node placed at the end of Tick?
Or would I have to do All the transforms in c++ after that first FScopedMovementUpdate( line?
EDIT: Also could I do this referencing in just the top parent component and it would automatically deal with all child components?
Or would I have to build a tree structure and start off separate scopes for each child component?