Search Unity

Smoothly changing Y axis (Gravity flip)

Discussion in 'Cinemachine' started by Oskiii, Nov 10, 2019.

  1. Oskiii

    Oskiii

    Joined:
    Feb 23, 2016
    Posts:
    13
    Hey,

    I've spent some time now trying to get Cinemachine to play nice with our gravity flipping mechanic.

    How the mechanic should work:
    1. Step on tile: Gravity switches (usually, but not always, 180 degrees)
    2. Character starts falling towards new down direction
    3. Camera rotates to match new up/down direction, rotating the Rigs too, but trying to keep world position of camera to avoid unnecessary movement

    What I have tried so far:
    -Overriding WorldUp in CinemachineBrain
    -Rotating the VirtualCamera through code
    -Rotating the Aim target through code

    None of the above have produced satisfactory results, though I could just have a setting wrong somewhere.

    I'm wondering if there's a proper way to do this?
     
  2. Oskiii

    Oskiii

    Joined:
    Feb 23, 2016
    Posts:
    13
    Bumping this with some more information.

    Here's how the gravity flip mechanic worked previously:


    Here's a video of the unwanted behavior with Cinemachine:


    Unity version: 2019.2.10f1
    Cinemachine version: 2.3.4
    Integrations: Rewired

    Screenshot of the inspector:
    upload_2019-11-13_17-3-31.png

    The Follow and Look At targets are a pivot objects which follow the character via another script. Normally this pivot doesn't rotate at all, but in the above video of the broken gravity flip, I'm trying to rotate it by 180 degrees around the Vector3.right axis (direction of the camera) for debug purposes. As you can see, the transition isn't smooth.

    Basically, I just want to be able to rotate the camera around it's forward axis by some amount (usually 180 degrees) without it flipping out. Is there a better way to do this?
     
  3. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    hmmm... interesting problem.

    I like your general setup, with the floating CameraPivot - that gives you more control.

    The problem I see is that using a FreeLook with LockToTarget binding, the camera won't necessarily rotate in place, which is what you want it to do. Instead. imagine the surface defined by the 3 orbits, around the target, as being rigidly attached to the target, and the camera rigidly attached to a point of that surface, as determined by the current controller input state. Now you rotate the whole thing, which is what happens when you rotate the target, because LockToTarget binding means just that. The only way you'll get the camera to stay put is to rotate the CameraPivot target along the camera-to-target axis.

    However, that won't give you the final rotation you want.

    Probably what you'll have to do is something like this: at the start of camera rotation event, activate a new vcam that you create dynamically at the exact position and rotation where the FreeLook is. Give it a higher priority than the FreeLook, and zero or very small blend time. Put DoNothing in Aim and Body. That means that there will be no procedural camera behaviour, and you will be able to manipulate the new vcam's transform as you like. As the target flips over, rotate the new vcam 180 degrees along the vcam-to-target axis. When the flip is finished, deactivate the vcam, which will cause the FreeLook to blend back in. Make sure InheritPosition is checked on the FreeLook, so that it chooses the nearest point on its (now inverted) orbit surface.

    I suggest also that you switch all the angular damping modes to Quaternion, to avoid gimbal lock.

    Let us know how that works out for you.