Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Jittery Diagonal movement

Discussion in '2D' started by Rocky_Unity, Feb 19, 2021.

  1. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    54
    Hello!

    I'm having a weird issue with movement of a 2D sprite.
    Moving up, down, left or right is smooth and great. Moving diagonally, I get a lot of jittery movement..

    Do you have any ideas how to fix this?


    This is the code that is handling movement


    Code (CSharp):
    1.  
    2.  
    3. // Runs in Fixed Update
    4.         private void UpdateMotor()
    5.         {
    6.             Vector2 targetPosition = _rb.position + Input * (StopMovement ? 0 : MoveSpeed) * Time.fixedDeltaTime;
    7.             Vector2 targetVelocity = (targetPosition - (Vector2)transform.position + ForceDirection) / Time.fixedDeltaTime;
    8.             _rb.velocity = targetVelocity;
    9.         }
    10.  
     
    Last edited: Feb 19, 2021
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    3,557
    Don't mix the use of Transform.position and Rigidbody2D.position. Always use the Rigidbody2D.position. Ensure you're using interpolation otherwise the Transform is only ever updated once after the simulation step.

    "(Vector2)transform.position" should be the _rb.position.
     
    Rocky_Unity likes this.
  3. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    54
    Aaah! My mistake. The mis-use of Transform fixed a different issue, and interpolation mostly fixed the topic at hand. It still seems ever so slightly jittery, but I might be just staring far too closely at pixels now o_O

    Thank you!!:)
     
  4. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    54
    Well, I added my character to a Cinemachine camera to follow, and the jitter is enormous now....


    I have done many google searches in trying to find a solution, but I can't seem to find anything that helps.
    I have moved my movement script to Update/FixedUpdate, making appropriate changes to Time.deltaTime/Time.fixedDeltaTime......

    This thread had the exact same issues, unfortunately with no solution though. https://forum.unity.com/threads/cinemachine-with-pixel-art-2d-problem.777587/

    I can't seem to figure this jitter issue out. Interpolate is on of course. I have checked and unchecked all the boxes in the Pixel Perfect Camera component, I've even removed it too... Always lots of jitter :(
    Any ideas?
     
    Last edited: Feb 20, 2021
  5. rarac

    rarac

    Joined:
    Feb 14, 2021
    Posts:
    132
    your camera position is not being updated fast or often enough

    force the camera to center on your character on the same tick that you move it
     
  6. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    54
    I tried to enforce a manual update on the Cinemachine Brain after each update in my character motor, but that unfortunately didn't help any.
    I made a stripped down project on Github. I hope someone can help with this. I've found hundreds of links online to others facing similar issues, but no real resolution found. Surely there must be a simple explanation/fix?

    To be clear, I don't care for Pixel Perfect per-se, I just don't want any "shimmer" or "jitter" to appear in my Pixel Art project.

    https://github.com/RockyGitHub/JitterProblems
     
  7. rarac

    rarac

    Joined:
    Feb 14, 2021
    Posts:
    132
    you can try to stop using cinemachine and update the camera transform in code at the same time you execute the movement code
     
  8. print_helloworld

    print_helloworld

    Joined:
    Nov 14, 2016
    Posts:
    159
    The issue is that the movement is normalized, thus the movement on both the X and Y axis on the screen doesn't increment by a whole factor. If in a single axis then the movement increments almost in sync with the refresh rate so the jitter happens less often, but its still somewhat present. The diagonal movement itself makes this more noticeable because the visuals eventually snap to a pixel on some other frame a bit later, but on two axes individually.

    If your visuals moved at 1 pixel on both X and Y per frame, although its not uniform speed, there won't be any jitter. One way to work around this funny glitch, is to have the movement move 3 pixels in a single axis, but 2 pixels diagonally, and with a fixed interval (say every 0.05 or 0.04 seconds) as opposed to every frame. Essentially, you want to synchronize the movement such that the pixels would be aligned to the screen every frame no matter what, and a fixed update step can help with that.

    Forcing the camera to be the same position as the player wont remove the jitter, because then it will just happen to everything else that isn't the player. Whether you use a physics rigidbody component or move through transform, it doesn't really matter either, since the issue is in the inherent nature of pixel perfect games and non whole digits being present.
     
    Last edited: Feb 21, 2021
  9. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    54
    Aaah this is fantastic information! And makes sense. I'm not entirely sure how I may implement it though.
    So it sounds like I should not use
    rb.velocity
    ... Instead I should use
    rb.MovePosition(pixelPerfectPosition)
    ?
    Which just leaves, how to do the math to determine
    pixelPerfectPosition



    Perhaps something like this?
    Code (CSharp):
    1.         private Vector2 PixelPerfectClamp(Vector2 moveVector, float pixelsPerUnit)
    2.         {
    3.             Vector2 vectorInPixels = new Vector2(
    4.                 Mathf.RoundToInt(moveVector.x * pixelsPerUnit),
    5.                 Mathf.RoundToInt(moveVector.y * pixelsPerUnit));
    6.  
    7.             Debug.Log("Clamp X: " + vectorInPixels.x + " into " + vectorInPixels.x / pixelsPerUnit);
    8.             Debug.Log("Clamp Y: " + vectorInPixels.y + " into " + vectorInPixels.y / pixelsPerUnit);
    9.             return vectorInPixels / pixelsPerUnit;
    10.         }
    What I'm really struggling with, is how games like Stardew and Hyperlight manage to have very clean camera smoothing/dampening, whilst also not having jitter
     
    Last edited: Feb 21, 2021
  10. print_helloworld

    print_helloworld

    Joined:
    Nov 14, 2016
    Posts:
    159
    Well if you're still moving using floating digits at the root, you will still get jittery movement unfortunately. For games like stardrew valley, and even EtG, they're not actually pixel perfect. They use pixel art as an art style but they dont limit themselves to the pixelation effect (smart). This is why jittering of any kind is never present in these games.

    Give that a shot, using the pixelation effect on the camera like the pixel perfect package can often be seen as a pointless burden in the modern day when you want to make a stylized game. Not many people would notice, and the people who do, rarely even care or just ignore it.
     
  11. rarac

    rarac

    Joined:
    Feb 14, 2021
    Posts:
    132
    hyperlight is one thing, ill give you that one its very smooth

    but stardew is not pixel perfect at all and is the simplest camera of all just centered on the player always

    dont know why you are using cinemachine but if you want a camera like stardew you dont need it
    hyperlight is another story, the camera work in that game is actualy quite complex
     
  12. Rocky_Unity

    Rocky_Unity

    Joined:
    Oct 13, 2017
    Posts:
    54
    Yes! I could care less for Pixel Perfect. I just want the pixel art style. I am struggling to figure out how to do this without using the Pixel Perfect camera though. So theoretically, I shouldn't have to snap anything to a special Pixel grid right?
    I get strange tearing and occasional shimmering effects if I don't use a PixelPerfect plug-in though, which is what drew me to the pixel perfect packages in the first place. I've spent the last 3 days trying to figure this out, I'm not sure why it has proven to be so hard.
    I want the pixel art style, not the pixel art limitations. I'm not sure where I am going wrong with this.

    Without the PixelPerfect camera, I occasionally see my tiles tear apart at the seems briefly too.. So to reiterate, I don't want to be pixel perfect. I just want the game to look clean, no shimmering and no tearing..


    Stardew has a minor smoothing/dampening effect on the camera, which makes a huge difference in my eyes. It's important to me to be able to smooth the camera and not be snapped to the character at all times.
     
unityunity