So I’m trying to get my player character to move both vertically and horizontally, but while the vertical movement is working fine, the player is constantly stuck at 0 on the x axis. Now, I did change the Horizontal axis to only use the a and d keys, so I’m wondering if that tampering could have fooled things up, but IDK. Any thoughts?
Here’s the code, and my altered input for the Horizontal axis is attached below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float turnSpeed = 250f;
public float moveSpeed = 500f;
GameObject playerCam;
Rigidbody2D playerRb;
// Start is called before the first frame update
void Start()
{
playerCam = GameObject.Find("Main Camera");
playerRb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
playerCam.transform.position = new Vector3(transform.position.x, transform.position.y, -10);
}
private void FixedUpdate()
{
Move();
}
void Move()
{
float vertical = Input.GetAxis("Vertical") * moveSpeed;
float horizontal = Input.GetAxis("Horizontal") * moveSpeed;
float turn = Input.GetAxis("Look") * turnSpeed * Time.deltaTime;
playerRb.MovePosition(playerRb.position + Vector2.up * vertical * Time.deltaTime);
//No horizontal movement
playerRb.MovePosition(playerRb.position + Vector2.right * horizontal * Time.deltaTime);
//Player rotation
transform.Rotate(Vector3.forward * turn);
}
}
Horizontal translation is working now, but vertical position is stuck at 0Y. I threw in a Debug.Log to check the input, and the float values are changing as normal corresponding to the inputs.
I have no colliders or gravity in the project, so I don’t know what the problem is. Any thoughts?
There’s lots of problems here. First, don’t modify the Transform, that’s the responsibility of the Rigidbody2D. It has no way of controlling the Transform correctly if you keep modifying it. If you add a Rigidbody2D then you should always go through it’s API to get it to move. Anything else is bypassing it and is undermining what it’s trying to do. You’re using MovePosition already so if you want it to rotate then use MoveRotation.
Issuing a MovePosition will be actioned during the next simulation step. If you issue another one before that then that one alone will be used. These are not actioned immediately and are not queued as commands. You should calculate the position you want to move to then issue a single move.
Note that whilst MovePosition will work for Dynamic bodies, it’s designed for Kinematic bodies as those typically use absolute user-defined position/rotations. Doing this on a Dynamic body will work but you also bypass any in-built velocities it might have as well as how gravity is applied. If you’re doing kinematic movement like this then you should add in the gravity term yourself as part of the single position you wish to move to.
Final note: You scale by Time.deltaTime however that is (technically) incorrect as that is the per-frame time. You should use Time.fixedDeltaTime. The reason why it works though is because many years ago, Unity decided that if a user reads Time.deltaTime during the script fixed-update callbacks, it will return Time.fixedDeltaTime instead as that’s probably the intent. Whist it will work, know that the two are different and if you use that outside the fixed-update you’ll actually get the per-frame (render) time.