My apologies ahead as I am a pure noob to Unity libraries and Unity itself.
I am creating a simple 2d game, where a 2d object needs to be constantly moving in a facing direction, but when applied horizontal input (e.g A, D) it needs to change the vector of movement and not change speed.
The object has a property Rididbody2d
This is what I came up to so far:
{
[SerializeField]
private float speed;
[SerializeField]
private float rotationSpeed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update ()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector2 movementDirection = new Vector2(horizontalInput, verticalInput);
float inputMagnitude = Mathf.Clamp01(movementDirection.magnitude);
movementDirection.Normalize();
transform.Translate(movementDirection * speed * inputMagnitude * Time.deltaTime, Space.World);
if (movementDirection != Vector2.zero) {
Quaternion toRotation = Quaternion.LookRotation(Vector3.forward, movementDirection);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
}
}
}
My idea is that during the update we should get whether the input was registered or not and if it was then the current vector multiply (?) by an angle that has been received (if pressed for 0.1 sec -> 0deg 1deg if pressed for 2 sec -> 0deg say 90 deg e.g.).
HOWEVER! Following the tutorials, I managed to get this thing moving only when keys are pressed. I googled my mind off and found actually nothing helpful. Manual was reread many times. Please help me!
P.S. English is not my native language, sorry for making mistakes!
CodePudding user response:
as soon as physics are involved you do NOT want to do anything via transform
at all but rather via the rigidbody component and also not in Update
but in FixedUpdate
.. otherwise you get all kind of strange behavior and break he physics/collision detection!
It sounds to me like what you would want to do would be:
[SerializeField] private float speed;
[SerializeField] private float rotationSpeed;
// reference this in the Inspector if possible
[SerializeField] private Rigidbody2D rigidbody;
// keep track of the target rotation
// for Rigidbody2D this is a simple float for the rotation angle
private float angle = 0;
private void Awake()
{
// as fallback get the Rigidboy2D on runtime
if(!rigidbody) rigidbody = GetComponent<Rigidbody2D>();
}
private void Update ()
{
// Still get user input in Update to not miss a frame
// evtl you would need to swap the sign according to your needs
angle = Time.deltaTime * rotationSpeed * Input.GetAxis("Horizontal");
}
private void FixedUpdate()
{
// rotate the Rigidbody applying the configured interpolation
rb.MoveRotation(angle);
// assuming if the object is not rotated you want to go right
// otherwise simply change this vector
rb.velocity = rb.GetRelativeVector(Vector3.right).normalized * speed;
}