Jump to content

  • Log In with Google      Sign In   
  • Create Account

Moving 2D Sprite Not Smooth


Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
3 replies to this topic

#1   Members   

137
Like
0Likes
Like

Posted 22 July 2016 - 06:49 PM

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:

 

giphy.gif

 

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:

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;
    }
}


#2   Members   

104
Like
0Likes
Like

Posted 22 July 2016 - 07:04 PM

I think this is probably happening because you are kicking it off from FixedUpdate() and there is some aliasing going on between when FixedUpdate() is called and when the coroutine is pumped. I would throw some Debug.Log calls into FixedUpdate(), Update() and PerformMove() so you can see what is being called when. The key is that you need to make sure PerformMove() is getting reentered on the same frame it sets isMoving to false or you will have stutter.


Edited by BrainDx, 22 July 2016 - 07:05 PM.


#3   Members   

137
Like
0Likes
Like

Posted 23 July 2016 - 05:58 AM

I think this is probably happening because you are kicking it off from FixedUpdate() and there is some aliasing going on between when FixedUpdate() is called and when the coroutine is pumped. I would throw some Debug.Log calls into FixedUpdate(), Update() and PerformMove() so you can see what is being called when. The key is that you need to make sure PerformMove() is getting reentered on the same frame it sets isMoving to false or you will have stutter.

 

Well the calls are happening in the correct order however I am not sure how to check if PerformMove is being called within the same frame that isMoving is being set to false.



#4   Members   

104
Like
0Likes
Like

Posted 23 July 2016 - 08:58 AM

Try adding Time.frameCount to your logging:

https://docs.unity3d.com/ScriptReference/Time-frameCount.html






Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.