Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to snap a Virtual Camera to a Target?

Discussion in 'Cinemachine' started by CDF, Jul 1, 2017.

  1. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,307
    Wondering how to snap my game camera that follows and looks at the player to the position and orientation of the player during some scripted moment.

    Say the player gets teleported somewhere. I would like the camera following to also teleport while keeping the same orientation and position from the character.

    How can I achieve this? do I need to setup a "Snap" camera, then force some kindof a cut to it?
     
    Ash-Blue likes this.
  2. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,307
    I see there's a method:

    MutateCameraState

    but how do I apply that back to the Virtual Camera?
     
  3. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Hey sorry for the slow response - I'm on vacation and can't check in so often.

    Don't go down that rabbit hole. Disabling the follow cam then re-enabling it after the snap should do the trick.
     
  4. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,307
    Thanks
     
  5. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    16
    When I start my game scene and activate a virtual camera, I want it to snap into its final position right way. I tried calling UpdateCameraState with a very large delta time and it doesn't seem to work. The camera always takes several frames to position itself. Even when I set all the damping values to 0, it still does the same thing.
    Is there something I'm missing here? My virtual camera has a Framing Transposer and a Composer on it.
    Even if I disable the virtual camera, as soon as I enable it, it takes several frames to orient itself.
     
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    You shouldn't be using a Framing Transposer and a composer in the same vcam. They will fight. Try using an ordinary Transposer, not a Framing Transposer.
     
  7. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    16
    Thank you. I tried this and it works most of the time.
    I have a custom blend setting of **ANY CAMERA** to this camera with a Transposer and Composer = Cut.
    It doesn't work if the brain is currently in the middle of a blend. It ignores the **ANY CAMERA** setting and blends anyway. I even tried setting the brain's default blend to Cut when I want it to snap, but it blends anyway. All my damping values are 0.
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Sounds like you are tripping over an old bug, but I'm not 100% sure.
    Does this problem still occur with the very latest versions of Cinemachine? (2.2.9 for 2018, and 2.3.4 for 2019)
     
  9. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    16
    We are on 2.2.8.
    However since writing that post, I've got it to work 100% flawlessly now!! The trick was to turn off+disable the brain and then turn on+enable after switching virtual cameras.
    Thank you so much, and for replying so quickly too!
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    I'm glad it's working for you, but switching the brain off and on is a hack that you shouldn't have to be doing. It would be nice to get to the bottom of this and solve it properly. Do let me know if the problem persists after you upgrade to 2.2.9.
     
  11. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    16
    I tried upgrading to 2.2.9 and removing the hack of switching off the brain. It works the same!
    BUT, I've noticed the behaviour of the Framing Transposer in my other cameras have changed very drastically!! It doesn't even keep the follow point on screen anymore.
    So we can't do the upgrade because none of our cameras behave the same anymore. It's a bit scary to think that if we need a critical update in the future, we will need to re-adjust all our cameras.
     
  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    When you say: it "works the same" do you mean that is still has the problem, or that it works properly now without the brain on/off hack?
    In what way to the framing transposers behave differently? They should be the same.
     
  13. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    16
    Works the same as in it works properly without brain on/off hack.
    With the framing transposer, it works fine if the Screen Y is near the center of the screen. It also works fine if I set a large enough soft zone (or unlimited). It starts to break down when I move the Screen Y closer to the edge of the screen, with a small finite soft zone. The follow point falls off screen and then sometimes the camera frantically tries to find the follow point again. If I move the Screen Y back to center, it will find the follow point and focus on it.
     
  14. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Interesting. Would you be willing to put together a lightweight sample project the shows this problem, export it as a unitypackage, and send it to me?
     
  15. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    16
    I will try to get this to you today, but if I don't to it, then Monday.
     
  16. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Thank you, I appreciate that. I'd like to make sure that there will be no problems upgrading to latest CM.
     
  17. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    16
    Here you go. Put this in an empty scene and run it, and you should see the behaviour.
    If you set ScreenY to 0.5 or increase the soft zone height, behaviour reverts back to normal.
    The exact same prefab with 2.2.8 also has normal behaviour.
     

    Attached Files:

  18. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Thank you very much for that!

    Interesting use-case. Normally, when the framing transposer is used, we assume that there is no LookAt target - the Follow target does the job of both. However, you are using it differently, and the result is very nice.

    And you are right, there is a difference in behaviour for this use-case, starting with 2.2.9. I think it's a regression, and that we should revert to the old behaviour. The fix is very simple - just one line.

    At this point, here are the options for you:
    1. Stay on CM 2.2.8, and wait for CM 2.2.10, which will contain the fix
    2. Embed CM 2.2.9 into your project and patch it (downside: you will have to add CM to your source control, and later remove it when you upgrade to CM 2.2.10)
    3. Use a custom framing transposer that contains the patch (downside, it may not be compatible with future upgrades to CM, but when they come you can at that point revert to the standard framing transposer, which will contain the fix).
    I can help you with options 2 and 3, should you choose one of them.
    Again, thanks for finding and reporting this, and for using CM so creatively :D
     
  19. lolun

    lolun

    Joined:
    Nov 25, 2014
    Posts:
    16
    We will choose option 1. Thank you again for being a tremendous help!
     
    Gregoryl likes this.
  20. rguerrasa

    rguerrasa

    Joined:
    Apr 21, 2020
    Posts:
    3
    Hello @Gregoryl , so that you know, I belive this problem is still happening in Cinemachine 2.71. Here´s how I tested in my game.
    1) Set one camera
    2) Set four VCs attached to this camera (these are for isometric views of my character position)
    3) At runtime, set VC1.follow and VC1.lookAt to the player character (can be a cube, whatever), using Transposer and Composer, NOT framing Transposer.
    4) Do a Debug.DrawRay from VC1 to the character inside Update(). You will see that exactly two random rays get drawn, before the third ray is drawn at the final position of where the VC is set.

    Instead of doing the hack suggested by @Iolun, I set a counter to increment every frame. As soon as the counter hits 3, it frees the Update() function to perform the rest of the code and track the character.

    So you might probably ask: Why these two frames matter so much? The answer is: It´s because I have a FogOfWar effect that draws a ray from the VC to the character on Update() and the opens up the FOW OnCollide(). If I do not se the buffer, these two frames will draw two random Rays and open up a random holes in my FOW, before the camera snaps to the correct location.

    It´s almost imperceptible, but created a problem for me in this case. So, I solved with a frame buffer.
     
  21. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    @rguerrasa For sure if you set the LookAt/Follow on one frame and then try to do stuff based on camera position, it won't work unless you wait for the camera to be positioned. The camera positions itself in CinemachineBrain.LateUpdate, and CinemachineBrain has a late script execution order. So if you want to respond on the same frame to a camera target change, you'll have to do it in LateUpdate, in a script that executes after CinemachineBrain. Alternatively, you can hook into CinemachineCore.CameraUpdatedEvent, which is fired immediately after the CM Brain positions the camera.
     
  22. lafr3mdulo

    lafr3mdulo

    Joined:
    Oct 8, 2021
    Posts:
    10
    Hello, just a note for anyone like me looking for an answer to this a few years later. I'm on version 2020.3.30f1 and CinemachineVirtualCamera now has a ForceCameraPosition function that snaps the virtual camera to a target.
     
    atrivedi7 likes this.
  23. Squeazer

    Squeazer

    Joined:
    Aug 4, 2015
    Posts:
    13
    Another solution for this that worked for me, you can call the internal update method with a deltaTime of 10 seconds (or whatever works for you), which will more or less evaluate the "blend" (might cause other issues, depending on your setup):

    Code (CSharp):
    1. cinemachineBrain.ActiveVirtualCamera.UpdateCameraState(Vector3.up, 10f);
     
    Last edited: Jul 10, 2022
  24. Amircu

    Amircu

    Joined:
    Aug 25, 2019
    Posts:
    1
    For anyone still struggling with this issue, Cinemachine was since then updated with a new function to address this issue specifically! It's called CinemachineVirtualCamera.OnTargetObjectWarped:

    Code (CSharp):
    1. /// <summary>This is called to notify the vcam that a target got warped,
    2.         /// so that the vcam can update its internal state to make the camera
    3.         /// also warp seamlessy.</summary>
    4.         /// <param name="target">The object that was warped</param>
    5.         /// <param name="positionDelta">The amount the target's position changed</param>
    6.         public override void OnTargetObjectWarped(Transform target, Vector3 positionDelta)
    7.         {
    8.             if (target == Follow)
    9.             {
    10.                 transform.position += positionDelta;
    11.                 m_State.RawPosition += positionDelta;
    12.             }
    13.             UpdateComponentPipeline(); // avoid GetComponentPipeline() here because of GC
    14.             if (m_ComponentPipeline != null)
    15.             {
    16.                 for (int i = 0; i < m_ComponentPipeline.Length; ++i)
    17.                     m_ComponentPipeline[i].OnTargetObjectWarped(target, positionDelta);
    18.             }
    19.             base.OnTargetObjectWarped(target, positionDelta);
    20.         }