Download

How to use repnotify booleans to drive an animation state machine. ( FULLY NETWORK REPLICATED)

Hi guys so for a long time i have really struggled with the idea of multiplayer replication especially when it comes to animations. I know a lot of people struggle with this issue too so i thought i would share my methods. I had originally set up my animations using Blendspaces as they are simple and easy to use. After a while though i found them to be more limiting and restrictive and so i began experimenting with locomotion state machines. Luckily for me the unreal system isnt that different from the unity system and so i was able to get a decent system up and running with a little trial and error. anyway here ill talk you through it

so first i wanted to know when the player is moving forward/Backward, Left/right or a combination of both. I tried multiple ways to do this using all the different methods suggested on various forum posts such as using the players velocity, direction, axis input etc in the end i went for this setup for ease of use and flexibility.

so what i did was first create action mappings for each movment in the projects input settings like so.

6be22010152915403bee529c3924bae385cc8971.png

so obviously you can see that when i press W i will be moving forward. S key moving backward, A key moving left and D key moving right. Normal game WASD controls.

then in my character BP i then checked these player inputs to see which one the player was pressing.

I then created a custom event in order to use these inputs as shown here

16b2ed70784a482b589b5ab3814b5bd8e535c362.jpeg

so for each custom event all i did was give them a name similar to the action inputs. I then made each event set a boolean value that will drive my animation blueprint.

b7641dffe6544cc09a41ca765c382a8b.jpg

so for each boolean i made them into a repnotify and inside each repnotify function i simply casted to the animation blueprint and set the boolean to be the same as the booleans inside the animation bp.

so here is the repnotify function for moving forward

6085bdd6db074356b2b7d30b0271865d.jpg

as you can see whenever the boolean changes, the repnotify function is called and it simply sends the boolean value into the animation blueprint

inside my animation blueprint i simply have the booleans the same as in my character bp i just added ABP suffix on the end so that i can see that these booleans are from the animation blueprint.

21ef250fc48e490c99705d3ef73c06f8.png

And lastly i use these replicated booleans driven by my player input in order to drive my locomotion animation state machine
fb1d0e49d94d4778b7245a4177612b8b.png

so for example here is the transition rule for when the player can move from idle into walk forward. as you can see i simply use the replicated boolean . it is really simple .
f0a17621df83411b9a6b14ea058373bf.png

so the execution goes like this. player presses W on the keyboard >>>>> this calls the server RPC PlayerIsMovingForward custom event (run on server) >>>>>> this sets the boolean playerIsMovingForward inside the character blueprint to be equal to true. >>>>>>this variable is repnotified so it calls the repnotify function>>>>>> inside this function it casts to the animation blueprint and sets the variable playerIsMovingForwardABP to be equal to true>>>> once the boolean is set to true this causes the player to go into the walking forward animation inside the locomotion state.

here is a small video of the final result . first few mins is set as a dedicated server showing two clients. the second half of the video is set to listen server showing server and one client connected.
as you can see the animations still work and are replicated wether it is a dedicated server or not

if anyone wants any help with replication or setting up a system like this drop me a pm and ill try to help when i can

thanks guys

This seems like a pretty terrible way to do this… you’re networking stuff that should be local, you’re limiting the usefulness of your animbp which will now only work for players and not AI…

What issues were you running into doing things the usual way?

What you mean by networking stuff that should be local?? I’m confused .

Ok so originally I had it set up using blendspaces driven by the players direction and speed which was great for normal movement range but then the project leader wanted to add in running start and stop animations based off which foot was on the ground. How are you supposed to add these to the blendspaces? To go from running to stop you let go of the keyboard key at which point speed becomes 0 and player would blend into idle pose where as it should be speed 0 blend into either running stop left up or running stop right up depending on the feet positions then after running stop has got to end of animation transition into idle . No matter how I tried to set up blendspaces or the axis to drive them I couldn’t get the transitions into start and stops to work.

Also when doing print strings on player speed and direction I noticed things like speed never goes negative so when you run forward it goes from 0 to maxwalkspeed value but it also does the same for walking backward so therefore you cannot use speed to determine the difference between walking forward or backwards. With direction theoretically 90 would be strafe left -90 strafe right 135 strafe diagonal etc etc now although I was getting these ranges with direction value it was also fluctuating with wierd results depending on which way the player was rotated and if for example you was using the mouse to aim at the same time as moving in certain directions the direction variable was actually different from what it should be . Causing the player to blend into the wrong poses

I tried move forward and move right axis which have better results as those go from -1 for backward to +1 for forward etc but unlike player speed and direction theses are not automatically replicated so you still need to manually rpc them to replicate the animations

so how should I be doing it then? Thanks

There are a few ways to approach both of those things. I haven’t got the editor in front of me right now, but off the top of my head:

You could play start and stop animations by having those anims in their own States, with transition rules in and out of your movement blendspaces. Example:
-A state called Idle contains your idle animation
-A state called Run contains your movement blendspace
-A state called “StopRun” contains your stop animation, set to non-looping
-A state called “StartRun” contains your start animation, set to non-looping
-**Idle **transitions to **StartRun **if pawn’s velocity is greater than 0
**-****StartRun **transitions to **Run **if TimeRemaining on the StartRun animation is 0 (use “get time remaining” node)
-**Run **transitions to StopRun if pawn’s velocity is 0
-**StopRun **transitions to **Idle **if time remaining on the StopRun animation is 0

You’d need a few more transition rules to smoothly enter/exit the start/stop run states when necessary but that should get you started.

The player speed/direction stuff is just math and coordinate spaces. You need to get the movement direction and velocity relative to the pawn’s forward direction, which you can google how to do, and map that to a range of -1 to 1.

“What you mean by networking stuff that should be local?? I’m confused .”

Any time you use RepNotify or NPCs you’re sending stuff over the network. Basically, you want to do that as little as possible, because bandwidth is limited. Anything you can figure out how to do locally on each machine, without sending information over the network, that’s how you should do it. Animation is a perfect example of this. Animation blueprints should never need any information that isn’t available locally. With your approach, you throw about a bazillion more packets around than is necessary.

My point was though that it was impossible to achieve all the correct range of animations using just a single blendspace. With a single blendspace I can get all the strafe movement and character movement including forward and back and idle to work but it is impossible to get start and stops especially for each different range of movement to work using blendspaces. I tried doing as you said using a mixture of multiple blendspaces and state machines to get it to work but I ended up with jerkier more unnatural looking movements. And because we have multiple strafe angles 45,135, left and right , strafe stops and run forward and backwards stops it all become complicated and messy . Like I said by using just state machines I had greater control over everything as with blendspaces you are bound simply by two rules of the axis you define where as with state machine you can use as many rules as you need making them a lot more flexible not to mention they have built in functionality like ratio timing of how long an animation has left to play etc so overall like I said it is ONLY my personal opinion that state machines ultimately offer greater control and flexibility over blendspaces.
Also you’re theory doesn’t take into account strafing , diagonal strafing and strafing starts and stops. How would you transition between all of those?

For calculating the direction I was using unreals built in calculate direction node but after much googling and trying all the different fixes that other people have tried who are also having trouble with this issue of the direction angles being calculated wrong/fluctuating . I gave up and then began experimenting with using other methods to drive the animations

Have you any links to these maths equations or what exactly I should search for ?? Thanks

Also explain to me how would you set up you’re run blendspace using speed/ velocity as an axis without including an idle animation at speed 0 in order to use speed =0 to transition into an idle blendspace/animation/state machine?

And as for you’re last bit I’m still confused . When you use the players velocity and other variables from the character movement you are already transmitting information over the network because epic have already setup in their code to make these variables replicate. Hence the reason why the thirdperson example project is networked synced and the animations are replicated wothout the user having to do anything.

All I am doing is sending a Boolean value over the network in order to replicate my
Animations . If it were a single player game then Yes you’re correct everything would be done locally but for multiplayer there is zero way to replicate the animations without either using rpc events (run on server , and multicast ) . In my case though I figured that rep notify would be more efficient because it is my understanding that rep notify functions are only called when the value that the function is made from changed therefore theoretically rather than my data being sent on tick as I imagine velocity is done . My Boolean value is only sent/transmitted once whenever the variable is changed . So when I press w for the first time it is sent once. The whole time I keep my finger on w nothing is being sent over the network because the value of the Boolean hasn’t changed its only when I release the key the rep notify function will fire again and change the Boolean back .

Now I’m no expert on any of this stuff I’m an Indie developer just trying to do as best I can and learn all this stuff but I fail to see how transmitting a single Boolean over the network will cause network problems or a bazillion packets as you say .

And like I pointed out by using velocity you are already transmitting information over the network, not locally as you put it because epic has already set it up like that it is just not exposed in the blueprints. So tell me how would you replicate animations without sending any packets ??