I'm using a Cinemachine Virtual Camera in a 2D project to follow around a target. The ground / background is a Unity Tilemap GameObject.
As you can see in the gif above (or on Imgur), when following around the player (a 24x24 sprite), the background tiles seem to warp or shimmer a bit.
I've tried to script all types of solutions to adjust the Virtual Camera transform position and hopefully snap/move it "correctly" to no avail.
I don't even know for sure that the source of the issue is with the camera setup. I'm running out of solutions to something that seems like a pretty straightforward and very common scenario. I've created a sample project illustrating the issue which can be downloaded here.
Using Unity 2017.3.1f1 Personal. The background sprites are 32x32, with a PPU of 32. No compression, Point (no filter), rendered using a material with Shader: Sprites/Default, and Pixel snap.
Cinemachine Virtual Cam is set to Ortho lens size 16, Body: Framing Transposer with default settings.
Thank you so much for any suggestions or tips!!!
It feels similar to what's being described here with sub-pixel movement but I don't know for sure, and the solution in that blog post seems like it should be unnecessary (but again - maybe not).
I've created camera scripts and attached them to the virtual camera as follows:
float maxPixelHeight = 32; CinemachineVirtualCamera vcam; public void Awake() { float scale = Screen.height / maxPixelHeight; float orthographicSize = (Screen.height / scale) / 2f; vcam = GetComponent<CinemachineVirtualCamera>(); vcam.m_Lens.OrthographicSize = orthographicSize; } public void Update() { Vector3 tempPos = vcam.transform.position; Vector3 newPos = new Vector3(Mathf.RoundToInt(tempPos.x), Mathf.RoundToInt(tempPos.y), Mathf.RoundToInt(tempPos.z)); vcam.transform.position = tempPos; } I've also tried:
public void Update() { Vector3 tempPos = vcam.transform.position; Vector3 newPos = new Vector3((float)System.Math.Round((decimal)tempPos.x, 2) , (float)System.Math.Round((decimal)tempPos.y, 2), (float)System.Math.Round((decimal)tempPos.z, 2)); vcam.transform.position = newPos; } and something like:
public void Update() { Vector3 tempPos = vcam.transform.position; vcam.transform.position = new Vector3(RoundToNearestPixel(tempPos.x), RoundToNearestPixel(tempPos.y), RoundToNearestPixel(tempPos.z)); } public float RoundToNearestPixel(float unityUnits) { float valueInPixels = unityUnits * maxPixelHeight; valueInPixels = Mathf.Round(valueInPixels); float roundedUnityUnits = valueInPixels * (1 / maxPixelHeight); return roundedUnityUnits; } 


