So I am starting out trying to create a top down 2D game that has grid based movement (like Pokemon) I have an implementation of movement functional however it is not really smooth: It seems to be janky when it stops the current MovePosition and starts the next one. What can I do to make this transition smooth while the key is being pressed? Here is the code: Code (CSharp): using UnityEngine; using System.Collections; public class PlayerController : MonoBehaviour { public float speed = 5f; private bool isMoving = false; private BoxCollider2D boxCollider; private Rigidbody2D rigidbody; void Start() { boxCollider = GetComponent<BoxCollider2D>(); rigidbody = GetComponent<Rigidbody2D>(); } void FixedUpdate() { if (!isMoving) { bool moveLeft = Input.GetKey(KeyCode.A); bool moveDown = Input.GetKey(KeyCode.S); bool moveRight = Input.GetKey(KeyCode.D); bool moveUp = Input.GetKey(KeyCode.W); if (moveLeft || moveDown || moveUp || moveRight) { Vector3 move = new Vector3(0, 0, 0); if (moveLeft) { move.x = -1; } if (moveRight) { move.x = 1; } if (move.x == 0) { if (moveUp) { move.y = 1; } if (moveDown) { move.y = -1; } } Vector3 end = transform.position + move; boxCollider.enabled = false; RaycastHit2D hit = Physics2D.Linecast(transform.position, end); boxCollider.enabled = true; if (hit.transform == null) { StartCoroutine(PerformMove(end)); } } } } protected IEnumerator PerformMove(Vector3 end) { isMoving = true; float squareRemainingDistance = (transform.position - end).sqrMagnitude; while (squareRemainingDistance > 0f) { Vector3 newPosition = Vector3.MoveTowards(rigidbody.position, end, speed * Time.deltaTime); rigidbody.MovePosition(newPosition); squareRemainingDistance = (transform.position - end).sqrMagnitude; yield return null; } isMoving = false; } }
You should either be using forces to move your character with physics in FixedUpdate, or set the Transform's Position in Update. From the looks of it, you should be using Update because you're polling inputs, and not using physics. You do not need to use that coroutine every frame, because it will continuously be started every frame before it has a chance to move. If you want smooth movement, you want to move incrementally over time in Update. Try using this: Code (CSharp): private void Update(){ // check inputs etc. // move smoothly, never moving farther than maxSpeed in one frame. transform.position = Vector3.MoveTowards(transform.position, endPosition, maxSpeed); }