Centering a angled/topdown camera on a given transform?

Hello, I’ve been working on a full 3d turn based tactics game. At the end of each turn I am trying to center (focus) the camera on the unit who’s turn is next.

My camera is the child of an game object which acts as a pivot, it is also offset and at an angle.

alt text

To zoom the camera I am changing the y position of the pivot, as changing FOV did not allow me the large zoom range I desire.

The problem I’m having is that when the y position of the camera is ~25, my script for centering it on the next unit is working fine but not when the y position is reasonably smaller/larger. In this case the unit is offset from the center of the screen. This is irregardless of the initial position of the camera before starting the scene.

At ~25:

alt text

At <25:

alt text

After some testing I’m nearly certain the problem is not to do with the moving/lerping of the camera, and is instead that I have likely over simplified the maths of this problem.

Below is where I calculate the new position/rotation of the pivot (this script is attached to the pivot). I simply get the center point on the ground where the camera is looking, and minus the pivots position to get the vector between them, then minus this from the units position, and use the units rotation so the camera is looking at it from behind.

	public void Focus(Transform target)
	{
		Vector3 targetPosition = target.position;

		Ray r = mainCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
		
		RaycastHit raycasthit;
		
		if (Physics.Raycast(r, out raycasthit, 100f, 1 << 10))
		{
			Vector3 centerPoint = raycasthit.point;
			
			Vector3 diffVector = centerPoint - transform.position;

			targetPosition -= diffVector;
		}

		if (cameraFocus != null && cameraFocus.isRunning)
			cameraFocus.kill();

		cameraFocus = Job.make(FocusCamera(targetPosition, target.rotation), false);
		cameraMovement.pause();
		cameraFocus.start();
	}

The movement of the camera uses the following co-routine so that the user movement can be paused while the camera lerps. Again I’m pretty sure this isn’t the problem but I’ll post the code incase.

private IEnumerator FocusCamera(Vector3 targetPosition, Quaternion targetRotation)
	{
		bool finished = false;

		Vector3 startPosition = transform.position;
		Quaternion startRotation = transform.rotation;

		float pos = 0;

		while (!finished)
		{
			pos += focusSpeed * Time.deltaTime;

			transform.position = Vector3.Lerp(startPosition, targetPosition, pos);
			transform.rotation = Quaternion.Lerp(startRotation, targetRotation, pos);

			if (pos >= 1.0f)
			{
				finished = true;
			}

			yield return new WaitForSeconds(Time.captureFramerate);
		}
		cameraMovement.unpause();
	}

Any help/advice on how to fix this, or a different behavior all together, or any useful aspect for that matter, would be much appreciated. Josh

Thanks to help from robertbu, in the comments of the question, I managed to fix this. I was over simplifying the calculation of the new rotation, I could not assume that I could just rotate the camera to the same angle as the target and always have it centered.

by removing:

transform.rotation = Quaternion.Lerp(startRotation, targetRotation, pos);

the target transform is now always centered in the view-port if this method is called. And I feel it looks better without changing the rotation from the users current camera rotation.

Thanks for the help

Maybe I’ve not understood what you want to do, but if all you want is that the camera looks at something, then why don’t you use Transform.LookAt()
?