Hi!
I’ve been working on a Cinemachine implementation of a camera I recently made.
The functionality is pretty simple, where I want the camera to look ahead of the player in the direction of the cursor by moving only on the X and Z axis, while retaining a fixed height (see gif).
digitalboilingegg
However, my implementation is not entirely correct. In theory, the yellow box should be at the intersection of the blue lines, but this is not correct when moving on the mouse on the Y axis of the screen. I realize that this is because I’ve locked the camera’s Y position which causes a slight skew, but I am unsure what the best way to rectify this is. See the following image, where the cursor is placed at the bottom of the screen but the yellow box is not at the intersection of the thin blue lines.
Zoomed in:

These are my cinemachine settings:
Furthermore, I have attached two scripts to my camera:
using UnityEngine;
public class CameraController : MonoBehaviour
{
[Header("General")]
[SerializeField]
float minPlayerScreenPositionX;
[SerializeField]
float maxPlayerScreenPositionX;
[SerializeField]
float minPlayerScreenPositionY;
[SerializeField]
float maxPlayerScreenPositionY;
[Header("References")]
[SerializeField]
Cinemachine.CinemachineVirtualCamera virtualCamera;
// Cached variables
Cinemachine.CinemachineFramingTransposer transposer;
// Start is called before the first frame update
void Start()
{
transposer = virtualCamera.GetCinemachineComponent<Cinemachine.CinemachineFramingTransposer>();
}
// Update is called once per frame
void Update()
{
updateCameraPositionBasedOnMousePosition();
}
void updateCameraPositionBasedOnMousePosition()
{
Vector3 mousePos = Input.mousePosition;
transposer.m_ScreenX = Mathf.Lerp(minPlayerScreenPositionX, maxPlayerScreenPositionX, Mathf.Clamp((Screen.width - mousePos.x) / Screen.width, 0f, 1f));
transposer.m_ScreenY = Mathf.Lerp(minPlayerScreenPositionY, maxPlayerScreenPositionY, Mathf.Clamp(mousePos.y / Screen.height, 0f, 1f));
}
}
and
using UnityEngine;
using Cinemachine;
/// <summary>
/// An add-on module for Cinemachine Virtual Camera that locks the camera's Z co-ordinate
/// </summary>
[ExecuteInEditMode] [SaveDuringPlay] [AddComponentMenu("")] // Hide in menu
public class LockCameraY : CinemachineExtension
{
float yPosition;
protected override void Awake()
{
base.Awake();
yPosition = transform.position.y;
}
protected override void PostPipelineStageCallback(CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
{
if (stage == CinemachineCore.Stage.Body)
{
Vector3 pos = state.RawPosition;
pos.y = yPosition;
state.RawPosition = pos;
}
}
}
So essentially, I’m changing the screenX and screenY variables based on the position of the mouse, but fixing the camera’s Y axis such that the camera’s zoom level doesn’t get altered.
Any help would be greatly appreciated!
P.S. the min- and maxPlayerScreenPosition variables are set to 0.33 and 0.66 respectively.


