Calculate movement direction relative to look at direction.

Hello, i’m working on a twin stick shooter game and i’m trying to set up the animations so that they fit with the current direction the player is moving in.
Basically If the player LOOK_AT Direction is 80, then I create two float ranges, one where min is LA_Dir - 45 and max is LA_Dir. The next float range would be min LA_Dir and max LA_Dir + 45.
(min 35,max 80) & (min 80, max 125). This simple equation would determine the FORWARD direction and then I would just check whether the Movement_Direction is within any of those two ranges.
I’m pretty sure I can replicate this to establish the Back,Right and Left directions. My problem is that the blueprint i’m creating is quite large and its seems to be that there should be another method of solving this problem without having to create such a huge blueprint. I’m concerned that such a big blueprint that is being called every time the left joystick (movement) is triggered will make the game run slow. This game is meant for Android.

If you guys have any knowledge that might help me in figuring this out I’d appreciate it. Thanks.

Hi @OniricMaster
Sorry i am pretty confused by your post , can you explain simpler whats your problem?
“set up the animations so that they fit with the current direction the player is moving in” You have different animation based on the direction? are you making a 2D 2D.5 game?
“determine the FORWARD direction” Any 3D actor or mesh, already have an easy to read “forward”

Hello @Est_engine , thanks for your reply.

It’s a 3d game, basically the movement is controlled with the left joystick and the Right Joystick controls the rotation of the player.

My problem is that I need to constantly determine what direction the player is moving in relative to the direction he is looking at (rotation) so that I can feed that variable into a blendspace so that the animations change correctly.

I know I can find the forward vector but since the forward vector is going to be constantly changing based on where the player is aiming I need to have some sort of equation that can calculate what direction the player is moving in relative to his rotation.
So if his forward vector is 90, then I would know that the the player is moving forward if the Movement Input is in between 90 - 45 or 90 + 45. But the moment I rotate my character what was previously forward is no longer the case.

Also regarding the different animations, theres currently 4 different animations, forward,back,left and right, these animations will be used for the lower body (legs) so that it looks like the player is moving in the correct direction.

Here’s a video I made recently which showcases the problem clearer. In the video you can see that at first the legs are moving correctly, but the moment I rotate the character (right joystick) it becomes all messed up because the values have changed.

I hope this made things a bit clearer, i’ve been posting about this problem for a while, I’ve tried quite a few things but nothing seems to work as wanted.
Thanks a lot.

Here’s a simple image I’ve done to better illustrate what I mean.

ooooook now i got it!

I suggest you to convert the quaternion in a euler rotation, i think there are some function too like Fquat but i explain an easy fix to your quest.

So 1, get rid of the negative rotation. making a new variable FixDirection.
get the Z rotation of the actor and add a branch, if is minor of 0, set FixDirection to 360 - the actor rot Z. if is bigger , get the rot Z and set FixDirection.
Make your actor spin and with a print check that your rotation now goes from 0 to 360. this variable will no more go negative like -90.
Do the same for the other direction you have.

  1. You will end up with FixDirection1 , FixDirection2. both from 0 to 360
    Add one to the other, and you should have the EndDirection, that could be greater than 360.
    if this variable is greater than 360:
    Divide it by 360, you will end up with a value like 1.25 or anything.
    get this value, use the truncate node, to have a 1.00, multiply 360 by it and subtract to the End_Direction you got.

This is the Value you want to blendspace.

I really hope i said it right XD

you mean like this?

excuse the rancid animations…

that’s using a 2D blendspace, here the actors rotation is constantly updating per tick to face the other actor in the character blueprint, same principle as if you were updating the rotation to face where the analogue stick was pointing.

Animation Blueprint:

read the tooltip on the ‘calculate direction’ node (including the typo in inbetween…)

“returns a degree of the angle between velocity and rotation forward vector” so your actors facing direction (actors rotation) and velocity (your speed). Speed doesn’t go into the minus like you might think you need for the backwards direction (like I did first time I tried to get my head round it), backwards is -180 or 180, forwards is 0 on the direction, speed is just literally how fast you are going in that direction.

so that’s where its getting the rotation from for the blendspace, its all taken care of for you with those two variables

Feed the blendspace the values, done here in the locomotion state:

The 2D blendspace:

@savagebeasty Thanks for your reply. I’ve been trying to use the Calculate Direction node for quite a while but It just never works, I imagine this has to do with the way the I’m making my character move and rotate.
So I’ve basically set it up exactly as you showed.
This is how I set up the movement and rotation for my character. It works well but It doesnt seems to work for the Calculate Direction node, I imagine that its because whilst AddMovementInput’s target is Pawn, AddActorLocalRotation’s target is Actor. I’ve been trying to set the rotation with a AddControllerYawInput but not only does it still not calculate the correct direction but now the character doesnt really rotate as I wanted it to.

This is the new method I’m trying although it doesnt give the desired results.

With both rotation methods that I’ve used the CalculateDirection node doesnt seem to work and I dont really understand why.

Thanks for the help.

Your blendspace has speed that goes into minus, min value should be 0, minus speed doesnt make sense, you’re either moving or you’re not :slight_smile:

Where are you setting the speed i can only see that you’ve set direction?

The world rotation of your pawn is basically irrelevant as the calculate direction uses the forward vector…which is forwards in local space of the pawn as you already know. So the blendspace itself doesnt actually care what the rotation as its only interested in forward/back/left/right of the actors forward vector.

Saying that theres always a chance something else is screwing it, you dont have ‘orient to movement’ ticked in your character movement comp do you?

Well Im currently ignoring the speed, im setting the blendspace so that the animations work at 0 speed. I dont think thats whats causing the problem, at least it wouldn’t make much sense to me.
I’ve noticed that when I print out the GetActorRotation, it stays at 0. Which means that clearly the way I’ve set up my rotations doesnt work with GetActorRotation. I simple dont know how to set up the rotation to work with AddControllerYawInput which when tested does change the GetActorRotation.

Also I did have the orient to movement ticked, I unticked and nothing changed.

Hhmm if actor rotation is returning 0 then thats definitely a problem :slight_smile:

Would explain why it only works in one direction :wink:

I’ll swItch my computer on shortly and grab all the settings for rotation

character movement comp:

bOrientRotationToMovement = false
bUseControllerDesiredRotation = true

Character Pawn:

// Disconnect from camera rotation
bUseControllerRotationYaw = false;
bUseControllerRotationPitch = false;
bUseControllerRotationRoll = false;

// how fast the character will rotate to desired rotation
RotationRate = FRotator(0.f, 1000.f, 0.f);

This code runs in the tick to set the controller rotation:

// Get direction to targets root location
APlayerController* PC = Cast<APlayerController>(GetController());
if (PC)
    // Get direction to target
    FVector VectorToTarget = CurrentTarget->GetActorLocation() - GetActorLocation();
    VectorToTarget.Z = 0.f;

    FRotator DirectionToTarget = FRotationMatrix::MakeFromX(VectorToTarget).Rotator();

    // update controllers rotation

Blueprint equivalent is basically this to set the rotation:

@savagebeasty thanks for the help. I actually managed to fix it although really understand how exactly. Basically I changed the AddActorLocalRotation node to SetActorRotation and I noticed that now it seemed to be working but a bit weird so I tweaked the BlendSpace and managed to get it working.

This is what the blendspace looks like now. (To me it doesn’t make much sense.But it works)

Yay good stuff. I know the feeling it makes my head hurt everytime i think about it :slight_smile:

That blendspace does look a bit wrong though, forward should be in the middle as thats direction 0 (the forward vector of your pawn), left/right the next ones along in both directions (for direction 90) then backwards should be on the far left and the far right for as thats where the direction is 180 or -180

shift all the nodes along to the left and add backwards to the far right, its nearly there :slight_smile: