Math Help - Regarding Controller Stick Magnitude

Ok, so i’m making a rolling ball style game with a third person movable camera. I want to make the game as fair as possible for both keyboard and controller players, but i have ran into an issue whereby if you look 45 degrees from the direction you wish to travel and use two keyboard keys, you are essentially getting a larger magnitude value than it is possible to get on a controller (without destroying it). This is because you are basically able to get 1 magnitude in both the X and Y directions, giving a total magnitude of around 1.4 whilst a controller limits the overall magnitude to 1 in any direction due to the physical radius preventing the stick moving further out.

I cant solve this issue by simply clamping the total magnitude to 1, as i use separate forces for both the X and Y direction, so i was hoping to clamp with the X and Y values to a ratio that will always cap at 1 magnitude, and this is where i need help.

Another option would be to take the forward vector of the camera direction and then apply a single clamped force in the direction the sticks are facing (by calculating the angle of the sticks) but this seems a lot more complex (and id still need help with it).

This is how i am currently controlling the ball: https://i.imgur.com/X1cFEhk.png

I am happy to post any more images if required.

Thanks in advance for any comments and help!

The stick gives you a magnitude from 0 to 1 and a direction (depending in which direction you push it). The keyboard is more limited because it gives you only 0 or 1 (key pressed or not pressed). To also simulate a direction with the keyboard you can use the ATAN2 function.

Say that you move your character with the arrow keys and say that:

  • Up = 1 if pressed, 0 if not pressed
  • Down = -1 if pressed, 0 if not pressed
  • Right = 1 if pressed, 0 if not pressed
  • Left = -1 if pressed, 0 if not pressed

Then using ATAN2(Up+Down, Left+Right) you have all possible directions at multiples of 45 degrees:

0,45,90,135,180 and -45,-90,-135,-180 (which equals 180)

The magnitude of your movement will always be 1 if any key is pressed. Otherwise it will be 0. This should give you a behavior similar to the stick.

Hope this helps.

In this case I would simply use a Min(1, X+Y). If X+Y > 1 the function will clamp to 1, otherwise just pass on X+Y.

I think you misunderstood my question, or i have misunderstood the answer.

I want to clamp the X and Y axis values so that the overall magnitude never goes above 0. Essentially i am trying to balance the equation so that the magnitude is always 1 or below.

When you press say up and right on the keyboard, if the forward direction is 45 degrees off where you with to go, then you can gain a magnitude of 1.414, which is what i’m trying to avoid.

“I cant solve this issue by simply clamping the total magnitude to 1, as i use separate forces for both the X and Y direction, so i was hoping to clamp with the X and Y values to a ratio that will always cap at 1 magnitude, and this is where i need help.”

At the risk of sounding like an idiot, i don’t really understand the stuff you are saying… I work with blueprints because i have absolutely no experience with coding, and i’m here for help with with math because well… i’m bad at math… a little more explanation and maybe some images would help a lot.

I will try to expand a little.

Take this image: https://i.imgur.com/9tnborK.png

I basically want to apply a dynamic clamp (min and max) to both the X and Y axis values so that the overall magnitude (the number coming from the sqrt) is never above 1.

Ok, I am trying to come along even if I think the approach you have taken doesn’t make much sense. Anyway, if you are bad at math, a trick you can use is to go on Wolframalpha and get some help from its mathematical engine.

So, rephrasing your question: if you have x and y and you are calculating sqrt(x^2+y^2) what are the maximum values of x and y so that the result is always less or equal to 1 ? The answer is 1/sqrt(2). As long as x and y are below that value, sqrt(x^2+y^2) will always be less or equal to 1.

Now i’m confused lol. Are you asking me that question? because that’s the question i came here specifically to get help for… xD

hahaha, sorry, read again my answer. I used the less than symbol and that truncates the content. Fixed it.

@%$^@! The preview shows it and then it is truncated. I removed all the symbols, try again.

i still don’t see it… xD

ok now i see it, and at the risk of making you wish you had never posted on this thread to begin with, i still don’t think its what i am looking for. Sticking in a cap of say ~0.7 will ensure my magnitude doesn’t go above 1, but it doesn’t change the fact that diagonal magnitude will always be greater than the magnitude in a single direction.

For example, if i cap my axis at 0.7 and hold down A, my magnitude is 0.7. If i then hold down AW, my magnitude is 1. This basically leaved me in the exact same position, only with smaller numbers.

What i am looking for is a way to use the relationship between X and Y axis in regard to the total magnitude of both. So say for example i hold A on my keyboard, the Y axis will be clamped to 0 because the magnitude is 1, and then if i hold down AW, the clamp for X and Y will be changed to 0.7 so that the magnitude is still 1.

Hopefully you understand what i am asking for. Also, if you could use actual example in blueprints (preferably relating back to the original image i posted in regards to how i actually control the ball) that would be extra amazing.

Thanks!

I like the challenge! :wink: Here is an idea. Threat X and Y as Boolean and use the OR function to “sum” them.

X=0, Y=0 then X OR Y = 0

X=1, Y=0 then X OR Y = 1

X=0, Y=1 then X OR Y = 1

X=1, Y=1 then X OR Y = 1

In this way no matter if X or Y or both are 1, their “total” will always be max 1. If only one of them is 1, the total is anyway 1. Does it make sense?

but how would this work in blueprints? if you could provide images it would be great. thanks!

Sorry I don’t have access to my dev environment at the moment.You can use the logical OR function, UE4 will do all necessary conversions for you. Just right click on the Blueprint and type OR, you will see it.

i had something like this in mind, but this doesnt work: https://i.imgur.com/oFFTuhx.png

This is what i have so far from what you have said. where do i go from here?

Or perhaps we could look at this problem from a different angle (pun intended). Would it be possible to get the relationship between the angle of the x and y axis and then use this angle to determine a clamp for the X and Y axis based on the magnitude.

For example. if the angle is 45 degrees, we know that in reality the magnitude of x and y is 1 in both directions, but we would want them to be clamped at ~0.7

do you understand what i mean?

And this is exactly what you can do with the ATAN2 function I described in my first answer. Scroll up to find it. It allows you to calculate the direction given the values of X and Y. Once you know the direction, you can cap the magnitude to 1 if it is on the diagonals (45, 135, -45, -135 degrees)

I already had the angle calculated, but as i said in my op, i cant simply cap the overall magnitude because i use the individual axis to control the ball as can be seen in the image on op. Is there a way i can use the angle, to then recalculate the max possible value for each axis and cap them individually?