Physics.Raycast False until Camera switch

Hello!

I’m currently developing a game, and ran into a confusing bug. When I play the game, the following Physics.Raycast calculation comes up false, until I run the switch camera function on the CameraController script. Wondering if anyone can spot what might be causing the bug.

using UnityEngine;
using UnityEngine.UI;

public class CameraController : MonoBehaviour
{
    private Camera mainCam;
    Camera cam;
    public Camera activeCam;
    public static CameraController instance;
    [SerializeField] private GameObject[] cameras = new GameObject[5];
    CameraMovement moveCam;
    private void Awake()
    {
        if (instance != null)
        {
            
            Debug.Log("two camera controllers");
        }
        instance = this;

        moveCam = activeCam.GetComponent<CameraMovement>();
        moveCam.enabled = true;
        activeCam = cameras[0].GetComponent<Camera>();
        activeCam.enabled = true;
        activeCam.tag = "maincamera";
        mainCam = activeCam;
    }

    // Use this for initialization
    void Start()
    {
        
        
    }

    // Update is called once per frame

void LateUpdate()
    {

        if (Input.GetKeyDown("1") && cameras[0] != null)
        {
            switchCameras(0);
        }
        else if (Input.GetKeyDown("2") && cameras[1] != null)
        {
            switchCameras(1);
        }
        else if (Input.GetKeyDown("3") && cameras[2] != null)
        {
            switchCameras(2);
        }
        else if (Input.GetKeyDown("4") && cameras[3] != null)
        {
            switchCameras(3);
        }
        else if (Input.GetKeyDown("5") && cameras[4] != null)
        {
            switchCameras(4);
        }
    }

    private void switchCameras(int keyNum)
    {
        for (int i = 0; i < cameras.Length; i++)
        {
            if (cameras *!= null && keyNum != i)*

{
cam = cameras*.GetComponent();*
moveCam = cam.GetComponent();

cam.enabled = false;
moveCam.enabled = false;
}
else
{
activeCam = cameras*.GetComponent();*
moveCam = activeCam.GetComponent();

activeCam.enabled = true;
moveCam.enabled = true;
}
}
}
}
And on a separate object in the scene.

void Update () {

if (Input.anyKey)
{
ray = camController.activeCam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
//false until CameraController performs switchCamera();
{
rayHit = hit.collider.gameObject;
//do stuff

}
}
}

Hi @Skaster87 ,

You are hitting a typical racing condition, with the only difference that in this case the race is kinda obvious: Update is executed before LateUpdate, so basically camController.activeCam is never using the one you are switching to when you touch a switching key, so the first thing to do is to ensure that both are executed in the same cycle, hence both in Update or both in LateUpdate.

But the above is not enough: you also need to make sure that the switching script is executed before the one that does the raycast, and to do so you have to set the script priority, otherwise it’ll not be guaranteed. To do so, please refer to this documentation page: Unity - Manual: Script Execution Order settings

An additional word of advice about code optimization: you do a GetComponent every single time you switch. You should simply declare the cameras field of type Camera.

You also seem to have another issue: reading the code I notice the line moveCam = activeCam.GetComponent(); and that tells me that you have this script on each of the cameras. You can avoid this altogether by attaching the CameraController script to an empty GameObject called CameraController, so you won’t need to enable/disable that instance of the script that, by the way, could cause more racing conditions.