So I have been trying to write my own custom camera projection inspired by this article: Adding some perspective to your Unity 2D game.. Basically want to make a 3D scene look 2D without distorting the sprites. Seems like this implementation was written for HDRP so I tried adapting it to UDRP like so:
using Cinemachine;
using UnityEngine;
using UnityEngine.Rendering;
[ExecuteInEditMode]
public class CameraScript : MonoBehaviour
{
private Camera _camera;
public Vector4 up = new Vector4(0, 1, 0, 0);
public bool _resetMatrixOnEnd;
private void Start()
{
_camera = GetComponent<Camera>();
_camera.transparencySortMode = TransparencySortMode.Orthographic;
}
// Start is called once before the first execution of Update after the MonoBehaviour is created
private void OnEnable()
{
RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
RenderPipelineManager.endCameraRendering += OnEndCameraRendering;
}
private void OnDisable()
{
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
RenderPipelineManager.endCameraRendering -= OnEndCameraRendering;
_camera.ResetWorldToCameraMatrix();
}
private void OnBeginCameraRendering(ScriptableRenderContext scriptableRenderContext, UnityEngine.Camera camera)
{
if (camera == _camera && camera.cameraType == CameraType.Game)
SetMatrix(camera);
}
private void OnEndCameraRendering(ScriptableRenderContext scriptableRenderContext, UnityEngine.Camera camera)
{
if (camera == _camera && camera.cameraType == CameraType.Game && _resetMatrixOnEnd)
camera.ResetWorldToCameraMatrix();
}
private void SetMatrix(UnityEngine.Camera camera)
{
var matrix = camera.transform.worldToLocalMatrix;
// since Unity uses OpenGL's view matrix conventions we have to flip the output z-value.
matrix.SetRow(2, -matrix.GetRow(2));
matrix.SetColumn(2, 1e-3f * matrix.GetColumn(2) - up);
camera.worldToCameraMatrix = matrix;
}
public static Matrix4x4 ScreenToWorldMatrix(Camera cam)
{
// Make a matrix that converts from screen coordinates to clip coordinates.
var rect = cam.pixelRect;
var viewportMatrix = Matrix4x4.Ortho(rect.xMin, rect.xMax, rect.yMin, rect.yMax, -1, 1);
// The camera's view-projection matrix converts from world coordinates to clip coordinates.
var vpMatrix = cam.projectionMatrix * cam.worldToCameraMatrix;
// Setting column 2 (z-axis) to identity makes the matrix ignore the z-axis.
// Instead you get the value on the xy plane.
vpMatrix.SetColumn(2, new Vector4(0, 0, 1, 0));
// Going from right to left:
// convert screen coords to clip coords, then clip coords to world coords.
return vpMatrix.inverse * viewportMatrix;
}
public Vector2 ScreenToWorldPoint(Vector2 point)
{
return ScreenToWorldMatrix(_camera).MultiplyPoint(point);
}
}
While it looks correct in game, the issue comes when trying to get the camera to follow the player. I currently just have to camera as a child of the player object. You can see the issue here:
Basically, as the player and camera move along the z-axis, the camera moves in and out instead of following the player due to the changes I made to the camera projection. Any ideas on a way to handle this? Would like to be able to get an effect like this working.