I find myself pretty regularly using a lot of specific conditionals in my anim BP’s state transitions or blend/transform nodes. This causes a lot of nodes and transition rules to lose their “fast path” indicator and throw warnings. My understanding of the Fast Path is that the FAnimInstanceProxy has native ways of passing around values that are faster than calls to the blueprint VM, so it’s best practice to set variables in the Event Graph when doing computations rather than asking the AnimGraph to perform them. e.g. if I need access to the dot product of my velocity and my character’s facing direction (to get strafe or walk values for blendspaces) it’s best to compute those one time, store the variable, and then use the fast path to access that variable in multiple places in the AnimGraph.
The issue is, a lot of very simple operations break the fast path. For example, I have an enum that holds my character’s locomotion state; if I want to transition states, I use an Enum-equals check to determine which locomotion state I am in and perform the transition. This is not a fast path operation. It’s about the most simple boolean check I can perform, but it’s got to call the blueprint VM. Now, I can work around this. I can create a series of setters in the AnimBP that perform this check, and turn my enum into bIsRun, bIsHover, bIsSlide, bIsDash, etc. inside the animBP. My question is: is this really any faster?
Most of these variables would be used in only one or two places, to dictate specific transitions. Is it worth it, from a performance perspective, to do ALL logic operations in the event graph rather than the AnimGraph? Even if there won’t necessarily be any copying around of values? Surely that just moves the VM overhead from one place to another; the variables still have to be set/got, and there’s no optimization from their re-use if they’re only used in one place? Or is there something about the way the AnimGraph is evaluated that makes it always faster to do these computations in the Event Graph?
There are some other instances that have cropped up:
- use of a float variable which has a different simple multiplier for scaling its effect in various places in the animgraph. Should I create a dozen variables, each of which essentially contains “var * 2”, “var * 1.75”, “var * 0.25”, one for every place it’s used?
- same as above, but with clamp ranges, or negations (i.e. 1-x)
- computing a rotator for a Transform Bone operation: the rotation is specific to the use case, so the computation has to be performed ONLY for that one Transform Bone. I would need to compute a series of rotators so that each of those Transform Bone nodes could be fast-pathed
- Places where the logic simply cannot be translated to fast path; e.g. if using a Get Relevant Anim Time Fraction node (which can’t be used without a state machine context) fast path breaks for a transition. If using Layered Blend Per Bone, fast path simply cannot be used period it seems; if these nodes are present in a state, is there any point in trying to optimize the REST to use fast path, as these nodes themselves will force fast path to be abandoned?
It feels like the warning system is insisting that best practice is to never, ever avoid fast path (except in cases where you’re testing or experimenting and it would be too cumbersome), but is it possible that there are contexts where the “fast path” is actually the slower route, because it produces savings in the AnimGraph that are more than offset by the additional costs in the EventGraph?