Proper way to 'reset' follow camera?

Right now I have a camera that follows and aims at a 3rd person character controller. I have a function where the player can teleport back to a place they saved instantaneously. The problem is the camera kind of freaks out. It seems to be an issue with the Aim portion.

I took out the art assets and character. Every time the camera rotates like mad is when I am pressing the teleport/return button. It just sends the sphere back to the starting position. I’d like the camera to reset back to a similar location as the start of the gif.

qualifiedsardonicarmednylonshrimp

How do I get this to just reset like normal similar to right at the beginning of the scene start?

Bump

It looks to me as though you’re just warping the character to the start position. The camera is trying to follow, and because of the damping it takes time. You need to tell the camera to cancel the damping because this is a warp, and not just a fast movement that it has to follow.
When you warp the player position, add this call: vcam.OnTargetObjectWarped(), to inform the vcam of the situation.

oh so that function will turn off damping?

For that frame, yes. It will preserve the target-to-vcam spatial relationship by applying to the vcam the same position delta as the target, bypassing all damping for that frame.

Normally that call is used when you want a continuous-looking follow to happen across a warp of the target. A common use-case is infinite worlds when you wrap around.

If you’re trying to just start over, it might be easiest to disable the vcam re-enable it. That will cancel all previous state and make the vcam start over. While it’s disabled, you can also reposition the vcam if you want to give it an initial starting point.

Correction: Disabling/re-enabling the vcam won’t work because the vcam’s OnEnable() method won’t get called until the next frame. Try instead to reset the vcam by setting vcam.PreviousStateIsValid = false. That should make the vcam snap to the new spot.

Hm I tried both ways, but nothing seems to be happening. Still does the same thing.

vCam.OnTargetObjectWarped(t, posDelta);
vCam.PreviousStateIsValid = false;

podDelta is just subtracting the old position from the new position right?

Yes.

Can you show me the entire code that handles the reset? vCam.PreviousStateIsValid = false should do the job.

1 Like

I commented out a function on the last line that called ‘vCam.PreviousStateIsValid = false’ in another class. That’s all it does though.

public void Respawn(Vector3 p, Quaternion r)
{
        Vector3 posDelta = p - transform.localPosition;

        transform.localPosition = p;
        transform.rotation = r;
        rb.velocity = new Vector3(0, 0, 0);

        vCam.PreviousStateIsValid = false;

        //camMovement.ResetCamera(transform, posDelta);
}

Can you prove that vCam is actually the current active vcam? Also can you show me the inspector for the vCam, and for the CM Brain?

Yes it is the only vCam in the scene.

5017955--491372--upload_2019-9-30_22-40-34.png
5017955--491375--upload_2019-9-30_22-40-57.png

Need to see anything else?

It all looks good to me. I don’t see off the top of my head why vcam.PreviousStateIsValid = false wouldn’t work, if you’re calling Respawn(). Can you see in the scene view that the player pops back to the origin but the vcam travels gradually? Does the effect disappear if you set the vcam’s damping (all of it) to 0?

So I set all the damping and look ahead to 0, but it doesn’t go away completely. The rotation is still wonky, but only a tad. It doesn’t reset completely and it still lerps over to the spawn point(not a warp).

So you’re saying that with no lookahead and no damping (aim or body) you’re not getting a hard follow? That’s impossible. Turn off the noise too. If at that point the vcam isn’t attached as though with a hard rod to your player, then there is something else interfering.

5027036--492644--upload_2019-10-3_9-5-20.png

https://thumbs.gfycat.com/TheseAdorableBaiji-mobile.mp4

Seems like the position damping makes the position a little better. Not perfect.

The rotate is still pointing to the direction it was before the warp though. Would the only solution be to turn off all damping for one frame then reset the position of the vcam manually?

With those vcam settings, the camera should be 100% locked to the target - there should be no frame that doesn’t have the target firmly positioned in the center of the game view.

Yet, in your clip, there is this frame:

Conclusion: the camera target and the player are not the same game object. Camera target and player are not in the same position. Is that the case?

1 Like

Wow ok make me look dumb… lol. im ashamed

I was totally overlooking the fact I changed the target to be a separate transform… That other cameraTarget is being lerped towards the player position.

Thank you! It all works properly now.

1 Like

My use case : I teleport the player on a “room change” and I wanted the camera to seemlessly follow the player (and NOT lerp to the new position).

This answer was the way to go for me.
Thanks !

1 Like

The PreviousStateIsValid tricks doesn’t seem to work every time when you’re using a TargetGroup.
Most likely because it also lags behind the actual transform it’s following or something

I fixed it like this.
I changed the vcam smoothing to 0 so we get instant follow for a small duration.

//When warping the player over long distances, the camera lerps the entire distance till the player
//We want instant teleport of the camera over a long distance
public IEnumerator WarpCamera() {
            //This trick works if you're following the transform directly but with a target group it doesnt seem to work
            //CameraManager.singleton.vCam.PreviousStateIsValid = false;

            ChangeCameraDamping(0);

            //yield return null;
            yield return new WaitForSeconds(1);

            ChangeCameraDamping(1);
}

//get correct transposer depending on your cam settings
public void ChangeCameraDamping(float amount) {
            vCam.GetCinemachineComponent<CinemachineFramingTransposer>().m_XDamping = amount;
            vCam.GetCinemachineComponent<CinemachineFramingTransposer>().m_YDamping = amount;
            vCam.GetCinemachineComponent<CinemachineFramingTransposer>().m_ZDamping = amount;
}
2 Likes