Search Unity

Camera Blending: Keep Distance while Blending

Discussion in 'Cinemachine' started by zyzyx, Nov 16, 2017.

  1. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    227
    Hi,
    I have a bunch of VCams positioned around a single target. They are toggled by user input. Now when blending from one cam to the next, position and rotation are interpolated linearly. This means when the current cam is on the opposite side of the target, the camera moves through or extreme close to the target.
    Is it somehow possible to take Camera Distance (each vcam has different value) into account while blending from one cam to another? Or is there a better way to accomplish something like this?

    upload_2017-11-16_15-31-54.png upload_2017-11-16_15-34-47.png
     
  2. Adam_Myhill

    Adam_Myhill

    Joined:
    Dec 22, 2016
    Posts:
    342
    Hi @zyzyx Interesting scenario. Yes the standard blends will 'go straight' to the next camera. I get you're trying to preserve an arc.

    First thing, I can see you're on an older version of CM. Best to grab the latest HERE and if you're reading this a day or two after this was posted, the final released version should be on the Asset Store. Either way, get onto cm v2.1

    An approach you might want to try is using an Orbital Transposer Body method on your vcam and then animating / code driving the Heading Bias. That will cause your camera to rotate around its Follow object - which you can set to be any object at a desired orbital point.

    upload_2017-11-16_13-20-18.png

    You can poke the Heading Bias with this: m_Heading.m_HeadingBias

    Give that a try and let us know how it goes
     
  3. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    227
    Hey @Adam_Myhill
    Thanks for your quick reply! I will try what you suggested.

    Quick followup question: Are there any plans to let us plug in a custom vcam lerp function in a future update?
     
  4. Adam_Myhill

    Adam_Myhill

    Joined:
    Dec 22, 2016
    Posts:
    342
    Not immediately on the horizon. It seems you want to do a form of orbit so try the Transposer Heading idea.

    Or, why not create a dolly track with exactly the shape you want?
     
  5. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    227
    Well, there are many camera positions (even user created ones) so I would have to make sure there is a dolly track from every cam to every other cam.
    Will try the Transposer Heading, thanks again!
     
  6. Adam_Myhill

    Adam_Myhill

    Joined:
    Dec 22, 2016
    Posts:
    342
    Ah gotcha. I see now why you're interested in different blend strategies.
    Try the Transposer Heading, I have a feeling it will sort of work but not between user generated cameras.
    Let's discuss this further and do so after you've given that a try so we're on the same page in terms of options, or partial solutions. Cheers.
     
  7. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    227
    So I tested the Transposer Heading idea but it ended up being too restrictive and I would have to animate the target as well.

    I ended up modifying the Lerp method in the CameraState.cs and changed:
    Code (CSharp):
    1. state.RawPosition = Vector3.Lerp(stateA.RawPosition, stateB.RawPosition, t);
    to:
    Code (CSharp):
    1. state.RawPosition = Vector3.Slerp(stateA.RawPosition, stateB.RawPosition, t);
    Pretty simple but does the job for the most part. It does get ugly in some edge cases though. I will try to tweak it a little bit to make it more robust.
     
  8. Adam_Myhill

    Adam_Myhill

    Joined:
    Dec 22, 2016
    Posts:
    342
    Solid idea, we'll give that a look here to see how it responds.

    There's definitely a good idea around the ability to select different lerp methods... On a waaay older predecessor to Cinemachine we had a number of options available. In theory it was great, in practice most of them were hardly used.
     
  9. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    227
    After working with the above solution for a bit I think a spherical/cylindrical interpolation option for blending VCams would be very useful for scenarios like a garage in a racing game where the player can tune and view the various parts of a car, or a spaceship hangar, etc.
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    @zyzyx Until we implement full-fledged custom blending, you might try a temporary solution. What if you added a behaviour to the Unity camera, alongside the Brain, that enforced a specified distance from the target? Enable the behaviour when you want it.

    It would do its work in LateUpdate(). It can find out what the target is by getting the current CameraState from the brain. Make sure you set the script execution order such that the new script executes after the brain.
     
  11. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    227
    I tried doing it in LateUpdate and it worked well, but ended up modifying the CameraState as described above (which is much more convenient for what I'm doing).
    Code (CSharp):
    1. //state.RawPosition = Vector3.Lerp(stateA.RawPosition, stateB.RawPosition, t);
    2.  
    3. // "cylindrical" lerp
    4. var v_up = Vector3.up;
    5. float state_posY = Mathf.Lerp(stateA.RawPosition.y, stateB.RawPosition.y, t);
    6. var tempPos_A = Vector3.ProjectOnPlane(stateA.RawPosition, v_up);
    7. var tempPos_B = Vector3.ProjectOnPlane(stateB.RawPosition, v_up);
    8. state.RawPosition = Vector3.Slerp(tempPos_A, tempPos_B, t);
    9. state.RawPosition += v_up * state_posY;
     
  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    @zyzyx FYI in the next release of CM, the vcam has a built-in option for specifying positional blend style: linear, spherical, or cylindrical. Thanks for your feedback on this topic!
     
  13. zyzyx

    zyzyx

    Joined:
    Jul 9, 2012
    Posts:
    227
    Hey thanks for the heads up! This sounds awesome!