Working on a 3rd person camera, I’d like the camera to follow and aim at the player, but move it 0.5 units to the (final) camera transform.right vector in order to have the player slightly to the left.
Changing the camera Aim → Tracked Object Offset or Aim → Screen X, just rotates the camera but doesn’t translate it.
I can also change the Follow Target so that it follows an empty GameObject that always stays 0.5f to the right of the player, but that would make the camera pivot around that offset instead of the player.
I can make the camera Follow an empty GameObject with this script attached to obtain the desired result:
public class FollowTargetWithCameraOffset : MonoBehaviour
{
public Transform target;
public Vector3 offset = new Vector3(0f, 0.0f, 0f);
public Vector3 cameraOffset = new Vector3(0f, 0.0f, 0f);
private Camera cam;
private Vector3 position;
private void FixedUpdate()
{
if (target == null) return;
if (cam == null) cam = Camera.main;
position = target.position + offset;
if ( cam != null ) position += cam.transform.right * cameraOffset.x;
transform.position = position;
transform.forward = target.forward;
}
}
With that solution, I’m getting the camera Right vector so that the target always stays to the right of the character, but as it depends on the Camera.transform.right, and the Cinemachine camera is chasing after this same object, it creates jerkiness as one depends of the other. Changing the Script Execution Order doesn’t seem to fix this issue.
So the final questions is: Is there any way to add a World Offset to the final position of a Cinemachine Free Look camera?
In any case, I can’t think of a single game rig that doesn’t use camera offset options, so please think about adding public Vector3 offset or something like that to the base Free Look camera
@xDavidLeon Thinking about it more, maybe the solution I gave you was overkill. Would you not get exactly the same result by setting the Composer Screen X (in the 3 rigs) to put the character a little to the left on the screen?
[Edit} You would also have to set the FreeLook Heading Bias to compensate for this, so that the character forward will match the camera forward.
Just wanted to pipe in here in support of this solution instead of the composer/bias one. In my game I dynamically move the look at point in front of the character a little bit based on their speed so that when they’re turning, especially to the left (which is the side of the screen they are on) they shift on screen to show more of what’s ahead of them. This code allows me not to have to re-do the math of the bias in that case, which is really nice. Thanks for writing this snippet, it’s very useful!
Please note that the above snippet needs to be adapted in order to work with the new CM 2.1 (RC available here: CM v2.1 Release Candidate ), because the API has changed.
I would strongly recommend upgrading, not least because the FreeLook is significantly improved. See the long list of features.
To make it extra easy for you, here is the new CameraOffsetter behaviour, modified to work with CM 2.1. Notice how much smaller it is
using UnityEngine;
using Cinemachine;
/// <summary>
/// An add-on module for Cinemachine Virtual Camera which post-processes
/// the final position of the virtual camera.
/// </summary>
[ExecuteInEditMode]
[SaveDuringPlay]
public class CameraOffsetter : CinemachineExtension
{
[Tooltip("How much to offset the camera, in camera-local coords")]
public Vector3 m_Offset = Vector3.zero;
protected override void PostPipelineStageCallback(
CinemachineVirtualCameraBase vcam,
CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
{
if (enabled && stage == CinemachineCore.Stage.Aim)
state.PositionCorrection += state.RawOrientation * m_Offset;
}
}
@Radiago In CM 2.1, the composer has a “lookahead time” setting, which does pretty much what you describe, out of the box. Give it a spin and let me know if it’s helpful.
Hi!
This code work so fine. But, if I use the Cinemachine Collider with this, does not work perfectly because the Cinemachine Collider ignores the offset.
Do u have a solution for this problem?