Search Unity

[Solved]2D sprites flicker/shake on camera movement.

Discussion in '2D' started by Eric-Eidel, Sep 26, 2014.

  1. Eric-Eidel

    Eric-Eidel

    Joined:
    Jan 20, 2014
    Posts:
    5
    Hello,

    I've been stuck on this problem for what seems to be an eternity. I've Googled and read many threads on this issue, but haven't managed to find a solution that would work for me.

    Some of my items (Which are Sprites that are rendered using a Sprite Renderer) shake when I move my character in the game. Also, other textures around the game shake at times - mostly name plates and health bars that I render using NGUI.

    What I have in my game that I think might be causing it:

    1) I have the camera update it's position to the player's position on Update. I tried many versions of this, at some versions the main camera would just be a child object of the player, at some versions I'd just set the position of the camera to be the position of the player and I've event tried to moveTowards:
    Code (CSharp):
    1. if (player != null)
    2. {
    3.     Vector3 new_vector = new Vector3(player.transform.position.x, player.transform.position.y, -10.0f);
    4.     main_camera.transform.position =  
    5.         Vector3.MoveTowards(main_camera.transform.position,
    6. new_vector, 100 * Time.deltaTime);
    7. }
    8.  
    2) The player is moving 1 unit of distance on the axis. From the moment a command is given to move (button is pushed), this is the code that moves the player (and other creatures on the screen) untill the track_value of that creature exceeds 1, at which point the creature stops:
    Code (CSharp):
    1. creature_data.track_value += Time.deltaTime * (Time.timeScale /  
    2.                                                        creature_data.this_move_speed);
    3. creature.transform.position =
    4. Vector3.Lerp(creature_data.prev_pos,
    5.                       creature_data.new_pos,
    6.                       creature_data.track_value);
    3) It is mostly noticeable shaking on sprites that have thin lines in them. I'm thinking that maybe something is causing the sprite to move back and forth by 1 pixel.

    Any help, input or links to similar problems would be greatly appreciated!
     
  2. Shadeless

    Shadeless

    Joined:
    Jul 22, 2013
    Posts:
    136
    Hey and Welcome to the forum.

    I've had this problem as well, and there really aren't that many resources covering the new 2D system and it's issues. Check my post out on this thread http://forum.unity3d.com/threads/efficient-tile-map-for-platformer.270211/ where I go in detail of what's causing the issue.

    And check this video out
    might have some helpful information.

    Cheers
     
    karmaral, GarBenjamin and Eric-Eidel like this.
  3. Powersource

    Powersource

    Joined:
    Oct 7, 2013
    Posts:
    2
    I don't know if I can help you but either way I think a screenshot/high res video would help.
    What is the resolution of your game? Because this reminds me of an issue (no idea what it's called) where a pixel wants to be rendered in a certain spot, eg. x=13.4 but it rounds it to the closest available pixel ie. 13. As the pixel moves by just 0.1 back and forward the pixel keeps jumping between 13 and 14 which can cause a bit of flickering. But as long as your resolution isn't too low it shouldn't be noticed (I think scaling of the sprite might affect it too, but I'm already in too deep water here so I'm gonna leave that there).
     
    Jaxcap, vyshan and bowserscastle like this.
  4. Eric-Eidel

    Eric-Eidel

    Joined:
    Jan 20, 2014
    Posts:
    5
    Hi guys!

    First of all, I'm sorry I wasn't able to produce a video. The res I was getting by using Fraps was too low to actually see what was happening, and as it's a sort-of MMO'ish game, I couldn't just upload the client without having the server run continuously.

    That being said, Shadeless link has solved all my problems. As he had guessed, the issue wasn't in the sprites at all! It is indeed the Camera's pixel precision that was at fault. I have ended up using the following code on movement, to update the camera location (mostly the code Shadeless proposed in the link above).

    As a follow up question, I'm very curious as to how to determine the proper pixelToUnits. I use some self made place holders at the moment and set them at an arbitrary size of 40 pixels. I've later learned that pixels should be a power of 2 (preferably) and I'm now considering how much of an impact having it as 40 would do... Does it actually matter what the size of a "unit" in pixels? Any input on that would be appreciated!

    For easier search in the future, I'll copy paste the code I actually ended up using (again, mostly the code Shadeless posted):

    Code (CSharp):
    1. public GameObject player;
    2. public Camera main_camera;
    3.  
    4. void Update()
    5. {
    6.         if (player != null)
    7.         {
    8.             float player_x = player.transform.position.x;
    9.             float player_y = player.transform.position.y;
    10.  
    11.             float rounded_x = RoundToNearestPixel(player_x);
    12.             float rounded_y = RoundToNearestPixel(player_y);
    13.  
    14.             Vector3 new_pos = new Vector3(rounded_x, rounded_y, -10.0f); // this is 2d, so my camera is that far from the screen.
    15.             main_camera.transform.position = new_pos;
    16.         }
    17. }
    18. public float pixelToUnits = 40f;
    19.  
    20. public float RoundToNearestPixel(float unityUnits)
    21. {
    22.         float valueInPixels = unityUnits * pixelToUnits;
    23.         valueInPixels = Mathf.Round(valueInPixels);
    24.         float roundedUnityUnits = valueInPixels * (1 / pixelToUnits);
    25.         return roundedUnityUnits;
    26. }
    Also, again, a million thanks to you guys!
     
  5. Shadeless

    Shadeless

    Joined:
    Jul 22, 2013
    Posts:
    136
    Hey, I'm glad that helped you, it took me some time to figure out the issue myself.

    As for the pixelsToUnits, it should be the same value that you're setting up when you import your tilesheet textures. Now, the important thing is that your tilesheet is a power of two size, not necessarily all the tiles in it. So I can have a 1024x1024px tilesheet that has 40x40px tiles in it. So I'd set the pixelsToUnits to 40 then. :)

    That's basically how many Pixels are in 1 Unity Unit coordinate in the transforms. It's how the rounding rounds the coordinates.

    Cheers
     
    bowserscastle and Eric-Eidel like this.