Hello, I need to move my player not only up and down but also left and right. But this script is only allowing me to move up and down and not left and right as well. Below is my script: Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { public Rigidbody2D rb2D; public float speed = 10f; // Use this for initialization void Start () { rb2D = GetComponent<Rigidbody2D> (); } // Update is called once per frame void FixedUpdate () { float Horizontal = Input.GetAxis ("Horizontal") * Time.fixedDeltaTime * speed; float Vertical = Input.GetAxis ("Vertical") * Time.fixedDeltaTime * speed; Vector2 newPositionX = rb2D.position + Vector2.right * Horizontal; Vector2 newPositionY = rb2D.position + Vector2.up * Vertical; rb2D.MovePosition (newPositionX); rb2D.MovePosition (newPositionY); } }
I'd hazard a guess that MovePosition() is probably overwriting newPositionX with newPositionY each time. You need to rewrite it so MovePosition only runs once with a vector2 holding both new positions. FixedUpdate() should only be for effecting rigidbody physics so you should be running this in update() anyway. And always use Time.DeltaTime.
Code (CSharp): rb2D.MovePosition (newPositionX); rb2D.MovePosition (newPositionY); Your player only moves up and down because these two lines conflict. MovePosition moves your character's rigidbody to an explicit location. Then you call it a second time, overwriting the first. If you changed the order of the lines, you would only be able to move left/right. The way to fix this is to call MovePosition just once, with both the X and Y position combined. Code (CSharp): private Vector3 movementInput; private void Update() { movementInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")); } private void FixedUpdate() { Vector3 offset = movementInput * Time.deltaTime * tweenSpeed; Vector3 newPosition = rb2D.position + offset; rb2D.MovePosition(newPosition); } Getting the inputs in Update is the way to go, but the rest doesn't really make a difference. The position of the rigidbody will only be updated in FixedUpdate when using MovePosition, so there's no reason to run this logic every frame. Since it's running on the fixed timestep, using "fixedDeltaTime" is correct to make the player's speed independent of time step, however "deltaTime" will also return "fixedDeltaTime" when used within a FixedUpdate function so either will work.
true, only glanced and should've specified splitting inputs and physics. Using Time.DeltaTime is better practice because the correct one will always be returned. But yea, fixeddelta within fixed works too.
Thanks Jeffreyschoch and JackHearts! I changed the code so that it uses a Vector 2 rather than a Vector 3 because I'm working in a 2D project but they work perfectly! (I dunno if that is a big change to how things work (using Vector 2 instead of Vector 3) but it still works regardless). I think also referencing Vectors is something new I learned as well so I will be implementing that in future projects!
Position is a Vector3, so be aware that if you set position to a Vector2, the Z value will be assigned 0 implicitly. For example: Code (CSharp): Vector3 position = new Vector3(10,10,3); // position is now (10, 10, 3) position = new Vector2(5, 5); // position is now (5, 5, 0) // reversed: Vector2 position = new Vector2(5, 5); // position is now (5,5) position = new Vector3(10,10, 3); //position is now (10, 10)
JayBee. vectors are convenient holders for floats so quite essential. A vector3 being x,y,z and vector2 x and y. The 2D scripting elements are simply ignoring the z axis. MovePosition for instance will only affect x and y so the z of the vector3 won't make a difference.You can access each value easily with myVector.x, etc. So your original code can be written like this... Code (CSharp): float Horizontal = Input.GetAxis ("Horizontal") * Time.fixedDeltaTime * speed; float Vertical = Input.GetAxis ("Vertical") * Time.fixedDeltaTime * speed; Horizontal = rb2D.position.x + 1 * Horizontal; Vertical = rb2D.position.y + 1 * Vertical; Vector2 newPos = new Vector2(Horizontal, Vertical); rb2D.MovePosition (newPos); When working in 2D you should be able to use vector2 pretty much all the time without ill effect. Just be aware of what jeffrey mentioned. If you change a position directly like transform.position = new vector2() then the z will set to zero. That may cause a problem if you've got sprites at certain z values for whatever reason.