Why does my tilemap look like it's low FPS?

You can see here:
https://imgur.com/a/LnhpdMf

Game plays super smooth as it’s fairly low fidelity. Watch the player character in the middle, no frame rate drop. And I don’t really experience any frame rate drop anywhere.

However, when the player is moving, it appears the tilemap is jittery/ stuttering/ low fps.

Is this a 2D issue? Graphics issue? Please help, thank you!

camera always centered on character so of course the character never moves relative to the screen

try putting some copies of that character standing still in the scene and you will see

I’m not sure I understand why this is an issue. What is the problem? What is the result? I’m hoping for advice as to why it’s happening.

Bumping, can anyone help with this?

It’s hard to tell from the video (since it would need to be recorded in fairly high FPS).
Only things I can think of is if there is pixel snapping going on (pixel perfect camera? Something else?)
I’ve used tilemaps before without this result, so it’s definitely not something default that should happen.

I mean place other sprite renderers on the map and see if its the same effect as the tilemap, so you can isolate if its a tilemap problem or an overall graphics problem

to tell you the truth this may be standard movement, but to be sure try turning off vertical sync, though if your monitor is 60hz the refresh rate will still be capped for 60fps

After further research I’m inclined to think it is this issue. Would you just recommend disabling pixel perfect? Tbh I set it up like two years ago and built on it, learned using a variety of tutorials, and not sure I ever really understood what the purpose of this was.

For the sake of narrowing down the problem you can try it. Not sure how your follow camera is setup, but another common “problem” is that the follow camera is updating in fixed update.

Ah well it turns out I must have removed pixel perfect at some point and just forgot. So that’s not the issue.

Not in fixed update, regular old update.

Totally stuck! Sucks.

How are you moving your character?

This is not a tilemap issue, it’s a camera issue (but more accurately a delta time issue). If you add a tiny bit of easing to the camera position it will smooth out the jitters.

Also, you might try upgrading to a unity version with this fix.

Hmm… can you tell me more about the camera easing?

Here’s a link to the download. If you can take a few minutes I would really appreciate you checking it out, especially since you’ve worked with pixels before.

https://ohnoponogames.itch.io/you-are-dead-demo

Tutorial may not be as apparent, but you’ll notice in the hub world and the main levels.

Ideally you want to fix the problem at its source, which is the jittery player movement. Camera easing wouldn’t fix the issue, just hide it.

If you give me more detail on how you’re moving your character I may be able to give suggestions.

I downloaded and played it, and the jittering I’m seeing falls in line with the camera jittering I’ve seen before. I can’t really diagnose it further without code context, though.

You can confirm the jittering is the camera yourself if you look at the player/camera moving in the scene view. In that context, it should just be the player/camera that is jittering rather than the world.

Wow thank you for taking the time to download and diagnose, I really appreciate it!

Here is my player’s movement script in Update():

            //Moving
            if (!isDodging)
            {
                //moveInput.x = Input.GetAxisRaw("Horizontal");
                moveInput.x = player.GetAxis("Move Horizontal");
                anim.SetFloat("Horizontal", moveInput.x);

                //moveInput.y = Input.GetAxisRaw("Vertical");
                moveInput.y = player.GetAxis("Move Vertical");
                anim.SetFloat("Vertical", moveInput.y);
            }

            moveInput.Normalize();


            //This is where you would put a bool for sliding on ice
            if (canWalk)
            {
                theRB.velocity = moveInput * activeMoveSpeed;
            }
            else
            {
                theRB.velocity = Vector2.zero;
            }

And for further reference here is the camera (I know there’s more here than you need, just some extra context because I didn’t feel like prettying it up):

    void Start()
    {
        moveSpeed = 100000;

        if (!isHub && shouldFollowPlayer)
        {
            target = PlayerController.instance.transform;
        }


        hubIntroStart = false;

        if (isHub)
        {
            PlayerController.instance.canWalk = false;
            Camera.main.orthographicSize = hubIntroSize;
            target = hubTargetStart;
        }
        //Calculate and store the offset value by getting the distance between the player's position and camera's position.
        //offset = transform.position - player.transform.position;

        //UIController.instance.bigMapText.SetActive(false);
    }

    private void Update()
    {
        if (target != null)
        {
            transform.position = Vector3.MoveTowards(transform.position, new Vector3(target.position.x, target.position.y, transform.position.z), moveSpeed * Time.deltaTime);
            {
                if (
                    //Input.GetButtonDown("Map")
                    PlayerController.instance.player.GetButtonUp("Map")
                    && UIController.instance.mapIsActive && !isBossRoom && !LevelManager.instance.isPaused)
                {
                    if (!bigMapActive)
                    {
                        AudioManager.instance.PlaySFX(pauseInSound);
                        ActivateBigMap();
                    }
                    else
                    {
                        AudioManager.instance.PlaySFX(pauseOutSound);
                        DeactivateBigMap();
                    }
                }
            }
        }

        if (isHub && (Input.anyKeyDown || PlayerController.instance.player.GetButtonDown("Dodge")) && !hubIntroStart)
        {
            StartCoroutine("HubIntro");
            hubIntroStart = true;
        }

       
    }

A few suggestions that may help:

  1. Turn on interpolation on your player Rigidbody.
  2. Place your camera code in LateUpdate.
  3. Use SmoothDamp instead of Lerp to ease the camera position.

For a more detailed breakdown of this problem and its solutions, check out this helpful article: Timesteps and Achieving Smooth Motion in Unity — KinematicSoup Technologies Inc.

Just came back to say I’ve spent the past few days trying out various combinations of your suggestions on different levels. Also tried out pixel perfect camera (was not using previously). Different results with different combinations.

Best result came from interpolating player rigidbody. It’s not perfect, but it’s a hell of a lot better. Thank you for the suggestion!

1 Like