I found a weird bug in a game I'm working on and I don't know how to fix it.

I’m an amateur Unity developer, with less than a year of experience. I’m working on a game in Unity, and at the moment it’s not much. There are a set of three doors you can open or close by clicking them. The doors are in an array, and I can detect which door is being clicked by taking the name of the object and using a foreach loop to figure out where in the array that object is. It will use that object’s index as a tag to figure out which door to open. I programmed it so that the function will automatically default to 0 if the foreach loop fails. I was under the impression that it never fails, but for whatever reason it does. Sometimes, but only if you’re moving around, the function will fail and default to 0, resulting in the program toggling the door with index 0 instead of the door that was actually clicked on. Does anyone know why this is happening?

Here’s the full script. Let me know if you need more information.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectInteraction1 : MonoBehaviour
{
    //Note to self: Always use GameObject arrays from now on. This is a game changer. Literally.

    public GameObject[] Doors;
    public GameObject[] DoorHandles;

    //This array of booleans determines two things about a door. Whether or not it's open, and whether or not it's
    //locked.

    public bool[,] doorStates = { { true, true, true }, { true, true, true } };

    public int value;

    public float animationTimer = 2;

    public LayerMask doorMask;

    private void Update()
    {
        Ray ray = new Ray(transform.position, transform.TransformDirection(Vector3.forward));

        Physics.Raycast(ray, out RaycastHit hitData);

        //This single if statement will basically determine the entire game's interaction system. Simply pressing M1
        //will activate every single line of code below.

        if (Input.GetMouseButtonDown(0))
        {
            //This really weird bug keeps occuring and I have no idea how to fix it. Sometimes, for whatever reason,
            //this value will just reset to 0 whenever you click on a door, resulting in the wrong door opening. It's
            //a really confusing bug, but it seems to only occur when the player is moving. Hopefully it doesn't get
            //in the way of anyone's playthrough. It might give them a spook.

            value = Value(hitData.collider.name);

            if (Physics.Raycast(ray, 2.5f, doorMask) && animationTimer <= 0)
            {
                if (doorStates[1, value])
                {
                    if (doorStates[0, value])
                    {
                        Doors[value].GetComponent<Animator>().Play("DoorOpen");
                        DoorHandles[value].GetComponent<Animator>().Play("Handle");
                        doorStates[0, value] = false;
                    }
                    else if (!doorStates[0, value])
                    {
                        Doors[value].GetComponent<Animator>().Play("DoorClose");
                        doorStates[0, value] = true;
                    }

                    animationTimer = 2;
                }
            }
        }

        animationTimer -= Time.deltaTime;
    }

    int Value(string objectName)
    {
        int value = 0;

        foreach (GameObject i in Doors)
        {
            if (i.name == objectName)
            {
                return value;
            }

            value++;
        }

        return 0;
    }
}
  1. Do not use “value” for variable names. It is a reserved identifier used in properties. “Value” is also not recommended, because it is similar.
  2. It is a much better idea to write a “DoorData” component that will store door index rather than trying to find door index by its name. Attach DoorData to all openable doors, and then you could even gather them all up using “GetComponentsInChildren” instead of assigning them manually. Likewise that component should drive its own animator and should store its own open/closed state.
1 Like

It seems to have worked. Thanks!

I did find out why it was happening, though. Turns out it wasn’t that the foreach loop was failing. It seems that the raycast itself wasn’t recognizing the object it was hitting as a valid object. Because of this, the Value function was receiving an empty name string, and therefore defaulting to 0 as I programmed it to do. I don’t know how to fix the raycast issue, but at least the door bug is gone.

Your component could have an OnMousDown() method that responds directly to being clicked on. Making it self contained.

In addition a static list could allow for multiple doors to be triggered by one doors click e.g. level unlock button.