stoopi_poopy
stoopi_poopy

Reputation: 3

Can someone help, my player, (which is a cube in a 3d environment), it teleports to 0,0 and i cant move it at all

(i think that it is in the update function of the code)

public class PlayerMovement : MonoBehaviour
{
    public float speed = 18;
    private Rigidbody rig;
    // Start is called before the first frame update
    void Start()
    {
        rig = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        float hAxis = Input.GetAxis("Horizontal");
        float vAxis = Input.GetAxis("Vertical");
        Vector3 Movement = new Vector3(hAxis, 0, vAxis) * speed * Time.deltaTime;
        rig.MovePosition(transform.position = Movement);
    }
}

Upvotes: 0

Views: 53

Answers (2)

derHugo
derHugo

Reputation: 90659

The code you have equals doing

void Update()
{
    float hAxis = Input.GetAxis("Horizontal");
    float vAxis = Input.GetAxis("Vertical");
    Vector3 Movement = new Vector3(hAxis, 0, vAxis) * speed * Time.deltaTime;

    transform.position = Movement;

    rig.MovePosition(transform.position);
}

Can you see now what the issue is?

  • your Movement will every frame be quite small since it is multiplied by Time.deltaTime (for 60 F/s this equals about 1/60 = 0.017) - not part of the issue yet ;)

  • Then you set your object fix to this position via transform.position. This will always stay quite close around 0,0,0 with a range of about 1/60 * 18 = 0.3.

  • And finally you tell the Rigidbody to move to exact the same position in which your object is now already in anyway.


Rigidbody.MovePosition expects an absolute world position so what you rather want to do is using

rig.MovePosition(rig.position + Movement);

Then note also that any Physics related movement should rather be done in FixedUpdate so your code should look like e.g.

public class PlayerMovement : MonoBehaviour
{
    public float speed = 18;

    // You could/should reference this directly via the Inspector
    [SerializeField] private Rigidbody rig;

    private Vector3 _movement;

    private void Awake()
    {
        if(!rig) rig = GetComponent<Rigidbody>();
    }

    // Get User input in Update
    private void Update()
    {
        float hAxis = Input.GetAxis("Horizontal");
        float vAxis = Input.GetAxis("Vertical");

        _movement = new Vector3(hAxis, 0, vAxis) * speed * Time.deltaTime;
    }

    // But apply Physics in FixedUpdate
    private void FixedUpdate()
    {
        rig.MovePosition(rig.position + _movement);
    }
}

Note that alternatively without separating both you could also directly assign the Rigidbody.velocity instead:

public class PlayerMovement : MonoBehaviour
{
    public float speed = 18;

    // You could/should reference this directly via the Inspector
    [SerializeField] private Rigidbody rig;

    private void Awake()
    {
        if(!rig) rig = GetComponent<Rigidbody>();
    }

    private void Update()
    {
        float hAxis = Input.GetAxis("Horizontal");
        float vAxis = Input.GetAxis("Vertical");

        var movement = new Vector3(hAxis, 0, vAxis) * speed * Time.deltaTime;

        rig.velocity = movement;
    }
}

Upvotes: 1

Vladimir Uleykin
Vladimir Uleykin

Reputation: 61

If I understand correctly, the object moves within the margin of error with respect to zero, but after the horizontal and vertical become equal to (0, 0), then the location becomes equal to the zero coordinate.

Read this page, I think you can find the answer to your question in it. Rigidbody.MovePosition

Possible Solution:

    // Update is called once per frame
    void Update()
    {
        float hAxis = Input.GetAxis("Horizontal");
        float vAxis = Input.GetAxis("Vertical");
        Vector3 Movement = new Vector3(hAxis, 0, vAxis) * speed * Time.deltaTime;
        //Replacing '=' with '+' or '-' should help
        rig.MovePosition(transform.position + Movement);
    }

Upvotes: 0

Related Questions