Search Unity

Follow Target recovery

Discussion in 'Cinemachine' started by Livealot, Nov 13, 2018.

  1. Livealot

    Livealot

    Joined:
    Sep 2, 2013
    Posts:
    228
    When a live virtual cam loses it's "Follow Target" transform, the default behavior seems to be that the camera just stops in place. Is there anything in the brain or setup where we can change/control that default behavior?

    For example, disabling that camera so a different virtual cam could take priority would be a natural choice.

    Alternatively, are there listeners already in the api that we can use to choose what to do next?

    Or maybe just some simple scripts that we need to add to each virtual cam to handle the target becoming null? I'd prefer not to poll every frame that FollowTarget != null

    To provide a scenario for context, lets imagine a tower defense game where you have close up virtual cams following each attacker. When the attacker gets killed (follow target becomes null), you'd want the brain to move on to another virtual cam with a valid follow target instead of stare sorrowfully at the spot the attacker died. How would you set that up?
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    I'm afraid you're stuck polling. You could have a script that checks the brain's current active vcam for null targets and just deactivates the vcam if it finds one.
     
  3. Livealot

    Livealot

    Joined:
    Sep 2, 2013
    Posts:
    228
    Ok, will try this. Since some camera types require a Follow Target, and some don't, what's the best way to tell the difference between Body types? I don't see that in the API. Something like...

    Code (CSharp):
    1. //recover from lost target if necessary
    2.             if (mBrain.ActiveVirtualCamera.Follow == null) {
    3.                 //if Body of Live Vcam is 'Framing Transposer'
    4.                 //        find a new target, disable Live vcam, switch to a default cam, etc
    5.                 //else if Body of Live Vcam is 'Do Nothing'
    6.                 //        do nothing since camera isn't supposed to have a target
    7.             }
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    I have not tried this myself, so I'm just talking....

    You could try first of all to cast the brain's ActiveVirtualCamera to a CinemachineVirtualCamera.
    If you get one, then call vcam.GetComponentPipeline().
    For each component in the pipeline, call component.IsValid. If it returns false, then it's because the required target is null.

    For other types of vcams (e.g. FreeLook) you can just check the targets directly, or do whatever, depending on the vcam type.

    The response, if the camera is not valid, should probably be to just disable it and allow the most eligible remaining vcam to become active.
     
  5. Livealot

    Livealot

    Joined:
    Sep 2, 2013
    Posts:
    228
    Thanks for the ideas Gregoryl!

    While it would be great to have scripting access to all the settings like vcam Type, there is an exposed reference for vcam.Name so I can use some spaghetti code switches to work with my specific named cameras. This seems to be working...

    Code (CSharp):
    1. //recover from lost target if necessary
    2.             if (mBrain.ActiveVirtualCamera.Follow == null) {
    3.                 if (mBrain.ActiveVirtualCamera.Name == "CM follows some target") {
    4.                     mBrain.ActiveVirtualCamera.VirtualCameraGameObject.SetActive(false);
    5.                 }
    6.             }
     
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    Not a great idea, performance-wise, to be checking string names. It causes boxing and generates garbage every frame. The way I suggested is better.

    If you really want to go the spaghetti route, use a Tag for the eligible vcams instead of the name. No boxing.

    I don't understand why you say you don't have access to the vcam type. Just do
    Code (CSharp):
    1. var vcam = mBrain.ActiveVirtualCamera as CinemachineVirtualCamera;
    2. if (vcam != null)
    3. {
    4.     bla bla bla
    5. }
     
  7. Livealot

    Livealot

    Joined:
    Sep 2, 2013
    Posts:
    228
    To clarify what I mean by vcam type, how would I access the Body, Aim or Noise enum that is selected for that vcam? Once I have a reference to the vcam, I can access Name and Lens (e.g., vcam.Name, vcam.m_Lens), but I can't find the others.
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    GetComponentPipeline gets an array of CM components that implement the pipeline as defined by the enums you chose in the vcam inspector. Each enum value corresponds to a component type. In any case, you don't need to know the types, you just have to check if they're valid - i.e. if they have targets. Like this:
    Code (CSharp):
    1.             bool isValid = true;
    2.             var vcam = mBrain.ActiveVirtualCamera as CinemachineVirtualCamera;
    3.             if (vcam != null)
    4.             {
    5.                 var components = vcam.GetComponentPipeline()
    6.                 for (int i = 0; isValid && i < components.Length; ++i)
    7.                     isValid = components[i].IsValid;
    8.                 if (!isValid)
    9.                     vcam.gameObject.SetActive(false);
    10.             }
    11.  
     
  9. Livealot

    Livealot

    Joined:
    Sep 2, 2013
    Posts:
    228
    Let me check for understanding.
    Originally, I was hearing that component.isValid was a proxy for vcam.Follow == null

    Now, I'm hearing that component.isValid takes into account the specific requirements of each vCam type, and would only check vcam.Follow for body types that require a Follow Target

    So if the body type is Framing Transposer, component.isValid will be false when vcam.Follow == null
    But if the body type is DoNothing, component.isValid will be true when vcam.Follow == null

    If I'm now hearing you correctly, thanks for your patience
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    Yes that is exactly right.
     
    Livealot likes this.