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

Reposition target and camera runtime - how to avoid the "popping"?

Discussion in 'Cinemachine' started by agostonr, Jan 25, 2018.

  1. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    I'm in the making of a simple endless game where I use Cinemachine.
    My problem is that - as endless games require - I occasionally revert the position of the player and the environment to avoid going to high float values.
    I do have damping on my camera's X which causes a noticeable "popping" in the otherwise seamless revert.
    How could I avoid this popping?
    Here's what I code, pretty simple:

    Code (CSharp):
    1. playerTransform.position -= delta;
    2. Camera.main.transform.position -= delta;
     
    DenisGLabrecque likes this.
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Oh boy, I don't think we cover that case! Let me think more about it and get back to you.
     
    syscrusher likes this.
  3. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Can you show me a picture of your vcam inspector?
     
  4. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    @Gregoryl Okay, thanks. Btw cinemachine solves a lot of scripting for a decent cam movement for a project so thanks for adding it in :)
     
  5. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    upload_2018-1-25_16-31-14.png

    upload_2018-1-25_16-31-31.png
     

    Attached Files:

  6. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    Note I messed around with the cam a bit after the post so it isn't exactly the same but the popping effects remains.
    @Gregoryl Did I post the info you needed?
     
    Last edited: Jan 25, 2018
  7. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Yes, the popping effect will remain so long as you have damping. You can't just poke the Unity Camera's position, because it's 100% controlled by the vcam, so your value will be immediately overwritten.

    We need to add an API call in the vcam to apply the delta to both the camera and the damping data. There's no other way to get it to work. I'll see if I can throw together a patch for you. Is this your only vcam?
     
    Deeeds likes this.
  8. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    Yep, only Vcam. How to make that API call? Edit: and only camera in the scene. Edit again, the "we" in "we need to apply...." refers to you at unity, or you and I? :D sorry, not a native speaker, got confused xd.
     
  9. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    I need to give you a patch for CM that adds the API call. What version of CM are you using?
     
  10. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    Latest I found on the asset store, 2.1.10
     
  11. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    ok, thanks. Stay tuned, I'll get something to you asap.
     
  12. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    Great thanks :D in the meantime I build other parts of the game.
     
  13. jonathangutman

    jonathangutman

    Joined:
    Dec 6, 2016
    Posts:
    5
    We've had similar issues where we needed to position and rotate the camera because of seamless portals connecting with other parts of the level. Have not been able to get it working if there is an active blend occuring during the teleportation or if recentering is enabled on the active vcam.
     
  14. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    @Gregoryl Wouldn't want to rush you but approximately when to expect a patch?
     
  15. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    It's a little tricky, and there are a few things to check. Also there are other fires around here :). Probably today or tomorrow.
     
  16. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    That's actually pretty quick. Keep up the good work :D
     
  17. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    I have a fix for the repositioning of a camera, but rotation is a little trickier. Can you give a little more info about your situation? A sample project would be great.
     
    Last edited: Mar 17, 2020
  18. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    PMing you with the patch
     
  19. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    Sorry took apart some stuff in the project :( Right now it doesn't have the "teleport back" feature. However, It doesn't rotate the camera, it's fix always. It only tracks the movement of the player, the rotation of the cam is the same always.
     
  20. zibas

    zibas

    Joined:
    Sep 15, 2010
    Posts:
    31
    Any updates on this? I'm in the same boat as agiro. I recenter the whole world regularly.
     
  21. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    If you're on Unity 2018, you can grab the latest CM release candidate from the package manager. In it, there is a new API call: vcam.OnTargetObjectWarped. After repositioning your target, you would call it as follows (transform is the thing that got moved):
    Code (CSharp):
    1.             // Inform any vcams that might be tracking this target
    2.             int numVcams = CinemachineCore.Instance.VirtualCameraCount;
    3.             for (int i = 0; i < numVcams; ++i)
    4.                 CinemachineCore.Instance.GetVirtualCamera(i).OnTargetObjectWarped(
    5.                     transform, posDelta);
     
  22. zibas

    zibas

    Joined:
    Sep 15, 2010
    Posts:
    31
    Thanks. Any tips if my project isn't in a good place to move past 2017 yet?
     
  23. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    well... you could PM me and I could send you a patch
     
  24. EwigeDreamer

    EwigeDreamer

    Joined:
    Sep 29, 2017
    Posts:
    3
    Hello) @Gregoryl , i have a similar project with a similar problem: airplane simulator in very big world. I must teleport this airplane every 1km to the center of coordinates together with other objects in the scene. Every time I give all transforms in scene a Vector3 offset... (including a CMbrain and vcam, but it does not work)
    What do I need to do to make the camera teleport without jerking? (i use Unity 2017.1.2p4)
    fffffffffffffffffffffaaa.PNG
     
  25. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    @EwigeDreamer If you upgrade to CM 2.1.12 there is an API call to support exactly this: vcam.OnTargetObjectWarped(). Are you in a position to upgrade? You will need Unity 2018.
     
    metroidsnes likes this.
  26. agostonr

    agostonr

    Joined:
    Jan 3, 2016
    Posts:
    193
    @Gregoryl Just out of curiosity. On gamedev.stackexchange there is a DMGregory named super helpful user. Ain't he you?
     
  27. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    nope, but thanks for the flattering supposition
     
  28. MrMuh

    MrMuh

    Joined:
    Jan 6, 2019
    Posts:
    2
    Hi!
    I am currently trying to implement a floating origin reset and everything looks very seamless when I use the OnTargetObjectWarped API - but when I enable the Cinemachine Confiner extension it starts to get choppy again. I tried to call OnTargetObjectWarped on the Confiner script but it doesn't fix the issue.
    Code (CSharp):
    1. GetComponent<CinemachineConfiner>().OnTargetObjectWarped(player.transform, posDelta);
    @Confiner setup: I am not sure if it is important but I want to constrain the camera movement to the y axis and therefore I created a collider polygon with the following points:
    Code (CSharp):
    1.             Camera.main.ViewportToWorldPoint(new Vector3(0f, 0f, 0)),
    2.             Camera.main.ViewportToWorldPoint(new Vector3(1f, 0f, 0)),
    3.             Camera.main.ViewportToWorldPoint(new Vector3(1f, 100f, 0)),
    4.             Camera.main.ViewportToWorldPoint(new Vector3(0f, 100f, 0))
    Do you have an idea how I could fix this problem?
     
  29. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    @MrMuh You don't need the call OnTargetObjectWarped on the confiner, that will be done automatically by the vcam.
    Can you elaborate a little more on what is not working? Maybe put together a little example that shows the problem?
     
  30. MrMuh

    MrMuh

    Joined:
    Jan 6, 2019
    Posts:
    2
    @Gregoryl thank you very much for the feedback! While preparing my example I found the issue :D The issue was that I moved the camera to a point which moves the camera into the collider which is used by the confiner. The vcam got moved out of the collider polygon which caused this "choppy" movement. So in the end everything works perfectly fine :)

    Thx for the support!
     
    Gregoryl likes this.
  31. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    350
    Hi @Gregoryl, many thanks for this update. It is great!

    But imagine situation when you have base scene with the camera and vcam, you loading new scene in "additive" mode, spawn your character, move camera with OnTargetObjectWarped, set m_BoundingShape2D in Confiner. You getting to the portal, load new scene in "additive" mode, move character, move camera with OnTargetObjectWarped, and put new m_BoundingShape2D in Confiner.

    As result: if vcam collides with new bounds it jumps out of the bounds, move character deeper - vcam appears inside the bounds. Go to the edge - it jumps out again)

    I make workaround by RemoveExtension(Confin)+Destroy(Confin)+AddComponent(Confin)+AddExtension(Confin). And now I can load scene, warp my character and put new Confin.

    I assume there is some defect, as extensions know about warp, but do not handle it properly.
     
  32. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    You need to call confiner.InvalidatePathCache() when you change the collider shape.
     
    vhman likes this.
  33. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    350
    Yes, that works.

    Sorry, that is clearly pointed in documentation.
    Thanks!
     
  34. Anderson-Cardoso859

    Anderson-Cardoso859

    Joined:
    Mar 23, 2014
    Posts:
    61
    Hi, I'm trying to warp the camera while it follows a moving target but the camera is popping.
    OnTargetObjectWarped only works for stationary cameras/target?
    I'm using Unity 2019.2.10f1 Cinemachine 2.3.4 and a simple 2D Camera
     

    Attached Files:

  35. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    It should work for a moving target, if the speed stays constant across the warp
     
  36. Anderson-Cardoso859

    Anderson-Cardoso859

    Joined:
    Mar 23, 2014
    Posts:
    61
    Thanks for the reply :)
    I think I found the problem. The target is a Rigidbody2D and I'm warping it using the Rigidbody2D.position property but this doesn't change the target position immediately, so I can't call OnTargetObjectWarped right away.

    I tried the following snippet but the camera still popping:
    Code (CSharp):
    1. IEnumerator WarpRoutine(deltaPos)
    2. {
    3.     target.rigidbody2D.position += deltaPos;
    4.     yield return new WaitForFixedUpdate();
    5.     vmCam.OnTargetObjectWarped(target, deltaPos);
    6. }
    From the link below, WaitForFixedUpdate should happens after the Physics update when the Rigidbody2D will update its position, right?
    https://docs.unity3d.com/Manual/ExecutionOrder.html

    Am I doing something wrong? Any tips on this one?
     
  37. Anderson-Cardoso859

    Anderson-Cardoso859

    Joined:
    Mar 23, 2014
    Posts:
    61
    Wow, It's working! I used the following snippet:

    Code (CSharp):
    1. WarpRoutine(deltaPos)
    2. {
    3.     target.position += deltaPos;
    4.     vmCam.OnTargetObjectWarped(target, deltaPos);
    5. }
    I don't know if it's ok to update a Rigidbody2D by directly setting it's transform.position...but that was the only solution that worked for me.

    Regards,
     
  38. saporter

    saporter

    Joined:
    Mar 19, 2015
    Posts:
    7
    @Gregoryl The OnTargetObjectWarped() was a great fix for many instances for me, but wondering if you ever solved the rotation issue? This does not appear to work, as I'm sure you know, when I rotate my target and camera around a point... is there something else I'm missing?
     
  39. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    We have not done any specific work on this, although it's possible that there's a workaround for you. Can you show me the inspector for the vcam?
     
  40. einWikinger

    einWikinger

    Joined:
    Jul 30, 2013
    Posts:
    97
    Has the warping behaviour changed from 2.4.0 to 2.6.1? With 2.4.0 the warping worked perfectly but after upgrading to 2.6.1 the camera stutters and hitches when being warped. I'm just starting investigation what's going on and what exactly changed in the internals of CM to show this regression. I may also be able to quickly put together a reproduction project for investigation.

    Edit: 2.5.0 also worked, have small repro, will post issue as soon as submitted
    Edit: Already broken in 2.6.0, so not specific to 2.6.1
    Edit: 2.6.0-preview.2 already exhibited the broken behaviour
    Edit: Just saw 2.6.2-preview.1 exists, but this did not fix the issue
     
    Last edited: Sep 3, 2020
  41. einWikinger

    einWikinger

    Joined:
    Jul 30, 2013
    Posts:
    97
    Last edited: Sep 4, 2020
    Gregoryl likes this.
  42. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    @einWikinger Thank you for reporting this issue. The regression has been identified and fixed for CM 2.6.3 which is still unreleased. If you are in urgent need of a patch for the current CM 2.6.2, contact me and I will give you one.
     
    einWikinger likes this.
  43. einWikinger

    einWikinger

    Joined:
    Jul 30, 2013
    Posts:
    97
    Thanks for addressing that, I've seen the changes land in the repository, will pull them if we need the fix before 2.6.3 releases!
     
    Gregoryl likes this.
  44. JuriKnauth

    JuriKnauth

    Joined:
    Jul 26, 2017
    Posts:
    7
    I still have problems resetting the cinemachineVirtualCamera with OnTargetObjectWarped.
    What is the 2nd argument for Vector3 positionDelta?

    My cinemachineVirtualCamera uses the Framing Transposer Body, has some look-ahead time and smoothing, with some DeadZones (soft and hard).

    The camera should follow the player who has a rigid body. It is a game with a lot of physics, where I want to reset the player and all physical objects, so ideally the timescale would be 0 when I do the reset. However, the camera does not seem to update when the timescale is 0. Update Method and Blend Update Method of the CinemachineBrain are Fixed Update and it ignores Time Scale.

    Ideally I need a way to reset all smoothing and interpolation of the camera.
     
  45. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    The positionDelta parameter is the change in position of the target being followed. The vcam will also move that amount, while preserving the state of the damping so that you don't see a glitch.

    OnTargetObjectWarped is meant for infinite-world type situations where the player is warped to the other side of the world, and you want the camera to keep tracking it as if nothing happened. If, on the other hand, you just want to reset and cancel any damping in progress, then you can set vcam.PreviousStateIsValid = false.
     
    JuriKnauth and gaborkb like this.
  46. JuriKnauth

    JuriKnauth

    Joined:
    Jul 26, 2017
    Posts:
    7
    Thanks, Gregoryl! However, it did not quite work out for me. Because the camera target was still off-center - somewhere in the dead zone.

    I have come to a different solution: At the end of the game I run this in a corroutine when the time scale is already 0:

    So I set the DeadZones to 0 for an update step and also turned the camera on and off.

    Code (CSharp):
    1.          
    2.             Rigidbody[] rigidbodies = FindObjectsOfType<Rigidbody>();
    3.  
    4.             int rigidbodiesLength = rigidbodies.Length;
    5.  
    6.             SetRigidbodiesKinematic(rigidbodies, rigidbodiesLength, true);
    7.  
    8.             CinemachineFramingTransposer composer = _cinemachineVirtualCamera1.GetCinemachineComponent<CinemachineFramingTransposer>();
    9.  
    10.             float deadZoneWidth = composer.m_DeadZoneWidth;
    11.             float deadZoneHeight = composer.m_DeadZoneHeight;
    12.             float softZoneWidth = composer.m_SoftZoneWidth;
    13.             float softZoneHeight = composer.m_SoftZoneHeight;
    14.  
    15.             composer.m_DeadZoneWidth = 0f;
    16.             composer.m_DeadZoneHeight = 0f;
    17.             composer.m_SoftZoneWidth = 0f;
    18.             composer.m_SoftZoneHeight = 0f;
    19.  
    20.             Time.timeScale = 1f;
    21.  
    22.             _cinemachineVirtualCamera1.enabled = false;
    23.  
    24.             yield return new WaitForFixedUpdate();
    25.  
    26.             _cinemachineVirtualCamera1.enabled = true;
    27.  
    28.             yield return new WaitForFixedUpdate();
    29.  
    30.             composer.m_DeadZoneWidth = deadZoneWidth;
    31.             composer.m_DeadZoneHeight = deadZoneHeight;
    32.             composer.m_SoftZoneWidth = softZoneWidth;
    33.             composer.m_SoftZoneHeight = softZoneHeight;
    34.  
    35.             _cinemachineVirtualCamera1.enabled = true;
    36.  
    37.             Time.timeScale = 0f;
    38.  
    39.             SetRigidbodiesKinematic(rigidbodies, rigidbodiesLength, false);
    40.  
     
    Last edited: Dec 2, 2020
  47. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Do you have this option checked? That should center the target in the dead zone when PreviousStateIsValid == false.

    upload_2020-12-2_9-56-18.png
     
  48. JuriKnauth

    JuriKnauth

    Joined:
    Jul 26, 2017
    Posts:
    7
    Well "center on active" was always checked (on). Always has been.
    I'm using 2020.1.12f1. I will investigate further and report back, maybe its a bug.
     
  49. mntngoatgames

    mntngoatgames

    Joined:
    Aug 25, 2020
    Posts:
    4
    Has anybody had this work while using Lookahead? I've tried everything here, and tweaking various values, and adding an offset based on the vector between the cam and the character, but nothing seems to make it transition smoothly with the lookahead enabled. If I set smoothing to 0 it gets close, but it still centers the camera over the character at the time of the warp and then moves back to lookahead position.
     
  50. mntngoatgames

    mntngoatgames

    Joined:
    Aug 25, 2020
    Posts:
    4
    Ok, so I figured it out. Another one of my scripts was making it so that the vCams follow target wasn't actually the object I thought it was. I updated the script to make the OnTargetObjectWarped function use the right target and it worked.

    Now I just need to figure out how to keep my parralax layers from getting all screwed up when the camera moves back. They're being moved the same amount as everything else so I'm not sure why it's glitching.
     
    Gregoryl likes this.