0
\$\begingroup\$

Whenever I try to move a character in unity, the character kind of, like, bobs around when walking. Is there any way to remedy this? I have tried the trick of putting the inputs into update and the outputs into fixedupdate, if that's any consolation. Also please ignore the fact that I've used the arrow keys instead of getaxis.

using System.Collections.Generic;
using UnityEngine;

public class MovePlayer : MonoBehaviour
{

    public bool upArrow = true;
    public bool downArrow = true;
    public bool leftArrow = true;
    public bool rightArrow = true;
    public float speed;
    public bool test = false;

    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            upArrow = true;
        }
        else
        {
            upArrow = false;
        }

        if (Input.GetKey(KeyCode.DownArrow))
        {
            downArrow = true;
        }
        else
        {
            downArrow = false;
        }

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            leftArrow = true;
        }
        else
        {
            leftArrow = false;
        }

        if (Input.GetKey(KeyCode.RightArrow))
        {
            rightArrow = true;
        }
        else
        {
            rightArrow = false;
        }

    }

    void FixedUpdate()
    {

        if (upArrow == true)
        {
            transform.position = new Vector3(transform.position.x, transform.position.y + speed, 0);
        }

        if (downArrow == true)
        {
            transform.position = new Vector3(transform.position.x, transform.position.y - speed, 0);
        }

        if (leftArrow == true)
        {
            transform.position = new Vector3(transform.position.x - speed, transform.position.y, 0);
        }

        if (rightArrow == true)
        {
            transform.position = new Vector3(transform.position.x + speed, transform.position.y, 0);
        }

    }

    void OnTriggerEnter2D(Collider2D bump)
    {

        if (bump.gameObject.tag == "Wall")
        {

            test = true;

        }
        else
        {

            test = false;

        }

    }


}
```
\$\endgroup\$
2
  • \$\begingroup\$ Can you show us this bobbing effect? I can't quite tell whether you're describing fixed timestep judder, rotational misalignment, collision jitter, etc... \$\endgroup\$ – DMGregory Jul 12 '20 at 1:11
  • \$\begingroup\$ Are you applying any external physics to this object? Is there a RigidBody? \$\endgroup\$ – Weckar E. Jul 12 '20 at 5:30
0
\$\begingroup\$

Firsly, use FixedUpdate only when using movement via physics systems,(i.e. if you're using rigidibody to move it via adding a force or by changing it's velocity), since you're doing neither it's good to move the player in the update itself.

void Update()
{
    if (Input.GetKey(KeyCode.UpArrow))
    {
        transform.position = new Vector3(transform.position.x, transform.position.y + (speed * Time.deltaTime * 10), 0);
    }
    if (Input.GetKey(KeyCode.DownArrow))
    {
        transform.position = new Vector3(transform.position.x, transform.position.y - (speed * Time.deltaTime * 10), 0);
    }
    if (Input.GetKey(KeyCode.LeftArrow))
    {
        transform.position = new Vector3(transform.position.x - (speed * Time.deltaTime * 10), transform.position.y, 0);
    }
    if (Input.GetKey(KeyCode.RightArrow))
    {
        transform.position = new Vector3(transform.position.x + (speed * Time.deltaTime * 10), transform.position.y, 0);
    }
}

The reason I multiplied by speed with Time.deltaTime is to normalise it and make it frame rate independent.

And also it is not a preferred way to move your player using transform, if you're particular about collisions, changing the position using transform.position can cause tunnelling into objects, I suggest you to move the player using Rigidbody and changing it's velocity.

Try doing something like this in FixedUpdate for a smoother rigidbody movement : rigidbody2D.velocity = new Vector2(Mathf.Lerp(0, Input.GetAxis("Horizontal") * Speed * Time.fixedDeltaTime, 0.8f), Mathf.Lerp(0, Input.GetAxis("Vertical") * Speed * Time.fixedDeltaTime, 0.8f));

\$\endgroup\$
2
  • \$\begingroup\$ I'd quibble with this advice: "use FixedUpdate only when using movement via physics systems." FixedUpdate is valuable anytime you want a consistent game feel under varying framerate conditions, ensuring you don't get hard-to-reproduce timing bugs due to different time steps, even if you're not using the built-in physics but implementing your own time-sensitive game logic. \$\endgroup\$ – DMGregory Jul 12 '20 at 11:29
  • \$\begingroup\$ I agree with you it's not right to say FixedUpdate is only for Physics systems, as you said it's for getting a more consistent feel,I think it's better to say to use FixedUpdate to compute Physics system calculations, or if you want something to update in-step with the physics engine. \$\endgroup\$ – Pikachuxxx Jul 12 '20 at 16:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.