Search Unity

Can Cinemachine Virtual Cameras have their own culling masks?

Discussion in 'Cinemachine' started by DChap_Salty, Jul 12, 2019.

  1. DChap_Salty

    DChap_Salty

    Joined:
    Dec 4, 2018
    Posts:
    3
    I have a Main Camera w/ Cinemachine brain. 2 Virtual cameras, A & B. I have a car model on its own "car" layer. I want virtual cam A to render the car, but when I cut to cam B, I want it to not render the car.

    Can I do this?

    It seems the Culling Mask option only exists on the Cinemachine Brain and I cannot adjust the culling mask for each virtual camera.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    That's correct. The culling mask is a feature of the Camera, not of the virtual camera. You would have to make a custom script to change the culling mask when vcam B activates, and change it back when vcam B deactivates.
     
  3. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Will this change in v3? Without being able to set culling masks, VirtualCameras aren't actually VirtualCameras, they're only half implemented -- you can't use them for shots where layers matter (which is a core feature of Unity, and many things rely on it working as-designed/built-in).
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    With CM3, the vcams are entirely decoupled from the layer system.

    We have no specific plans to implement a feature to manipulate the camera's layer mask, but we do provide an API (CinemachineExtension) so that you can implement custom extensions to drive properties that are not included in the core implementation.

    This would be a good topic for a tutorial video. Taking note. Can you describe the use-case that you have in mind?
     
  5. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    e.g. from a new asset I'm working on (and making sure it's compatible/integrated with CineMachine core features) I'm testing at the moment (modular in-game player-editable weapons):



    What's happening:
    1. Vcam-1 shows the player's FPS/3PS camera (here: over-the-shoulder, can run around with FPS controls)
    2. Vcam-2 shows all the modular weapons the player has collected, from a side-view, making it easy to re-build the weapon in different configurations
    3. All GameObjects in the main game/map are on default layer
    4. ...but all GameObjects that only exist in player inventory are on an 'Inventory' layer
    5. Vcam-1 is rendering 'Everything ... [minus Inventory]"
    6. Vcam-2 is rendering 'Everything'
    7. When blend 1->2 FINISHES, the mask switches to show 'everything' (inc. inventory)
    8. When blend 2-1> STARTS, the mask switches to show 'everything except inventory'
    In general ... vcam-2 probably wouldn't render 'everything' (e.g. in an actual scene, I wouldn't render all the nearby objects/etc -- only the player's location (Terrain + Buildings + large scene-items)) so that in 'editing weapon' mode the player camera doesn't get interfered with by random nearby objects/physics.

    Note also: this is Unity's preferred way of handling things, and has the benefit that it isn't just making the cameras render nicely, it's also making sure Physics etc works correctly, automagically, because everything in Unity is (should be!) filtered by Layer/LayerMasks.
     
  6. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,445
    VCams don't render, Cameras do. VCams are just "presets" to the most common camera properties. It's up to you to respond to VCam switches to do anything to the camera that is not included in the preset.

    On your other thread about blending events, I completely agree. CM should be notifying with plain events on BEGIN and END of a blending. It's lazy for CM to leave that to hackish piggybacking sniffer scripts to try to figure out what's going on inside the Brain.
     
    Unifikation likes this.
  7. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Right, but ... specifically in Unity (other engines are designed differently) the culling-mask is a fundamental 'common property' of the Camera. All other Unity features/APIs/systems have been dependent since the very first versions of Unity on a shared concept that layermask defines the whole game/render/physics/everything logic. A camera's cullingmask isn't a 'nice to have', it's essential to understanding what that camera will draw.

    Or, to put it another way: pre-CineMachine every time I worked on a project with custom multi-camera setups (blending, timeline-style animations, even funky stuff like matrix interpolation (if you're careful then you can smoothly blend Unity cameras from Orthographic -> Perspective, even though lots of people on the forums don't believe it ;))) ... then we've had at least some variation in layermasks for the different cameras.
     
  8. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    FWIW: my neatest solution so far is to take @Gregoryl's example from the thread @halley referenced - https://forum.unity.com/threads/oncameratransition-onblendcomplete-event.520056/#post-8887161 - and modify it so that it generates a trio of callbacks:

    Code (CSharp):
    1.  
    2. class VirtualCameraReactToBlendInOut : MonoBehaviour
    3. {
    4. // ... various bits from @gregoryl's example, that then invoke these 3 callbacks:
    5. public abstract void _OnVirtualCameraAnimateIn_Started( CinemachineVirtualCameraBase vcam );
    6. public abstract void _OnVirtualCameraAnimateIn_Finished( CinemachineVirtualCameraBase vcam );
    7. public abstract void _OnVirtualCameraAnimateOut_Started( CinemachineVirtualCameraBase vcam );
    8. }
    9.  
    ... and then subclass that to do mask updates, which seems to work well. I'm expecting/hoping to update/replace the base class sometime in 2025 (when CMv3 is supported in Unity production versions :)), and remove its hacky code, but I shouldn't need to change the subclasses which are now independent, e.g.:

    Code (CSharp):
    1. public class SetVirtualCamerasMask : VirtualCameraReactToBlendInOut
    2. {
    3.     public LayerMask cullingMaskWhileLive;
    4.     private LayerMask _savedLayerMask;
    5.  
    6.     public override void _OnVirtualCameraAnimateIn_Started( CinemachineVirtualCameraBase vcam )
    7.     {
    8.     }
    9.  
    10.     public override void _OnVirtualCameraAnimateIn_Finished( CinemachineVirtualCameraBase vcam )
    11.     {
    12.         _savedLayerMask = Camera.main.cullingMask;
    13.         Camera.main.cullingMask = cullingMaskWhileLive;
    14.     }
    15.  
    16.     public override void _OnVirtualCameraAnimateOut_Started( CinemachineVirtualCameraBase vcam )
    17.     {
    18.         Camera.main.cullingMask = _savedLayerMask;
    19.     }
    20. }
     
    Gregoryl likes this.
  9. SureSight

    SureSight

    Joined:
    Aug 2, 2013
    Posts:
    65
    You can add a custom extension. This works like a charm for me

    1. Create the below class "CinemachineExtensionLayerMask"
    2. Click the "Add Extension" dropdown on the virtual camera and select "CinemachineExtensionLayerMask" from the list
    3. Configure the desired layer mask on the extension

    Code (CSharp):
    1. public class CinemachineExtensionLayerMask : CinemachineExtension
    2. {
    3.     [SerializeField]
    4.     private LayerMask _layers;
    5.  
    6.     protected override void PostPipelineStageCallback(CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
    7.     {
    8.         Camera.main.cullingMask = _layers;
    9.     }
    10. }
     
    Whatever560 and two7two like this.
  10. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    519
    Camera.main would bring issues in multi cam setup. However the workaround does not seem that simple ... just have a look at CinemachinePostProcessing extension and it will chill your spine ...
     
  11. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    It's not so bad. That extension has extra complexity for reasons of its own. To get the Unity Camera associated with a vcam, you can do:
    Code (CSharp):
    1. Camera GetCamera(CinemachineVirtualCamera vcam)
    2. {
    3.     var brain = CinemachineCore.Instance.FindPotentialTargetBrain(vcam);
    4.     return brain != null ? brain.OutputCamera : null;
    5. }
     
    Whatever560 likes this.
  12. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    519
    This indeed seems way less complex, thanks very much @Gregoryl !
     
    Gregoryl likes this.
  13. aplusgreenlawn

    aplusgreenlawn

    Joined:
    Nov 14, 2023
    Posts:
    16
    Hey Im new to all this even C#, culling mask, virtual cameras. Im have a problem with my camera going Live when activated, it activates but stays in Standby and ive been trying to figure this out for 3 days and its frustrating me. Ive read other posts and i dont understand what anyones talking about. I have a vcam on a DollyCart thats fine in picture its CM vcam2. Player vcam1 Is my main virtual camera, and Shoot vcam3 is my aim in zoom cam all the settings are the same as Player vcam1 other then higher priority which does nothing by the way no matter what i have it at for Shoot cam3, and Field Of View is 25 instead of 40. Ive tried various ways in script and in inspector to fix this spoke with an AI for 2 days but every answer it gives is wrong, Ive messed with every setting, only thing Ive noticed is people talking about culling mask in cinemachine brain, which in mine theres nothing that says culling mask only my main camera not the virtual ones has a culling mask function in inspector, but everyone with my problem says this is the fix and i cant figure it out.. I took 3 screen shots one with MainCamera Cinemachine Brain, Shoot vcam3 with PlayerShooting.cs, and Player vcam1 with ThirdPersonShottingController.cs. Can anyone tell my why my Shoot vcam3 activates but doesnt change from standby to Live? one thing Ive noticed is I have one of those DollyCart Cams that show the level before starting and my Shoot vcam3 says Live during the cut scene but once the main Virtual cam Player vcam1 starts it goes back into standby. ShootCamPlayerShoot.jpg PlayerCamThirdPersonScript.jpg MainCamBrain.jpg
     
  14. aplusgreenlawn

    aplusgreenlawn

    Joined:
    Nov 14, 2023
    Posts:
    16
    everything else works fine my animation and right mouse click Aim button all work fine just the cam dont leave standby once main VR cam kicks in
     
  15. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    @aplusgreenlawn My friend, please consider using sentences and punctuation in your posts. It's very hard to understand what you're saying in your wall of text.

    1. The camera's culling mask is a field in the Unity Camera component (not the CM Brain). Since your vcams are all on the Default layer, make sure that the culling mask includes Default.

    2. If your culling mask is ok and your vcam is still not going live, probably it's the vcam Priority. If multiple vcams are active, the CM Brain will make Live the one with the highest Priority. If multiple vcams have that same highest Priority, then the most-recently-activated one will win.
     
  16. aplusgreenlawn

    aplusgreenlawn

    Joined:
    Nov 14, 2023
    Posts:
    16
    My typings not the best, sorry. I think I may have figured it out while I was walking the dog. When I created my Player vcam1, I did some timeline thing with my CM vcam2 From the DollyCart on the DollyTrack to make My DollyCam smooth into my Player vcam1. And when I created my Shoot vcam3 I just duplicated my Player vcam1 and changed some settings, so I'm thinking that might have something to do with it. And thanks Gerg!
     
  17. aplusgreenlawn

    aplusgreenlawn

    Joined:
    Nov 14, 2023
    Posts:
    16
    I dont know what happen, now I can't find the timeline that was created for doly cam to player cam. Everything works as it should in GamePlay my "Aim" button works. The camera transition works! It just sits in standby though.
     
  18. aplusgreenlawn

    aplusgreenlawn

    Joined:
    Nov 14, 2023
    Posts:
    16
    Shoot vcam3 has highest priority on my list but only activates when I press the "Aim" button (RightMouseClick), but it will not come out of Standby "Status".
    I also tried having my "PLayer vcam1" Deactivate/Activate when my "Shoot vcam3" is Activated/Deactivated. But "Player vcam1" stays Live "Status" even when Deactivated and lower Priority?
     
  19. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    Do you have an active Timeline that is forcing Player vcam1? Timeline overrides the Priority system (and will even force-activate deactivated vcams).