Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Moving a Mixing Camera with Confiner Extension

Discussion in 'Cinemachine' started by LiterallyJeff, Sep 3, 2019.

  1. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Hey there,

    I'm finally getting to play around in Cinemachine again after a long time, and I'm trying to set up a scene with a 3D top-down perspective, sort of RTS style perspective. I have two perspective vCams, a zoomed out view, and a zoomed in view. FOV doesn't change, just position and rotation.

    For this, I'm using a Mixing Camera with the two vcams. That part is working well. I can move the mixing camera parent around for global planar movement, and change the weights to interpolate between the views for a fancy zoom.

    Now I'm trying to confine the whole system using the Confiner extension with a 3D bounding box.

    When I test this behavior, I'm able to (manually via transform gizmo) drag the mixing camera, or any vCam child outside the bounds and the vCam is moved back into the collider, but the transform is left where it was. This makes the vCam stay at the edge of the bounding box, and creates an offset between the vCam and its transform.

    Am I doing something wrong here? How can I manually control a vCam while also getting the benefits of the confiner extension?

    Perhaps I'm overlooking another way to set this up to leverage the procedural positioning? I don't have a Look or Follow target, I just have a scene that can be explored by dragging around and zooming.
     
    Last edited: Sep 3, 2019
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Of course as soon as I write this I have the idea to create an empty game object as a follow target, and give the vCameras a Framing Transposer to track it. That seems to be doing the trick and provides smooth motion as well.

    Still open to suggestions if there's something better for a target-less control scheme.
     
    Last edited: Sep 4, 2019
  3. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,760
    The vcam transform represents the requested vcam position, and the confiner applies a correction so that the final camera position so that it stays in the bounds. If you want the vcam transform to completely reflect the final camera position, you could write a little script to update the vcam's transform.position to match vcam.State.FinalPosition. The cleanest way to do that would be via a custom CinemachineExtension, but an ordinary behaviour would probably do the job.

    Actually I think the empty game object as target is a perfectly good way to do this.
     
    LiterallyJeff likes this.
  4. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Just for posterity, the empty gameobject target solution is working, but I had to create my own "confiner" for the target transform with dampening to preserve the original confiner functionality. (Previously the target would move outside the confiner bounds, causing undesired camera behavior until it returned)

    A 3D trigger and a script on the target like this did the trick:
    Code (CSharp):
    1. public Collider boundary; // trigger boundary
    2. public float stiffness = 1f;
    3. public float maxOvershoot = 1f;
    4.  
    5. private void LateUpdate()
    6. {
    7.     // if this target is outside the bounds
    8.     if (!boundary.bounds.Contains(transform.position))
    9.     {
    10.         // get the closest point on the bounds
    11.         Vector3 target = boundary.ClosestPointOnBounds(transform.position);
    12.  
    13.         // get a factor of how far the target is away from the desired position
    14.         float distFactor = Vector3.Distance(transform.position, target) / maxOvershoot;
    15.  
    16.         // apply it all to the speed to move over time
    17.         float step = distFactor * stiffness * Time.deltaTime;
    18.  
    19.         transform.position = Vector3.MoveTowards(transform.position, target, step);
    20.     }
    21. }
    Now the vCameras use the framing transposer to track this target, and the boundary is soft due to this new script.
     
    s_marcell, Fotal and Gregoryl like this.