Just as title, expose things like m_TargetOrientationOnAssign. Camera is at the center of game making, games are unique, enable us to make unique things without having to modify and keep our own version of every package you release. /end of rant
You assume you need that member, but very likely there is a way to get what you want without it. Exposing too many internals makes a bad API.
What are you trying to make? Maybe everything you need is already exposed.
I’m using ECS, with GO for presentation for certain entities like player. In the game you can stand on moving platforms that move and rotate. I use CinemachineOrbitalFollow for the player camera with; currently WorldSpace. But the idea to move to LockOnAssign and update m_TargetOrientationOnAssign as platform moves to rotate the reference frame without converting the rotation to Horizontal Axis and Vertical Axis inputs.
Probably a better strategy is to keep your invisible GO target always rotated to match the current reference frame. That is, keep its rotation at identity unless it’s on a platform, at which point you rotate it to match the platform. Then, you can set your camera’s binding mode to LockToTarget and leave it there. Your reference frame is thus controlled by your target.
I will try it out. But some quick tests, I think position dampening will make it not behave correctly. (Seems to have same issue if I rotated m_TargetOrientationOnAssign just a few minutes ago).
Having an invisible intermediate target gives you a lot of control. In general it’s a very powerful strategy. Make it match your player’s position exactly, and set the rotation how you want. Position damping has nothing to do with the rotation frame, so I’m not really sure what you’re referring to.
Yes, I’m already using proxy target as I don’t have everything as GOs. By that I handle dampening myself as well, so might just be some incorrectness in my own code now. I’ll need to investigate.
Moving between LockToTarget and World seemed to snap it to a different angle. Keeping it to LockToTarget and just rotating it with parent deltas if present seems to work fine (at least for platforms that stay with Y up).
The issue seems to be from Rotation Componser Damping. Will need to look into how to solve that one more.
So long as you move your proxy target smoothly, there should never be any problem with damping. Just set it to the amount you like. Since you don’t describe the issue, that’s about all I can say.
With LockToTarget binding mode, the OrbitalFollow will use the target’s up vector as its internal up, so there should be no problem rotating away from world up.
Ok, so the Rotation Composer you can verify yourself. This is a pure GO setup in gif below. I simply rotate the target in scene, and you can see that the rotation is dampened. So if we intend to keep the rotation space of the platform by rotating target with TrackTarget this will have same issue.
This works if I can swap betwen binding mode of world and target and not use deltas (which doesn’t have issue shown below). “targetRotation” in code below is parent rotation and "shouldBeLockedToTarget " is only true if we are on the platform.
var shouldBeLockedToTarget = cameraFinalTargetTransformDataRef.ValueRO.setLockToTarget;
var isLockedToTarget = cinemachineOrbitalFollow.TrackerSettings.BindingMode is BindingMode.LockToTarget;
if (shouldBeLockedToTarget != isLockedToTarget)
{
cinemachineOrbitalFollow.TrackerSettings.BindingMode = shouldBeLockedToTarget ? BindingMode.LockToTarget : BindingMode.WorldSpace;
cinemachineCamera.PreviousStateIsValid = false; // Tried both with and without
}
var targetPosition = cameraFinalTargetTransformDataRef.ValueRO.targetPosition;
var targetRotation = shouldBeLockedToTarget ? cameraFinalTargetTransformDataRef.ValueRO.targetRotation : quaternion.identity;
virtualCameraPresentationReferenceDataRef.ValueRO.targetProxy.Value.transform.SetPositionAndRotation(targetPosition, targetRotation);
You never need to change the binding mode. Leave it on LockToTarget and handle everything in your proxy target. When not on a platform, your proxy target does not rotate. When on a platform, it rotates with the platform. Make sure that when you get on/off a platform you do not snap the rotation to/from identity. Just start/stop rotating it. An easy way to do that is to simply parent it to the platform when riding, and to null when not.
Take a look at the FreeLook OnSphericalSurface sample scene which ships with CM. It has a moving platform that the target can hop onto.
For the rotation damping, it makes sense that you’re seeing it. You can stop it by setting the rotation composer’s damping to 0. However, that might give you an undesired rigidity. If you want to keep the damping, but not when the rotation is due to the platform, then you will have to do some work. Unfortunately Cinemachine does not support travelling reference frames out of the box.
EDIT: you mentioned earlier that you are handling damping yourself for your proxy target. If that’s the case, then you can just set CM’s damping to 0 and your problem is solved.
I haven’t tried it myself, but off the top of my head I can think of 2 ways to implement a traveling reference frame for Cinemachine.
-
Create a custom extension which tracks delta platform rotation and sets CInemachineCamera.State.RotationDampingBypass accordingly. You can search Cinemachine code for RotationDampingBypass to see some examples of how to set it. Make sure you set it after the Body stage, because OrbitalFollow will set it, and you want to add your value to it rather than overwrite it.
-
Write a script which tracks platform rotation and calls CinemachineCamera.ForceCameraPostion every frame to rotate the CinemachineCamera (and its damping state) along with the reference frame. You’ll need at least CM 3.1.5 for this, and you can look at the Portals sample scene for inspiration.
It’s excellent that you are using a pure-GO scene for your experiments, that keeps things nice and simple, and separates the concerns.
Knowing that your real project is entities-based, let me just flag one potential gotcha: it’s vital to move your GOs smoothly, using interpolation to compensate for Unity’s variable deltaTime. If you don’t do that, you will get jitter which no amount of damping can hide. I’m seeing jitter in your video, so I’m suspecting that smooth player movement will be an issue for you.
This was what I said worked before, but it does not solve the non Y up direction. You said the two below thus I showed that it does not work.
But I think that I came to a realiziation that it would be probelmatic if you’re in a non Y up, and you walk off, and it would hit the limits of what the orbital rings allow. So in those cases one would probably want some custom lerping for the Y when moving on and off anyway - which the “moving delta rotation to target” approach works with.
I handle the Orbital Follow Dampening yes. I’ve not digged into how the Rotation Composer dampening, but that’s a solution to do that myself as well.
I’ll check out the sample and the suggestion of custom extensions.
Yep, there’s interpolation from both platform and CC from physics, which I don’t think adds up 100%. Also with all debug stuff enabled server falls behind and you get some rollbacks ![]()
Normally, with LockToTarget, the orbital rings will respect the target’s up, no matter what it is, so there should be no issue with this.
Perhaps I don’t understand what you’re trying to do. When the player steps off the platform, what is supposed to happen? Does the player just remain in whatever rotation it was, or does it lerp back to world up? If the latter, you can just handle that in your proxy target script. As you lerp the proxy target’s rotation, the camera will naturally follow without any further intervention from you.
As for damping, here is what I was suggesting: Let your player proxy script fully handle the position damping. In other words, the proxy’s position should lag the real player’s position by some temporal amount. Then, set all of CM’s damping to 0 (position and rotation, everywhere). That will eliminate the reference frame problem, while preserving a damped camera (the CM camera will rigidly track your damped proxy).
Lets say the player moves on to a platform, it rotates around X 45 degrees, and now the player moves across to another platform rotated 45 degrees in opposite X. We can’t just continue to apply deltas if the new platform would move, but need to do some custom lerp to correct the up rotation. Same if the player moves off a platform, where Y up should be default up. So yeah, we agree^^
That sounds solid. But it sounds like the same type of dampening that I did for Orbital follow. As I said I haven’t investigated what type of damping the Rotation Composer does. On the TODO ![]()
We can’t just continue to apply deltas if the new platform would move, but need to do some custom lerp to correct the up rotation.
Let’s assume that the proxy target is parented to the current platform, or to null if no platform. When the player changes platform, you don’t want a sudden rotation pop, right? So you should just reparent the player proxy, not changing its rotation.
So, how to make it stand up properly? In your proxy target’s Update, you just need a single line to always lerp the proxy target’s local up a little bit towards Vector3.up. That will give you the desired effect in all cases.
As I said I haven’t investigated what type of damping the Rotation Composer does.
Rotation Composer handles camera rotation to frame the target at its current position. Because your proxy target has position damping built-in, RotationComposer’s damping is redundant. Set it to 0.
