Disable GameObjects with a certain name?

Hi!
I’m working on my game’s save function, and this code is part of it. What I want it to do is turn on certain GameObjects when certain floats equal one. Here’s the code…

var chapter1 : float;
var chapter2 : float;
var chapter3 : float;
var chapter4 : float;
var chapter5 : float;
var chapter6 : float;
var chapter7 : float;
var chapter8p1 : float;
var chapter8p2 : float;
var playedOnce : float;
var playedTwice : float;


function Start () {
   
}

function Update () {
   
    if (Application.loadedLevel == 4)
    {
        chapter1 = 1;
        chapter2 = 0;
        chapter3 = 0;
        chapter4 = 0;
        chapter5 = 0;
        chapter6 = 0;
        chapter7 = 0;
        chapter8p1 = 0;
        chapter8p2 = 0;

    }

    if (Application.loadedLevel == 5)
    {
        chapter1 = 0;
        chapter2 = 1;
        chapter3 = 0;
        chapter4 = 0;
        chapter5 = 0;
        chapter6 = 0;
        chapter7 = 0;
        chapter8p1 = 0;
        chapter8p2 = 0;

    }

    if (Application.loadedLevel == 8)
    {
        chapter1 = 0;
        chapter2 = 0;
        chapter3 = 1;
        chapter4 = 0;
        chapter5 = 0;
        chapter6 = 0;
        chapter7 = 0;
        chapter8p1 = 0;
        chapter8p2 = 0;

    }

    if(chapter1 == 1)
    {
        GameObject.Find("Chapter 1").SetActive(true);
    }

    if(chapter1 == 0)
    {
        GameObject.Find("Chapter 1").SetActive(false);
    }

    if(chapter2 == 1)
    {
        GameObject.Find("Chapter 2").SetActive(true);
    }

    if(chapter2 == 0)
    {
        GameObject.Find("Chapter 2").SetActive(false);
    }

    if(chapter3 == 1)
    {
        GameObject.Find("Chapter 3").SetActive(true);
    }

    if(chapter3 == 0)
    {
        GameObject.Find("Chapter 3").SetActive(false);
    }

    if(chapter4 == 1)
    {
        GameObject.Find("Chapter 4").SetActive(true);
    }

    if(chapter4 == 0)
    {
        GameObject.Find("Chapter 4").SetActive(false);
    }

    if(chapter5 == 1)
    {
        GameObject.Find("Chapter 5").SetActive(true);
    }

    if(chapter5 == 0)
    {
        GameObject.Find("Chapter 5").SetActive(false);
    }

    if(chapter6 == 1)
    {
        GameObject.Find("Chapter 6").SetActive(true);
    }

    if(chapter6 == 0)
    {
        GameObject.Find("Chapter 6").SetActive(false);
    }

    if(chapter7 == 1)
    {
        GameObject.Find("Chapter 7").SetActive(true);
    }

    if(chapter7 == 0)
    {
        GameObject.Find("Chapter 7").SetActive(false);
    }

    if(chapter8p1 == 1)
    {
        GameObject.Find("Chapter 8 - 1").SetActive(true);
    }

    if(chapter8p1 == 0)
    {
        GameObject.Find("Chapter 8 - 1").SetActive(false);
    }

    if(chapter8p2 == 1)
    {
        GameObject.Find("Chapter 8 - 2").SetActive(true);
    }

    if(chapter8p2 == 0)
    {
        GameObject.Find("Chapter 8 - 2").SetActive(false);
    }

    if(playedOnce == 1)
    {
        GameObject.Find("Played Once").SetActive(true);
    }

    if(playedOnce == 0)
    {
       GameObject.Find("Played Once").SetActive(false);
    }

    if(playedTwice == 1)
    {
        GameObject.Find("Played Twice").SetActive(true);
    }

    if(playedTwice == 0)
    {
        GameObject.Find("Played Twice").SetActive(false);
    }
}

function Awake () {
    DontDestroyOnLoad (transform.gameObject);
}

My only issue is that because of the final Awake function, I can’t put the GameObjects I’m trying to turn on and off in the code as variables. How could I make this code work without setting any of the GameObjects as variables, and instead make the code search the scene for an Object named that? I’m really bad at explaining this kind of stuff, so if you have any questions, feel free to ask!

It seems like that’s exactly what you’re doing with GameObject.Find, isn’t it? I mean, you SHOULDn’t be, but as far as I can tell you are.

I’m seeing a number of coding issues here, in addition to a major conceptual problem with this as a part of a game saving algorithm. So I’ll tell you how to fix those issues one at a time, because these are bad programming habits that you should fix, and it’s easier to teach new concepts if modifying code for which you know the purpose… and then I’m going to tell you to scrap it and do something along the lines of this fantastic tutorial instead. So basically: read this whole comment; if you want to follow along and make changes to your script to check your own understanding that’s good; but at the end, the recommendation will be to scrap it anyway and follow that tutorial.

First, you’re using floats for literally everything. This is not only wasteful, it’s begging for trouble sooner or later. There’s not a single thing here that should be a float. As you have them there, you’re using them as bools - replace all your “float” with “bool”, and use true instead of 1 and false instead of 0. Boom, the code has been made more reliable.

But wait there’s more! (use an int)
Your chapters, as far as I can tell, are exclusive from each other - only one will be active at a given time, right? This means you can put all this data in a single “int”-type variable instead, representing “which chapter should be active?”.

int chapterActive = -1;
function Update() {
if (Application.loadedLevel == 4) {
chapterActive = 1;
}
//etc

if (chapterActive == 1)
{

Saved you about 40 lines of tedious code right there.

But wait there’s more! (pass bools as parameters)
Your pairs of if statements (e.g. lines 62 & 67) are unnecessary. Anything in the parentheses of an if statement boils down to a bool, and .SetActive takes a bool as a parameter:

GameObject.Find("Chapter 1").SetActive(chapterActive == 1);

Lines 62 through 170 can become, by my count, 11 lines of code, and those 11 lines are much easier to read. For example, if you’d typo’d one of those names, how annoying would that have been to debug?

But wait there’s more! (GameObject.Find)
I hinted at this earlier, but there is never a good reason to use GameObject.Find. In this case, while I can’t say for sure without more knowledge about your goals here, but I think what you want here is to have a singleton, which contains an array of drag-and-drop-able public GameObject references; the singleton will be in the scene that gets loaded, that way this script (even though it started its life in another scene) will still be able to access them. Since this one requires more information, I’ll leave that alone for now, but feel free to ask for more info about this one; suffice it to say that this would let you reduce the 11 repetitive lines above with, like, 3 lines, and better yet, you won’t have to alter your code if you add more chapters later.

But wait there’s more! (Javascript)
Alright, so here’s the big one: Don’t use Javascript. It’s marketed as being the good language for beginning coders, but that’s just not the case. I’ve got a long article that explains exactly how and why. C# is objectively a better language to use in Unity, especially for beginners… and JavaScript is a marketing department lie.

If you’re deep into this project and don’t want to rewrite all your existing code, I understand that, but you’ll be much better off if you do (and I bet it won’t take as long as you’d be afraid it will to convert).

1 Like