Answers for "How to get overall intensity for each Joystick Axis?"
http://answers.unity.com/questions/804075/how-to-get-overall-intensity-for-each-joystick-axi.html
The latest answers for the question "How to get overall intensity for each Joystick Axis?"Answer by tofurocks
http://answers.unity.com/answers/1904480/view.html
For anybody looking for a solution that works with the new Input System:
private float getMagnitude(Vector2 vector)
{
float x = Mathf.Abs(vector.x);
float y = Mathf.Abs(vector.y);
float xSq = x * x;
float ySq = y * y;
return Mathf.Sqrt(xSq + ySq);
}Mon, 30 May 2022 18:15:06 GMTtofurocksAnswer by ThoseGrapefruits
http://answers.unity.com/answers/1783398/view.html
In order to do this right, you have to normalise against the maximum possible magnitude for that angle.
If you just clamp the magnitude of the vector to `[0, 1]`, then you only have to move `Mathf.Sqrt(magnitude)` in any diagonal direction to get the same normalised magnitude as moving `magnitude` in a horizontal or vertical direction. You run into the opposite problem if you just take the max of the 2 magnitudes, where diagonals are underrepresented instead of overrepresented.
## First, the code.
Vector2 vector = new Vector2(
Input.GetAxis("Horizontal"),
Input.GetAxis("Vertical")
);
float angle = Mathf.Atan2(vector.x, vector.y);
float maxMagnitude = Mathf.Abs(vector.x) > Mathf.Abs(vector.y)
? 1 / Mathf.Sin(angle)
: 1 / Mathf.Cos(angle);
float magnitude = abs(vector.magnitude / maxMagnitude);
(The above is untested, as I was looking for a JS solution when I came across this question, and just translated it into Unity C#)
## Now, the explanation.
![unit circle with enclosing rectangle and 2 sample points][1]
The circle here is the unit circle, and the enclosing square encloses all possible `{x,y}` values that can be given back by a joystick. The orange and pink dots are 2 example positions of the joystick, which fall into the 2 separate pink and orange tinted parts of the graph respectively. These tinted areas represent the 2 different cases that are handled by the ternary in the code above — more on that later.
The fundamental problem is that the magnitude coming out of the vector is relative to that outer square, but you want the magnitude relative to the unit circle, so that it is always in the range [0, 1]. You also want it to stay proportional no matter where the joystick is, so if the joystick's current values fall outside of the unit circle (e.g. `{ x: 0.9, y: 0.9 }`) the output magnitude should be *almost but not quite* 100%, because the user isn't actually pushing the joystick full-speed-ahead in that direction.
The solution is pretty straightforward: we take the vector's value and divide it by the **maximum possible magnitude at that angle**. In the diagram, the vector's value is the solid coloured line, and the maximum possible magnitude is that *plus* the dotted line extending all the way to the edge of the square.
Like I said before, there are 2 cases. Both are gonna use some trig to calculate the maximum possible lengths, taking advantage of the fact that we're working with right triangles.
### "Case 1" (the pink case)
Looking at the diagram, we know *θ1* (the `angle`) and the length of the adjacent side from that corner (that pink `1`). We want to find *h1*, which is the maximum possible magnitude at that angle. Referring to your trigonometric ratios (or [wikipedia](https://en.wikipedia.org/wiki/Trigonometry#Trigonometric_ratios) if you're like me and forgot them all) you'll see that the cosine of an angle *θ* is the ratio between the adjacent side and the hypotenuse, so we can use that to calculate the length of the hypotenuse. The formula is:
cos(θ1) = adjacent / hypotenuse = 1 / h1
Solving for `h1`, we get:
h1 = 1 / cos(θ1)
### "Case 2" (the orange case)
The problem we're solving is exactly the same here: how long is the hypotenuse (`h2` in this case). However, the 1-length side is now *opposite* θ2 instead of adjacent to it (you can see this side in faint dotted orange). No problem, as `sine` is the ratio between the opposite and hypotenuse.
sin(θ2) = opposite / hypotenuse = 1 / h2
again, solving for `h2` this time:
h2 = 1 / sin(θ2)
So, that explains the 2 cases, but how do you differentiate between them? Simple! When the absolute value of x is larger than the absolute value of y, it falls into the first (pink) case. Otherwise, it's the second (orange) case. Again, these are visually split up with the pink and orange tinted areas on the graph. Note that it's important to use the absolute value because, although the examples were both in the positive-positive quadrant, the joystick could be in any of the 4 quadrants, so both `x` and `y` could be negative.
Side note: when they are equal, you could use either one and get the same result (approximately, floating point math probably will make it slightly different), as that means you are hitting one of the corners.
[1]: https://objectstorage.us-sanjose-1.oraclecloud.com/n/axwr2igzbcmc/b/grapefruit-share/o/axes.pngSun, 25 Oct 2020 20:44:25 GMTThoseGrapefruitsAnswer by camta005
http://answers.unity.com/answers/1612321/view.html
The original idea works you just need to take the absolute value of each axis:
Mathf.Max(Mathf.Abs(Input.GetAxis("Vertical")), Mathf.Abs(Input.GetAxis("Horizontal")));Thu, 14 Mar 2019 05:41:11 GMTcamta005Answer by robertbu
http://answers.unity.com/answers/804093/view.html
Note the axes produce values between -1 an 1, so a upper right diagonal will be (1,1) not (0.5, 0.5). You can do:
float mag = new Vector2(Input.GetAxi("Horizontal"), Input.GetAxis("Vertical")).magnitude / Mathf.Sqrt(2.0f);
But this will produce a value of 1.0/sqrt(2) (0.707) for left, right, up and down. You only get 1.0 for a full diagonal. You may want this instead:
float mag = Mathf.Clamp01(new Vector2(Input.GetAxi("Horizontal"), Input.GetAxis("Vertical")).magnitude);Mon, 06 Oct 2014 15:30:44 GMTrobertbu