Upside down Cinemachine Dolly Track?

Hi! I’ve beem experimenting with the Cinemachine Dolly Track to make a skate grinding system as of lately, and I’ve realised that I can’t turn the waypoints upside down, the up of the dolly track seems to be stuck looking towards the Scene Up, as shown in this pictures:
153831-annotation-2020-03-08-013327.png
And
153832-annotation-2020-03-08-013402.png

Is there any way to change this? I’d like to have the up vector of the path segments pointing down!

I’ve done this and the twisting is vexing. See my youtube channel trailer prototype,
The way I solved it is to use a second virtual camera pointing down and use an animation track to fade between them, but I still couldn’t get rid of the twist, so I embraced it!

I wanted to investigate a bit of this myself – the upside down camera is a good fix, but I’m making a rail shooter that has limited camera movement, so having another camera control that essentially does the same thing but with a flipped axis seems wasteful. TL;DR I’m in the same boat.

What I found is that you can roll all the way to 180 in a straight line, so the issue is not being upside down by itself, so that’s great. When the track starts going vertical and there’s a potential to be upside down, we start to have problems.

I think there might be a way to “cheat” if you set the roll to 180 as the track reaches the upward point of the loop and begins to head backwards, but you get a bunch of spins that you especially don’t want if a character is meant to be touching “ground”

163688-cinemachine-loopdeloop.png

I looked into how the pathing is done, and the issues are from EvaluateOrientation and EvaluateTangent in CinemachineSmoothPath (at least, that’s because it’s the script used when I generate a cart with a track).

EvaluateTangent takes in a point on a curve and gets the bezier tangent from the curve at that point and turns that into a worldspace direction and returns it.
EvaluateOrientation uses that to find the “forward” direction at the same point. Then it orients the track according to this information and the “up” direction it finds from the transform.

I think it narrows it down to any combination of these things, but I haven’t dug very deep and I’m not so great at the geometry involved:

  • BezierTangent3 is not taking into
    account the local up direction
  • The result from transform.TransformDirection does not provide enough info on the local up vector for EvaluateOrientation to do its job correctly
  • The operations in the if (!.fwd.AlmostZero()) block are ending up defaulting to the global Vector.up even though the local transformation is used.

Theoretically, I think this is solvable. We shouldn’t be losing a degree of freedom by climbing vertically because rotations are represented as Quaternions, which prevent gimbal lock when applying transformations to vectors. My hunch is that the code self-imposes a gimbal lock on accident when the previous point’s “up” becomes the next point’s “forward” in climbing vertically - and then rights itself by using the global up.
If I ever get a grip on how to fix this I’ll update.

,I wanted to investigate a bit of this myself.
You can roll all the way to 180 in a straight line, so the issue is not being upside down by itself, so that’s great.

I think there might be a way to “cheat” if you set the roll to 180 as the track reaches the upward point of the loop and begins to head backwards, but you get a bunch of spins that you especially don’t want if a character is meant to be touching “ground”

163688-cinemachine-loopdeloop.png

I looked into how the pathing is done, and the issues are from EvaluateOrientation and EvaluateTangent in CinemachineSmoothPath (at least, that’s because it’s the script used when I generate a cart with a track).

EvaluateTangent takes in a point on a curve and gets the bezier tangent from the curve at that point and turns that into a worldspace direction and returns it.
EvaluateOrientation uses that to find the “forward” direction at the same point. Then it orients the track according to this information and the “up” direction it finds from the transform.

I think it narrows it down to any combination of these things, but I haven’t dug very deep and I’m not so great at the geometry involved:
-BezierTangent3 is not taking into account the local up direction
-The result from transform.TransformDirection does not provide enough info on the local up vector for EvaluateOrientation to do its job correctly
-The operations in the if (!.fwd.AlmostZero()) block are ending up defaulting to the global Vector.up even though the local transformation is used.

If I ever get a grip on how to fix this I’ll update this.