- Home /
Input.GetAxisRaw isnt being called?
I have a script that takes user input from the horizontal and vertical axes via Update, stores them in 2 floats, moveX and moveY, and calculate velocity of the rigidbody2D via FixedUpdate. the calculation is done in a separate function. I first calculate the velocity along the x axis and then the velocity along the y. While the Y is getting registered, the x isnt. I swapped up the order in which the calculation is done and the condition swapped as well; now x is being registered while y isnt. Help!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public Rigidbody2D rb2d;
float moveX;
float moveY;
public float moveSpeed;
private void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
private void Update()
{
moveX = Input.GetAxisRaw("Horizontal");
moveY = Input.GetAxisRaw("Vertical");
}
private void FixedUpdate()
{
CalculateVelocity();
}
void CalculateVelocity()
{
if (moveX != 0)
{
rb2d.velocity = Vector2.right * new Vector2(moveX, rb2d.velocity.y) * moveSpeed;
}
else rb2d.velocity = Vector2.zero;
if (moveY != 0)
{
rb2d.velocity = transform.up * new Vector2(rb2d.velocity.x, moveY) * moveSpeed;
}
else rb2d.velocity = Vector2.zero;
}
}
Answer by sztobar · Oct 11, 2020 at 02:46 PM
You multiple rb2d.velocity
by either Vector2.right
or transform.up
. Both of these vectors resets one axis to zero. It's becuase:
Vector2.right = new Vector2(1, 0);
transform.up = new Vector2(0, 1);
or transform.up = new Vector2(0, -1);
(or something different if the game object is rotated)
The fix to your problem should be simple as writing something like this instead:
rb2d.velocity = new Vector2(
moveX * moveSpeed,
moveY * moveSpeed
);
OK that's understandable but then why is it that only the second input (based on the order in which the code is written) is being read? And I'd usually go with the velocity way of moving things about in unity but the problem came in when I had to rotate the camera, based on which the sprites of the scene would also rotate and imitate the camera rotation. So after, say, a rotation of 90 degrees (of the camera but the sprites rotate 90 as well), the local axes and the global axes are out of sync. After another 90, they get flipped! So as to overcome this i thought I'd provide a direction to the movement script via the method in the problem. Now while the method I chose isn't respondent on one axis, after 90 degrees of rotation, there's ZERO respondent axes and after another 90, the axis that was respondent originally is still working fine!
About only the second input being read - if you would run a visual studio debugger (it's initiated by clicking on Attach to Unity
button there) you can see how your code is executed, which might help you understand why the code behaves that way. Let me try to visualize that by writing on comments which code lines gets executed :
when
moveX != 0
andmoveY !=0
if (moveX != 0) // <- is true { rb2d.velocity = Vector2.right * new Vector2(moveX, rb2d.velocity.y) * moveSpeed; // <- this gets assigned to velocity } else rb2d.velocity = Vector2.zero; if (moveY != 0) // <- is also true { rb2d.velocity = transform.up * new Vector2(rb2d.velocity.x, moveY) * moveSpeed; // <- this get assigned to velocity thus replacing previous condition } else rb2d.velocity = Vector2.zero;
when
moveX == 0
andmoveY ==0
if (moveX != 0) // <- is false { rb2d.velocity = Vector2.right * new Vector2(moveX, rb2d.velocity.y) * moveSpeed; } else rb2d.velocity = Vector2.zero; // <- this gets assigned if (moveY != 0) // is false { rb2d.velocity = transform.up * new Vector2(rb2d.velocity.x, moveY) * moveSpeed; } else rb2d.velocity = Vector2.zero; // <- this gets assigned
when
moveX != 0
andmoveY ==0
if (moveX != 0) // <- is true { rb2d.velocity = Vector2.right * new Vector2(moveX, rb2d.velocity.y) * moveSpeed; // <- this gets assigned to velocity } else rb2d.velocity = Vector2.zero; if (moveY != 0) // is false { rb2d.velocity = transform.up * new Vector2(rb2d.velocity.x, moveY) * moveSpeed; } else rb2d.velocity = Vector2.zero; // <- this gets assigned to velocity, and replaces velocity
when
moveX == 0
andmoveY != 0
if (moveX != 0) // <- is false { rb2d.velocity = Vector2.right * new Vector2(moveX, rb2d.velocity.y) * moveSpeed; } else rb2d.velocity = Vector2.zero; // <- this gets assigned to velocity if (moveY != 0) // <- is true { rb2d.velocity = transform.up * new Vector2(rb2d.velocity.x, moveY) * moveSpeed; // <- this gets assigned to velocity } else rb2d.velocity = Vector2.zero;
In summary: No matter what the value of moveX
is - the condition with moveY
(no matter if true or false) will replace its effects.
Hope that clears things a little.
That is extremely insightful! I did come to the conclusion that only the second input was working using the vs debugger but didn't dig this deep into it. I'll see if I can make up some fix for it and post it asa I find one. Thanks again for the help!
Your answer
Follow this Question
Related Questions
Smooth movement using Rigidbody2d 3 Answers
2D Directional top down movement,Topdown 2d Directional Movement 0 Answers
Movement using rigidbody.velocity to apply a constant force until stop 1 Answer
helicopter horizontal movement problem C# 0 Answers
How to make the player move a fixed distance? (Tile per tile) 0 Answers