Development of our MMO-style controller, part six! The original specification with contents and an overview can be found in this post.
This is going to be the most complicated part so far. This section of blueprints replaces the functionality we removed in an earlier post, but adds some custom controls that we need.
This code will be added to the MyCharacter blueprint event graph.
This is a beast of a function. Hopefully I can break it down so that it all makes sense.
What does this replace?
I mentioned that this replaces functionality we removed from the character already. This was back in the post setting up our blueprint defaults and input axes. We need to add this functionality back into the game, so that our character model faces the direction we are moving in, and also turns to face a new movement direction when we change direction.
If we use the default behaviour, as provided by Unreal Engine, we can’t walk backwards, with our back to the camera. The camera would automatically rotate with our character, to face the direction we were moving in.
We need to check this every tick, so that we’re smoothly changing direction as necessary.
Are we moving?
First thing to do is check if the character is currently moving. We’ll need the CharacterMovement component, and get the velocity from that.
Using the Vector Length of the velocity, we can check if the amount of movement is large enough for us to want to update the character’s rotation.
If we do not set this initial check, the character will tend to snap around to odd directions at the end of movement.
So we’re moving, are we moving backwards?
Next step is an important branch: are we moving backwards. Once again changing the motion based on the direction of movement is key.
We get this information from the MovingBackwards boolean stored in MyPlayerController. This is simple enough check!
We’re moving forwards! Now what?
We need to update the rotation of the character if we’re moving forwards. We’ll need to get the direction we’re currently facing, the direction we want to be facing (the direction of movement), and some how smoothly move towards that direction.
What we need to do is update the rotation of the character a small amount, until it reaches the direction needed. This is accomplished by the RInterpTo function.
RInterpTo Interpolates a rotation based on an initial value and target value, using the Delta Time value scaled by a parameter InterpSpeed. Each tick, as this function is called, RInterpTo returns us a value closer and closer to our desired rotation.
We grab the velocity of our character and get the rotation for this as our target value (this is the direction of movement, we aren’t facing it yet), and interpolate to that from our actor’s current rotation.
Once we have the result from the RInterpTo node, we set that to our actor’s rotation, after zeroing out the pitch and roll.
To scale the RInterp, I used two variables, BaseTurnRate, set to 45.0, and RotationSmooth, set to 0.85.
What about moving backwards?
This is very similar, but when moving backwards we need to rotate the character in the opposite direction to movement.
This is mostly the same as the previous code. The additions are not overly complex.
To make the character face the opposite direction to movement, we combine the rotation from the velocity with another rotator of yaw -180.0. This gives us the reverse we need.
Additionally, to keep in the theme of doing things slower while moving backwards, an additional scaling parameter is used on the way to the InterpSpeed plug on the RInterpTo node. The normal backwards scaling value of 0.25 here was too much, so I upped it to 0.5.
Then from our RInterpTo node, we can update the actor’s rotation, after again zeroing out pitch and yaw.
That’s it! We’ve completed the orientate to motion re-write. I have to say, our version is way better.