Hi,
I’m heavily relying on StateDrivenCamera, however in a scene setup that was working perfectly well previous camera don’t get deactivated when changing the state. I tried debugging internally (ChooseCurrentCamera and InternalUpdateCameraState) and I don’t see how the code deactivate previous camera
CM_MainLoop should be deactivated here. Going back and force state calls InternalUpdateCameraState but don’t disable either of the two



[Edit 1]:
I steped in :
public override void OnTransitionFromCamera(
ICinemachineCamera fromCam, Vector3 worldUp, float deltaTime)
fromCam is CM_MainLoop as expected, “this.” is CM_CollectionCamera. However no deactivation here. I also tried putting steps on AddActiveCamera and RemoveActiveCamera it never steps in
So I’m looking at previous State Driven Camera code before the rewrite :
You were iterating through all cams and deactivating those not being the “best” (Not sur it was a good practice, letting the transition do the deactivation feels indeed better)
if (m_ChildCameras != null)
{
for (int i = 0; i < m_ChildCameras.Length; ++i)
{
CinemachineVirtualCameraBase vcam = m_ChildCameras[i];
if (vcam != null)
{
bool enableChild = m_EnableAllChildCameras || vcam == best;
if (enableChild != vcam.VirtualCameraGameObject.activeInHierarchy)
{
vcam.gameObject.SetActive(enableChild);
if (enableChild)
CinemachineCore.Instance.UpdateVirtualCamera(vcam, worldUp, deltaTime);
}
}
}
}
I implemented this myself previously and it was VERY useful, I think I can manage it with an extension however so it can be extended to any type of VCam.
if (mActiveBlend != null)
{
mActiveBlend.UpdateCameraState(worldUp, deltaTime);
m_State = mActiveBlend.State;
}
else if (LiveChild != null)
{
if (m_InheritChildPriority)
{
Priority = LiveChild.Priority;
}
m_State = LiveChild.State;
}

It’s pretty rough but here is an extension that handles child priority inheritance, I’m pretty sure it could be included in the package if you feel so. Also there is a small fix for state driven camera not deactivating children.
It seems to work on my project (there is a couple of extension method, use builtin “as” keywork and ! operator for the bool)
public class CinemachineInheritChildPriority : CinemachineExtension, IHasUpdate
{
[Tooltip("If recursive retrieve all childs in hierarchy otherwise only direct childs")]
public bool Recursive = false;
[Tooltip("Set childs list to be updated at each frame instead of awake")]
public bool AlwayUpdateChildList = false;
private List<CinemachineVirtualCameraBase> _childs;
private CinemachineVirtualCameraBase _cinemachineCameraRoot;
protected override void Awake()
{
base.Awake();
UpdateChildren();
_cinemachineCameraRoot = GetComponent<CinemachineVirtualCameraBase>();
}
private void UpdateChildren()
{
var childs = GetComponentsInChildren<CinemachineVirtualCameraBase>(includeInactive: true)
//Do not take root object as child
.Where(c => c.gameObject != gameObject);
_childs = (Recursive ? childs.Where(c => c.gameObject.transform.parent.gameObject == gameObject) : childs).ToList();
}
protected override void PostPipelineStageCallback(CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
{
var isNotRootCamera = ReferenceEquals(vcam.gameObject, gameObject).IsFalse();
//BUG Dirty state driven camera fix
if (isNotRootCamera)
{
_cinemachineCameraRoot
.AsOptional<CinemachineStateDrivenCamera>()
.IfPresent(sdc =>
{
if (ReferenceEquals(vcam, sdc.LiveChild)) return;
vcam.gameObject.SetActive(false);
});
}
//only apply on root camera
if ( isNotRootCamera ) return;
var priority = _childs.Where(c => c.isActiveAndEnabled)
.OrderByDescending(c => c.Priority).Select(c => c.Priority)
.FallbackIfEmpty(int.MinValue)
.First();
if(priority == int.MinValue)return;
vcam.Priority = priority;
}
public void Update()
{
if(AlwayUpdateChildList) UpdateChildren();
}
}