Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Framing Transposer - Camera Distance Only

Discussion in 'Cinemachine' started by jimmyjamesbond, Apr 2, 2019.

  1. jimmyjamesbond

    jimmyjamesbond

    Joined:
    Mar 17, 2015
    Posts:
    19
    Is there any way to use the Framing Transposer just for dolly out to frame the group without changing the position to fit all objects? I want the main character to be at the center of screen at all times but the dolly out to accommodate enemies other objects. I've tried adding enemies to the Target Group as a very small weight and large radius but that still contributes to the position of the camera a bit which isn't ideal. Any ideas?
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,243
    Put the main character as the sole member of the target group. Add a custom script to dynamically adjust its radius in the group to be equal to the distance to the farthest enemy you want to have in frame.
     
  3. jimmyjamesbond

    jimmyjamesbond

    Joined:
    Mar 17, 2015
    Posts:
    19
    Eureka! Can do. This would be a great mode to add to Cinema Machine. Distance Framing Only or something.
     
  4. YannigJuicy

    YannigJuicy

    Joined:
    May 20, 2019
    Posts:
    2
    Could you put your Script Jimmy please ?

    Thanks for help
     
  5. Fressbrett

    Fressbrett

    Joined:
    Apr 11, 2018
    Posts:
    83
    necro, but I just came across this exact problem. After trying out custom CinemachineExtentions to revert the position changes and writing custom scripts for camera framing, the solution proposed by @Gregoryl is surprisingly simple and achieves exactly what I was looking for!

    @YannigJuicy, here is a simple script that does what you want:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using Cinemachine;
    4.  
    5. namespace Nachtwerk
    6. {
    7.     /// <summary>
    8.     /// This component updates the radius of a CinemachienTargetGroup Target, based on distances to Targets defined in this script.
    9.     /// This can be used to utilize a FramingTransposer on a CinemachienVirtualCamera in order to dolly out to frame the group without
    10.     /// changing the local X/Z position to fit all objects, i.e. to get a "true dolly" without any other camera movement.
    11.     /// To use this component, just define all targets you want to frame here and only add a single target to the CinemachineTargetGroup, the one you want to center on.
    12.     /// </summary>
    13.     [RequireComponent(typeof(CinemachineTargetGroup))]
    14.     public class FramedTargetGroupRadiusUpdater : MonoBehaviour
    15.     {
    16.         [System.Serializable]
    17.         public class Target
    18.         {
    19.             public Transform Transform;
    20.             public float Radius;
    21.         }
    22.  
    23.         public List<Target> Targets = new List<Target>();
    24.         private CinemachineTargetGroup _targetGroup;
    25.  
    26.  
    27.         private void Update()
    28.         {
    29.             UpdateRadius();
    30.         }
    31.  
    32.         private void UpdateRadius()
    33.         {
    34.             if (TargetGroup == null || TargetGroup.m_Targets.Length == 0)
    35.                 return;
    36.  
    37.             float maxDistance = 0f;
    38.             foreach(Target target in Targets)
    39.             {
    40.                 float targetDistance = (TargetGroup.Transform.position - target.Transform.position).magnitude + target.Radius;
    41.                 if (targetDistance > maxDistance)
    42.                     maxDistance = targetDistance;
    43.             }
    44.  
    45.             CinemachineTargetGroup.Target[] cinemachineTargets = TargetGroup.m_Targets;
    46.             cinemachineTargets[0].radius = maxDistance;
    47.             TargetGroup.m_Targets = cinemachineTargets;
    48.         }
    49.  
    50.         private CinemachineTargetGroup TargetGroup
    51.         {
    52.             get
    53.             {
    54.                 if (_targetGroup == null)
    55.                     _targetGroup = GetComponent<CinemachineTargetGroup>();
    56.                 return _targetGroup;
    57.             }
    58.         }
    59.     }
    60. }
     
    Yuchen_Chang likes this.