0
\$\begingroup\$

I would like to be able to switch between a variable number of cameras in my scene.

The common approach requires toggling the active camera's 'enabled' property to true and setting the others to false. This is an issue when iterating through the 'Camera.allCameras' array as it doesn't contain the inactive cameras.

I therefore thought that I could get around this by creating a local array of cameras during initialisation and then iterate through that:

using UnityEngine;
using System.Collections;

public class CameraSwitcher : MonoBehaviour 
{
    int cameraIndex;
    Camera[] cameras;

    void Start() 
    {
        cameraIndex = 0;

        // Assumes that all cameras are initially active in the scene
        cameras = new Camera[Camera.allCameras.Length];

        int i = 0;

        while (Camera.allCameras.Length > 0)
        {
            cameras[i++] = Camera.allCameras[0];
            Camera.allCameras[0].enabled = false;
        }

        // Does not get recognised as main camera when activated
        cameras[cameraIndex].enabled = true;
    }

    void HandleInput()
    {
        if (Input.GetKeyDown(KeyCode.F1))
        {
            cameras[cameraIndex].enabled = false;

            cameraIndex = ++cameraIndex == cameras.Length ? 0: cameraIndex;

            cameras[cameraIndex].enabled = true;
        }
    }

    void Update() 
    {
        HandleInput();
    }
}

The two problems with this approach are:

1) I assume that all cameras in the scene are initially active

2) Setting the camera's 'isenabled' to true in the local camera array does not set the main camera and it therefore remains 'null'

How can I store all the cameras in the scene, regardless of their active status, iterate through the array and set the main camera based on the array index?

\$\endgroup\$
2
\$\begingroup\$

I think you are only forgot to set the tag MainCamera. Accordingly to the documentation Camera.main will reference the first enabled camera with MainCamera tag. So this should fix the problem:

cameras[cameraIndex].tag = "MainCamera";
cameras[cameraIndex].enabled = true;

Edit:

There are several ways of finding objects (or Component attached to object) in a given scene. The simplest (and slowest ) way is using FindObjectsOfType.

Generally it's better to avoid find methods, or eventually use them only in initialization (Awake or Start). Because of your cameras are all already present in the scene (aren't they?), you can eventually serialize an array of references to Cameras in your CameraSwitch component, and assign them from the inspector.

public class CameraSwitcher : MonoBehaviour 
{
    int cameraIndex;
    [SerializeField]
    private Camera[] cameras;
\$\endgroup\$
0
\$\begingroup\$

I had same issue with this; even tho I changed the new active camera's tag to MainCamera, you have to first disable the first active camera's tag just @Kelly Thomas said.

\$\endgroup\$
  • 1
    \$\begingroup\$ This looks like it's restating information that's already present in the post above from five years ago. Do you have any new tips or advice to add? \$\endgroup\$ – DMGregory Jan 19 at 14:54
  • \$\begingroup\$ Thanks for your reply, Warren. I'll invite you to please familiarize yourself with our Code of Conduct. Please treat other users on this site in a friendly & welcoming manner. Rude messages will be deleted and may result in restrictions to your account. \$\endgroup\$ – DMGregory Feb 2 at 20:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.