Search Unity

Question How do I get two Vcams to interpolate between each other based on distance?

Discussion in 'Cinemachine' started by SevDavis, Apr 12, 2021.

  1. SevDavis

    SevDavis

    Joined:
    Nov 12, 2015
    Posts:
    8
    Hey all,

    I've set up two virtual cameras within cinemachine, in my code
    i've got them named as "Battle Camera1" and "Battle Camera2".

    Basically, I want the either camera to gain higher priority based on the distance between the player and the enemy AI object.

    In battle camera one the priority is higher if the player and the enemy AI character is farther apart, while this camera is active the player's view is of an over head shot of the world.

    When the player and the enemy AI is close to each other and engaging in combat the Battle Camera 2 should be active, that camera view is more intimate, and close to showcase the visceral nature .

    code is as follows.
    .................................................................................................

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using Cinemachine.Utility;
    6.  
    7. public class CameraZoom : MonoBehaviour
    8.  
    9.  
    10. {
    11.     //Virtual Camera Variables that will store the Virtual camers  that will swap based on distance
    12.     [SerializeField]
    13.     private GameObject[] battleCamera;
    14.    
    15.  
    16.     //Variable for storing the Camerablend  component
    17.    // [SerializeField]
    18.    // private CameraBlender vCamBlender;
    19.  
    20.     //Virtual Camera Priority/Weight Variables that store the priority of the dominant Camera
    21.     [SerializeField]
    22.     private float battleCamOnePriority;
    23.     [SerializeField]
    24.     private float battleCamTwoPriority;
    25.  
    26.     //Distance Variable for storing distance
    27.     [SerializeField]
    28.     private float enemyDistance;
    29.     [SerializeField]
    30.     private float playerDistance;
    31.  
    32.  
    33.     //Actor game object Variables to store the game characters
    34.     [SerializeField]
    35.     private GameObject player;
    36.     [SerializeField]
    37.     private GameObject enemies;
    38.  
    39.  
    40.  
    41.  
    42.  
    43.     //State of Virtual Cameras that will become active and inactive depending on the player's distances
    44.     private bool battleCameraOneIsActive = true;
    45.     private bool battleCameraTwoIsActive = false;
    46.  
    47.     void Awake()
    48.     {
    49.         //upon starting the scene, Distance variables are set to the player and enemy's transoforms
    50.         playerDistance = Vector3.Distance(player.transform.position, enemies.transform.position);
    51.         enemyDistance = Vector3.Distance(enemies.transform.position, player.transform.position);
    52.  
    53.    
    54.  
    55.     }
    56.  
    57.     // activating the virtual cameras
    58.     public void ActivateCamera(int index)
    59.     {
    60.         for (int i = 0; i < battleCamera.Length; i++)
    61.         {
    62.             if (i == index && playerDistance > enemyDistance)
    63.             {
    64.                 battleCamera[i].SetActive(true);
    65.                 battleCamOnePriority = 5;
    66.                 battleCamTwoPriority = 0;
    67.  
    68.             }
    69.             else
    70.             {
    71.                 battleCamera[i].SetActive(false);
    72.                 battleCamTwoPriority = 0;
    73.  
    74.             }
    75.         }
    76.  
    77.         for (int i = 0; i < battleCamera.Length; i++)
    78.         {
    79.             if (i== index && playerDistance <= enemyDistance)
    80.             {
    81.  
    82.                 battleCamera[i].SetActive(true);
    83.                 battleCamTwoPriority = 5;
    84.                 battleCamOnePriority = 0;
    85.             }
    86.             else
    87.             {
    88.                 battleCamera[i].SetActive(false);
    89.                 battleCamTwoPriority = 0;
    90.             }
    91.         }
    92.     }
    93.  
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    I don't see a question here. Do you have something specific to ask?
     
  3. SevDavis

    SevDavis

    Joined:
    Nov 12, 2015
    Posts:
    8
    Hi Gregory,
    I'm trying to get my virtual cameras to interpolate between each other based on the calculating the distance between the player object and the enemy game object.

    Since cinemachine camera virtual cameras display views on a priority system, I'm trying to code specific a specific function in which battle camera one has more priority when the player and the enemy game object is far apart, and when the player is in close proximity and attacking each other the second camera takes priority to better display it.

    Currently in the code, the camera's aren't functioning as I want and I'd just like some help in getting them to work

    I hope i was clear enough.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    One way to do this would be to have the far vcam be at normal Priority (say 10), and the near vcam at lower priority, so that by default the far vcam is active.

    Then, on your near vcam, add a custom script that raises its priority above 10 when player/enemy distance is below a desired threshold, and lowers it again below 10 when distance is greater than the threshold. You just need to check the distance and change the priority of the near vcam. The CM Brain will take care of blending between the vcams. You can adjust this bend time in the Brain's Default Blend property.

    Here is a sample script that does that:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Cinemachine;
    5.  
    6. // Attach this script to the near vcam.
    7. // Populate the Player and Enemy fields in the inspector.
    8. public class ActivateWhenClose : MonoBehaviour
    9. {
    10.     public Transform Player;
    11.     public Transform Enemy;
    12.  
    13.     public float ThresholdDistance = 10;
    14.     public float HysteresisDistance = 1;
    15.  
    16.     public int LowPriority = 9;
    17.     public int HighPriority = 11;
    18.  
    19.     CinemachineVirtualCamera nearVcam;
    20.  
    21.     void Start()
    22.     {
    23.         nearVcam = GetComponent<CinemachineVirtualCamera>();
    24.     }
    25.  
    26.     // Update is called once per frame
    27.     void Update()
    28.     {
    29.         bool nearCameraIsActive = nearVcam.Priority >= HighPriority;
    30.         var distance = Vector3.Distance(Player.position, Enemy.position);
    31.  
    32.         if (nearCameraIsActive && distance > ThresholdDistance + HysteresisDistance)
    33.             nearVcam.Priority = LowPriority;
    34.  
    35.         if (!nearCameraIsActive && distance < ThresholdDistance - HysteresisDistance)
    36.             nearVcam.Priority = HighPriority;
    37.     }
    38. }
    39.  
     
  5. SevDavis

    SevDavis

    Joined:
    Nov 12, 2015
    Posts:
    8
    Thank you so much, I did some reworking in the hours that followed and came to a similar solution. I really appreciate your assistance to this.

    kindest regards
     
    Gregoryl likes this.