I've been struggling with an issue for quite some time now and have all but run out of ideas.
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 this gif, when following around the player (a 24x24 sprite), the background tiles seem to warp 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;
}