Search Unity

Decide on blend type right before vCams translation

Discussion in 'Cinemachine' started by Deadcow_, Mar 2, 2020.

  1. Deadcow_

    Deadcow_

    Joined:
    Mar 13, 2014
    Posts:
    128
    I've got the game with plenty of static cameras. Every camera has its own trigger area and when player steps on the trigger this causes camera translation. Default CinemachineBrain blend works just fine.
    This said, vCams are not following player in any way.
    Trigger causes this code to run:

    Code (CSharp):
    1.  
    2. public void FocusVolume(CameraVolume volume)
    3.         {
    4.             if (_latestVolume != null) _latestVolume.VirtualCamera.Priority = 190;
    5.             _latestVolume = volume;
    6.             volume.VirtualCamera.Priority = 210;
    7.         }
    8.  
    Player also often goes between different scenes and on the new scene he triggers new vCam I need this translation to be instant. Previous scene kept loaded but disabled btw, if it matters.
    I found no way to just warp CinemachineBrain to the specific vCam. I tried two things:

    Code (CSharp):
    1.  
    2. public void FocusVolume(CameraVolume volume)
    3.         {
    4.             var currentScene = volume.gameObject.scene.name;
    5.             var onNewScene = currentScene != _latestLoadedScene;
    6.  
    7.             var brain = _gameplayCamera.GetComponent<CinemachineBrain>();
    8.             if (onNewScene)
    9.                         brain.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.Cut;
    10.             else
    11.             {
    12.                         brain.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.EaseInOut;
    13.                         brain.m_DefaultBlend.m_Time = volume.TranslationTime;
    14.             }
    15.  
    16.             if (_latestVolume != null) _latestVolume.VirtualCamera.Priority = 190;
    17.             _latestVolume = volume;
    18.             volume.VirtualCamera.Priority = 210;
    19.             _latestLoadedScene = currentScene;
    20.         }
    21.  
    So, here I try to set Default Blend to Cut right before camera transition, but this change is not applied right away, it's applied on the next transition.
    I also tried to put second part of this code (with priority changing) in coroutine, skipping one frame.

    Other thing I tried:
    Code (CSharp):
    1.     private CinemachineBrain _brain;
    2.  
    3.     public void AB(ICinemachineCamera a, ICinemachineCamera b)
    4.     {
    5.         if (a != null && b != null && a.VirtualCameraGameObject.scene.name != b.VirtualCameraGameObject.scene.name)
    6.         {
    7.             var blend = _brain.ActiveBlend;
    8.             blend.Duration = 0.1f;
    9.         }
    10.     }
    11.  
    12.     public void B(CinemachineBrain b)
    13.     {
    14.         _brain = b;
    15.     }

    upload_2020-3-2_15-43-27.png

    I am able to detect ActiveBlend I need, but Duration value is not applied...

    So, is there some "correct" way to decide on next blend type via script?
     
    Last edited: Mar 2, 2020
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,446
    Have you tried creating a CustomBlends asset? It allows you to customize blend styles on a per-vcam basis.

    upload_2020-3-2_13-58-33.png
     
  3. Deadcow_

    Deadcow_

    Joined:
    Mar 13, 2014
    Posts:
    128
    I thought about that, but I've got dozens of scenes, and it's not always possible to tell from which location player will come, and same vCam may be activated instantly or regularly. And also at this stage of development we're rearranging scenes so pretty often. So the process of setting up this asset will cause lots of pain.
    It is doable, but I'd like to find some better way. It seems right to me to do this from code...
    I also thought I might generate CustomBlends asset and create conditions for every vCam to every other vCams from different locations.
    Links count will grow exponentially, but i think it'll be below 1k of items anyway.. But it feels like a terrible idea for me)
     
    Last edited: Mar 2, 2020
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,446
    ok. You should be able to do it from code.
    I like your FocusVolume() method. It should work.
    When is it called?
    The transition is triggered in the Brain's LateUpdate method, and your new blend style needs to be in place at that time. If you only ever set it just before activating a vcam, then it should do the job for you. Can you put some Debug.Logs in there to prove that it's not getting reset elsewhere?
     
  5. Deadcow_

    Deadcow_

    Joined:
    Mar 13, 2014
    Posts:
    128
    Oh my, you are right, It's my mistake.
    I put some logging messages and figured out that transition — "CameraActivatedEvent" comes before my FocusVolume.
    It happening, as I assume, because at first previous location is deactivated and new one is activated, here comes automatic transition, without any vCam priority toggling, and then OnTriggerEnter fired and FocusVolume called.

    Ok, done! Thanks for quick response Gregoryl
     
    Gregoryl likes this.
  6. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    483
    Apologies for jumping on this thread, but this is very similar to a problem I'm having currently. Maybe I'm approaching this problem incorrectly, but runtime transitions seems like a common problem. We have dozens of dynamically instantiated cutscenes that contains their own VCAMs that we blend to. The current transition scriptable object doesn't work in our case either because these cameras are not active or in the scene as the Brain. I'd love to have a friendlier API that would allow us to add procedural transitions easier than overwriting the default blend or digging into the fixed-length array of m_CustomBlends. Is there an easier method to do this that maybe I'm missing?
     
  7. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,446
    @Ferazel The custom blends asset is name-based, not object-reference based, so custom blends set in there will work on any vcam with a matching name. Could you solve your problem with systematic naming of these dynamic vcams?

    The latest version of CM (2.5.0-preview.2) has a new inspector for the Custom Blends asset that allows you to directly edit the vcam names, without forcing you to point to a loaded vcam.
     
unityunity