I’m trying to teleport my player and I’m using a Cinemachine camera. It works ok-ish, but I get some serious dampening during the teleport when I don’t want ANY dampening during the teleport. Seems to me that the OnTargetObjectWarped should immediately pop the camera to where I teleported to, unless I’m misunderstanding the purpose of that method.
So I fade my screen to black -
Then I do this:
var delta = teleportTo.position - player.transform.position;
virtualCamera.OnTargetObjectWarped(teleportTo, delta);
player.Transport(teleportTo);
Then I fade my screen back in from black. And I should expect the camera to be exactly where I want it to be. Instead the camera is still transitioning toward the player transform. Am I misunderstanding something?
Should I be disabling the dampening values first? Seems like that defeats the entire purpose of the OnTargetObjectWarped call.
Has anyone else tried this code and it seems to change nothing? I made sure the delta was in the right order of operations and I also tried moving the PreviousStateIsValid before/after the warp with no discernable difference.
Edit: Uploaded a quick video showing the problem. It only appears to happen when I hold a direction on the analog stick or keyboard key while teleporting/warping. Occurs for both directions - I tried moving to the trigger zone from the left and the cam moved towards the player like the first example in the video below. I’m using Rewired for input but I don’t think that should really change much regarding Cinemachine’s behavior.
So you were right that the player had already been teleported but switching the order didn’t change anything.
I moved the code telling the camera that it needed to warp to the same file where the teleportation of the player occurs to make it easier to see the order of operations, but it still doesn’t instantaneously snap like I was hoping. I tried putting two slightly different versions of the code before and after the warp (commented one out when I tried the other as well as leaving both uncommented just to test but no dice either way) and the camera still lags behind a bit. I guess I can just cover the movement with a small loading screen if this doesn’t end up working.
/*code before warping attempt.
first, it checks if the object is a player.
then if a player has been detected entering the trigger for the next checkpoint,
it attempts to notify the camera will need to warp before/after the warp with slightly
different variables in the code
*/
cm = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<CinemachineVirtualCamera>();
cm.OnTargetObjectWarped(goToTeleport.transform, checkpointLocation.position - goToTeleport.transform.position);
Debug.Log("Warped Cam to chkpoint loc:" + checkpointLocation.position + " and current player pos: " + goToTeleport.transform.position);
cm.PreviousStateIsValid = false;
PlayerController_MainCharacter pcmc = goToTeleport.GetComponent<PlayerController_MainCharacter>();
pcmc.ResetPlayerToCheckPoint(checkpointLocation.position);
/*
that method teleports to the position as a vector 2 and resets velocity
public void ResetPlayerToCheckPoint(Vector2 CP_Position)
{
transform.position = CP_Position;
rigid2D.velocity = Vector2.zero;
}
*/
pcmc.ResetCatsToCheckPoint(checkpointLocation.position);
if (goToTeleport.GetComponent<RopeSystem>() != null)
goToTeleport.GetComponent<RopeSystem>().ResetRope();
}
else
{
goToTeleport.transform.position = checkpointLocation.position;
}
//code after warping; this.transform.position is from the trigger that causes the warp
cm = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<CinemachineVirtualCamera>();
cm.OnTargetObjectWarped(goToTeleport.transform, goToTeleport.transform.position - this.transform.position);
Debug.Log("Warped Cam to chkpoint loc:" + checkpointLocation.position + " and current warper obj pos: " + this.transform.position);
cm.PreviousStateIsValid = false;
Big red flag here: cm = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<CinemachineVirtualCamera>();
I think your setup is wrong. The vcam should not be a child of or component on the main camera. You want this:
One GameObject, which is the Unity Camera with a CM Brain.
A separate GameObject which is the vcam.
A third GameObject which is the player (used as vcam target).
None of those GameObjects should be parents or children of each other.
Next, to do the warping, it should look like this:
Player enters the warp zone, you record its position
Warp the player to the new spot.
If you want to completely reset the vcam and cancel the damping, you do vcam.PreviousStateIsValuid = false.
If you want to teleport the vcam along with the player and preserve its current state of damping (maybe it was catching up to the player and you want to keep that state across the warp) then instead of vcam.PreviousStateIsValuid = false you do CinemachineCore.Instance.OnTargetObjectWarped(player, playerNrewPosition - playerOldPosition)