Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Camera flips heading with rotation

Discussion in 'Cinemachine' started by Phaz0r18, May 5, 2024.

  1. Phaz0r18

    Phaz0r18

    Joined:
    Feb 21, 2013
    Posts:
    9
    Hi everyone, I'm trying to recreate the behaviour of my single player camera but with a group. I'm making an arcade racing game, and I'd like the camera to always follow the Player with an offset to the rear.

    Behaviour: I'd like the camera to aim at the Player, zoom in when stopped, zoom out slightly whilst moving and to lag in the rotation direction when turning and then re-centre behind the Player shortly after.

    I've been able to achieve this for a single player set as the Target/Look At.

    Gif :
    https://media.giphy.com/media/v1.Y2...ZfYnlfaWQmY3Q9Zw/PxWwCTsPYgDd3kNBu4/giphy.gif

    Using these vcam settings:


    (I'm using the 'Single Camera Controller' only to assign the Player as the Follow/ Look At targets and to dis/enable this GameObject or the Group GameObject when Players join/leave)

    However, when changing using the same settings with a CinemachineGroupTarget I get a few issues, Gif/ settings below:

    Gif Behaviour: https://media.giphy.com/media/v1.Y2...ZfYnlfaWQmY3Q9Zw/9Ap26de7CHgB03grsM/giphy.gif

    Vcam settings:

    I have the TargetGroup as the Main GameObject and another Virtual Camera as it's child, the issue I'm facing is that when the Player's turn a corner the Camera switches it's heading to follow the group from the front.

    I'm aware that's probably due to the Group Target's 'Rotation Mode' being the 'Group Average' however, I assumed limiting the 'X-Axis Value Range' in the Body property would limit the rotation. The behaviour I'm aiming for is that the camera would follow behind the group, able to aim around in an orbital arc limited to the rear half only which always re-centre's to the rear of the group? I think I'm just missing the magic combination of settings + extensions, any ideas?

    The other issue is that the Camera complains about the Look At target being the same as the Follow target, despite using the offset to increase the orbit range away from the center, is this correct or should this be detached or following a different object?
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,768
    You're tripping over a bug in CinemachineTargetGroup: the Group Average rotation mode is not behaving properly. We have logged an issue for this and will fix it.

    In the meantime, here is a workaround for you:

    Change the group's Rotation Mode to Manual, and add the following script to the group. It manually computes the average rotation.
    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. [ExecuteAlways]
    5. [RequireComponent(typeof(CinemachineTargetGroup))]
    6. public class AverageGroupMemberRotation : MonoBehaviour
    7. {
    8.     CinemachineTargetGroup m_Group;
    9.     void Start() => m_Group = GetComponent<CinemachineTargetGroup>();
    10.     void Update()
    11.     {
    12.         float weightSum = 0;
    13.         for (int i = 0; i < m_Group.m_Targets.Length; ++i)
    14.             if (m_Group.m_Targets[i].target != null)
    15.                 weightSum += m_Group.m_Targets[i].weight;
    16.         transform.rotation = CalculateAverageOrientation(weightSum);
    17.     }
    18.  
    19.     Quaternion CalculateAverageOrientation(float weightSum)
    20.     {
    21.         if (weightSum > 0.001f)
    22.         {
    23.             var averageForward = Vector3.zero;
    24.             var averageUp = Vector3.zero;
    25.             for (int i = 0; i < m_Group.m_Targets.Length; ++i)
    26.             {
    27.                 if (m_Group.m_Targets[i].target != null)
    28.                 {
    29.                     var scaledWeight = m_Group.m_Targets[i].weight / weightSum;
    30.                     averageForward += m_Group.m_Targets[i].target.forward * scaledWeight;
    31.                     averageUp += m_Group.m_Targets[i].target.up * scaledWeight;
    32.                 }
    33.             }
    34.             if (averageForward.sqrMagnitude > 0.0001f && averageUp.sqrMagnitude > 0.0001f)
    35.                 return Quaternion.LookRotation(averageForward, averageUp);
    36.         }
    37.         return transform.rotation;
    38.     }
    39. }
    40.  
    Next, you need to change some settings on your vcam. I used the Lock to Target with World Up binding mode, which does a better job at restricting the camera to be behind the group. Do you want mouse input from the user? If so, keep the Orbital Transposer. Otherwise, you can use a plain Transposer with some yaw damping to slow down the recentering. The axis range will only affect how much the user can turn the camera with the mouse.

    Here is what I used:

    upload_2024-5-7_9-12-25.png

    I've attached a test scene that shows both kinds of camera setups.
     

    Attached Files:

    Phaz0r18 likes this.
  3. Phaz0r18

    Phaz0r18

    Joined:
    Feb 21, 2013
    Posts:
    9
    Hi Gregory! Thank you so much for taking the time to respond as well as confirming a bug & providing a fix!

    I was able to utilise the script provided as well as changing a few settings with the vcam to get the desired effect.

    As well as adding the above script I also switched the Binding Mode as suggested and changed the 'Target Forward' to use 'velocity' instead. I'm not using any mouse input for the camera but found that the Transposer didn't re-center as well as the Orbital Transposer so I stuck with it and tweaked the re-centering time to get the desired effect.

    Now to try and figure out how to blend cameras!

    Working Gif: https://media.giphy.com/media/v1.Y2...ZfYnlfaWQmY3Q9Zw/BxMoQriaTNhxQpHQjl/giphy.gif

    Final Vcam Settings:
    https://imgur.com/a/nKO5Ejy
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,768
    Glad to hear it's working.

    If you're using Velocity as heading then you probably don't need to worry about the group's rotation any more and can remove the custom script.

    Also, if you're not using mouse input, then you might want to clear this field so that CM won't read the mouse.

    upload_2024-5-10_12-28-11.png
     
  5. Phaz0r18

    Phaz0r18

    Joined:
    Feb 21, 2013
    Posts:
    9
    It makes perfect sense that Velocity as a heading isn't tied to target.rotation so will try removing the script and monitor the effects, thanks for mentioning!

    Currently CM isn't reading any mouse input which is affecting my camera even with this setting enabled, clicking/dragging in any direction during gameplay has no effect. I was worried something like this may crop up, funny how getting another developer's input always highlights bugs :p

    I think this may be related to the other question I posted about using the Input system (https://forum.unity.com/threads/input-system-breaks-ui-toolkit-buttons.1582608/#post-9826938), as I'm having difficulty getting Unity to respond to any inputs that I haven't explicitly coded a response for.