The proper way for smooth 2D movement.

So I was following the fantastic 2D tutorial made by pixelnest, but I noticed that it was kind of choppy. Every 2 seconds or so everything would seem to jump backwards one frame then go forwards again. i.e. it actually looks like it goes the wrong way for one frame then keeps going.

I remade the project, stripped out everything and the issue still happens.

The objects that move have a Box Collider 2d and a RigidBody 2d. But gravity is set to 0 and no forces are being applied.

The movement is done like this:

void Update()
{
	// 2 - Movement
	Vector3 movement = new Vector3(
		speed.x * direction.x,
		speed.y * direction.y,
		0);
	
	movement *= Time.deltaTime;
	transform.Translate(movement);
}

I have tried, FixedUpdate and LateUpdate. FixedUpdate makes it quite a bit worse and Late is about the same as just update.

I’ve deployed to Android, Web, and Desktop and they all have the same little jump.

I have the FPS script from the wiki, and the game runs solid at 60.3. If set it to “don’t sync” it runs at about 411, and the choppyness is almost gone, but still visibile.

Is there a better way I can use to move these objects for a simpler side scroller like this that doesn’t have this choppyness.

Thanks,
Wright

Rule of thumb when dealing with movement of rigidbody enabled objects: never use translate.

Instead, set the velocity directly or use rigidbody2D.AddForce() to move around.

1 Like

Thanks for the response unitylover, I tried setting the velocity directly in Start() but that actually seemed to produce a even slightly jumpier result. Using the translate gave a much smoother gliding motion with jumps only every 2 seconds or so.

I’m not having any issues with the collisions themselves…just the actual moving of the sprite.

:frowning:

It would be nice to see a video demonstrating this behavior because I can’t visualize the problem you’re experiencing. Is the moving objects moving along the ground? Maybe a screenshot of your game view would help me help you.

Here’s a webplayer version of it: http://thewrightdev.com/Test/Build_Test.html

Just track the ship with your eye and you will see it “jump” every so often.

Wow, now that’s funny! At first I didn’t notice the issue but you’re right, if you follow the sh ip with your eye it seems to lag back every so often. Are you using any kind of interpolation on the object? Can you post your inspector settings for the ship?

Have you checked the profiler to see if there is anything else that may be causing it?

@zombiegorilla - Unfortunately I don’t have the pro version so I don’t think I can look at that. But looking at the system resources there’s no sort of spike or anything, pretty much dead flat.

@unitylover - Hm, I tried turning on interpolate but it didn’t really make any change at all? Here’s the inspector: (I left the interpolate option on, but it was off originally).

The move script itself:
1481648--82089--$6iCXd.png

As an experiment remove the Time.deltaTime multiplication and increase your movement vector to compensate. I’m curious if the issue is something to do with frame speed.

edit: And put the movement code inside a fixed update.

I’m running into this too a bit, curious to know if it gets resolved.

1 Like

This is a really complicated issue that you would run into with just about any game engine, and unfortunately there isn’t a clear solution with Unity (unless you buy all of your customers those fancy G-Sync monitors). The core issue is that the update/render rate of your game isn’t perfectly synced with your monitor’s refresh rate. When the two fall out of sync, you’ll notice the jitter.

You might find this Unity Answers page helpful: http://answers.unity3d.com/questions/275016/updatefixedupdate-motion-stutter-not-another-novic.html.

And this followup thread with a sample project: http://forum.unity3d.com/threads/162694-SmoothMovementTest-should-help-eliminate-Hiccup-sources.

Here’s another informative thread that touches on this issue: http://forums.tigsource.com/index.php?topic=32714.0.

I remember there being a few other posts on TIGSource related to jittery movement, but that’s the only link I had bookmarked. Sorry :frowning:

1 Like

@bryantdrewjones - Holy crap. Thanks for all the info…I guess I’ll just have to make due for now.

Is it possibly because of a floating point inaccuracy, like the delta time etc doesn’t always exactly add up to 1.0 every second, and so it is very slightly out of sync with the exact 60hz refresh, and so once in a while when all those inaccuracies add up, a frame slightly misses the vertical blank because it’s slightly too short or long, causes a 1-frame stall, and then resumes? Does it happen with vsync off? Is it possible to do something everyone few frames or something to re-sync it to 60hz to compensate? Like, if over the course of 1/2 a second, you add up all the delta times, and find out if it’s exactly 0.5 seconds, and if not add/subtract the difference to the position?

Hello, tutorial co-writer here.

Thanks to some feedbacks we updated the scripts so we are now using rigidbody in the right way.
The feeling is different but it’s definitely less glitchy.

The purpose of using Translate was to be more beginner friendly but it was a bad idea to show some bad practice :).

Here’s the new script, from http://pixelnest.io/tutorials/2d-game-unity/player-and-enemies/.

using UnityEngine;

/// <summary>
/// Player controller and behavior
/// </summary>
public class PlayerScript : MonoBehaviour
{
  /// <summary>
  /// 1 - The speed of the ship
  /// </summary>
  public Vector2 speed = new Vector2(50, 50);

  // 2 - Store the movement
  private Vector2 movement;

  void Update()
  {
    // 3 - Retrieve axis information
    float inputX = Input.GetAxis("Horizontal");
    float inputY = Input.GetAxis("Vertical");

    // 4 - Movement per direction
    movement = new Vector2(
      speed.x * inputX,
      speed.y * inputY);

  }

  void FixedUpdate()
  {
    // 5 - Move the game object
    rigidbody2D.velocity = movement;
  }
}
3 Likes

Hello I am having similar problems here. I have a ball game and I gave velocity to my ball object at the start and let it find its own way with hitting objects in 2D space. Its vector is (6,6) for example. After hitting some objects it changes its velocity to (8.1, 2.7) for example. But if I start with (2,2) velocity I never faced with this problem. Issued vectors are 3,6,7,8,9 and with vector of (2,2) (2.5,2.5) (4,4) (5,5) (10,10) object move correctly. But if I start with (2,2) for example and increase the speed during the game to a working speed like (4,4) it again lost his way.

private float ballSpeed = 3f;

void Start ()
{
GameManager = GameObject.Find(“GameManager”);
rb = GetComponent ();
rb.velocity = new Vector3(ballSpeed,ballSpeed,0);
Debug.Log(rb.velocity);
}
In the inspector of ball object Mass is 0.1, Gravity is 0, Interpolate=Interpolate, Collision Detection = Continuous, Linear and Angular Drag are 0.
As I understand problem occur because of frames or frame rate something. Any idea would be nice and I will keep seaching the issue and for the solution.

hello friends
i am raycast to hit check and hit point to character movement in update but character not smoothly working
plz help me.
my Code :-
void FixedUpdate ()
{
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
RaycastCheck();
}
void RaycastCheck()
{
Vector3 mousePos = Input.mousePosition;
mousePos.z = 10;
Vector3 screenPos = Camera.main.ScreenToWorldPoint(mousePos);

RaycastHit2D[ ] hits;
hits = Physics2D.GetRayIntersectionAll(Camera.main.ScreenPointToRay(Input.mousePosition),100);

for(int i = 0; i < hits.Length ; i++)
{

if (hits != null /&& hits != null && hits.collider != null && hits_.collider.name.Contains(balloontype.name)/)
{
if(hits*.collider.tag == “Hero”)*
{
PlayerHit = true;
}
if(hits*.collider.tag == “Wall”)*
{
WallHit = true;
}
else
{
WallHit = false;
}
}
if(WallHit && PlayerHit == true)
{_

gameObjectTodrag.transform.position = Vector3.MoveTowards(gameObjectTodrag.transform.position,hits_.point,Time.deltaTime * 50f);
}
}
}_

Four and a half years later and the solution still hasn’t surfaced. Are there any Unity Store Assets that have projects with smooth object scrolling? That would be really handy…

There’s ufo asset tutorial, it’s relatively smooth over small velocities.

Not sure of everything you are doing, but you should not check for input in FixedUpdate() check for input in Update().

As the script is controlling the movement of the object directly I would be inclined to say that the object should be set to kinematic.

If you don’t wish to set the object as kinematic then i’d suggest using the AddForce() method of the rigidbody to modify the objects position. You can also modify the rigidbody’s velocity property but the docs do state to avoid using this if possible.

I follow the above principles and can’t say I’ve ever had a problem with smooth movement.