Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Recentering X Axis of the free look camera with Simple Follow With World Up

Discussion in 'Cinemachine' started by DanielP_, Aug 27, 2020.

  1. DanielP_

    DanielP_

    Joined:
    Jun 4, 2019
    Posts:
    16
    Hi!

    I'm using the Free Look Camera for my new game with Simple Follow With World Up as binding mode and I can't recenter the camera in the X Axis.

    Using a normal Cinemachine Virtual Camera with Orbital Transposer and Simple Follow With World Up I can set the variable named "Value" (virtualCamera.m_XAxis.Value) and the camera works perfectly but if I try to recenter the camera in the same way like the other camera I have problems (it works if I change the value in the FixedUpdate method but causes problems with the aimed target).

    After reading different posts, I found two interesting posts:
    1. I tried the different proposed solutions in this post but none of them work for me and here you can see how looks the solution you proposed, (maybe am I missing something?)
    2. The second post, works fine but I can't manage to use fixed time to complete the rotation or using with a custom animationCurve to set the interpolation time.
    Thank you!
     
  2. gaborkb

    gaborkb

    Unity Technologies

    Joined:
    Nov 7, 2019
    Posts:
    856
  3. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    If you want to keep using the FreeLook, it's possible with a modified version of the SimpleFollowRecenter script. The problem with the original is that it was disabling the orbital transposers while recentering. This revised version works better. Just add it to your FreeLook.

    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3. using Cinemachine.Utility;
    4.  
    5. public class SimpleFollowRecenter : CinemachineExtension
    6. {
    7.     public bool Recenter;
    8.     public float RecenterTime = 0.5f;
    9.     protected override void PostPipelineStageCallback(
    10.         CinemachineVirtualCameraBase vcam,
    11.         CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
    12.     {
    13.         if (stage != CinemachineCore.Stage.Body)
    14.             return;
    15.  
    16.         Transform target = vcam != null ? vcam.Follow : null;
    17.         if (target == null)
    18.             return;
    19.  
    20.         if (Recenter)
    21.         {
    22.             // How far away from centered are we?
    23.             Vector3 up = vcam.State.ReferenceUp;
    24.             Vector3 back = vcam.transform.position - target.position;
    25.             float angle = UnityVectorExtensions.SignedAngle(
    26.                 back.ProjectOntoPlane(up), -target.forward.ProjectOntoPlane(up), up);
    27.             if (Mathf.Abs(angle) < 0.1f)
    28.                 Recenter = false; // done!
    29.             else
    30.             {
    31.                 angle = Damper.Damp(angle, RecenterTime, deltaTime);
    32.                 Vector3 pos = state.RawPosition - target.position;
    33.                 pos = Quaternion.AngleAxis(angle, up) * pos;
    34.                 state.RawPosition = pos + target.position;
    35.             }
    36.         }
    37.     }
    38. }
    39.  
    The only thing you will have to add to this is some code somewhere to cancel the recentering when the user tries to rotate (just set SimpleFollowRecenter.Recenter = false) otherwise it will obstinately keep trying until it gets there.
     
    Last edited: Aug 27, 2020
  4. DanielP_

    DanielP_

    Joined:
    Jun 4, 2019
    Posts:
    16
    Thank you for your response, It works but I don't see the way to implement this solution using an animation curve to define the camera movement. Is there any way to do this?
     
  5. DanielP_

    DanielP_

    Joined:
    Jun 4, 2019
    Posts:
    16
    This camera doesn't work for me (It isn't the behaviour that I'm looking for) and, in case to use a similar camera, I would prefer to use a Free Look Camera with World Space selected as Binding Mode.

    Thank you!
     
    gaborkb likes this.
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    The current recentering movement is defined in the script above, at line 31. It just damps out. You could replace that with a call to SmoothDamp for ease-in-ease-out, or add a field to the script defining a curve. What kind of movement are you looking for?
     
  7. DaniP_

    DaniP_

    Joined:
    Feb 9, 2015
    Posts:
    4
    Sorry for the delay in my response, I'm the same guy (PedragDanilovic) but I changed my nickname.

    Finally I could manage to adjust the movement making some changes, I used a simple virtual camera with orbital transposer and Simple Follow with World Up and I only moved the Y and Z axis of the FollowOffset using animationCurves attached to the movement of the right joystick.

    Thanks for the support and your solutions :)
     
    Gregoryl likes this.