Search Unity

how to enable a gameobject?

Discussion in 'Editor & General Support' started by MrDude, Apr 24, 2008.

  1. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    This is the weirdest behavior this...

    I followed the instructions for creating a splash screen and then added a camera to the cube to make sure the camera always fits the cube onscreen.

    When trying to turn off this camera and turn on the main camera, I call
    Code (csharp):
    1.  
    2. camera.active = false;
    3.  
    This only prints a message saying that this method is depreciated and I should disable the gameobject. Okay...
    Code (csharp):
    1.  
    2. gameObject.active = false;
    3.  
    Fine, now the gameObject becomes grayed out in the inspector, calling "GameObject.Find("PC").active for a print gives me a NullReferenceException error... but the camera is still active.

    Upon closer inspection in the inspector, I find that the game object is no longer active, but each of it's components still are...

    Setting active = true on the other camera makes both camera draw.
    I have to manually set one camera to active and the other to false. Mind you, I have to call the camera directly, even though Unity tells me that calling active on components is depreciated...

    Have a look at this:
    Code (csharp):
    1.  
    2.     GameObject.Find("SplashCamera").active = true;
    3.     GameObject.Find("PC").active = false;  
    4.     GameObject.Find("Main Camera").active = false;
    5.  
    Main Camera is a child object of the prefab named PC. The above code works perfectly but by adding this line at the bottom:
    Code (csharp):
    1.  
    2.     print(GameObject.Find("PC").active);   
    3.  
    I get a nullReferenceException.

    So, in summary,
    1. If I can't access a prefab after it was disabled, how to re-enable it again?
    2. Why does my prefab get disabled but it's components remain active?
    3. What is the correct way of disabling a prefab / camera?
    4. What is the correct way of switching from camera to camera?

    Thanks for your help :)
     
  2. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    There are two concepts of "active" here:

    1) A GameObject has an active flag, which will turn off the GameObject. The components will retain their state, so when you reactive the GameObject a previously disabled Component won't be renabled, but even a checked component on an inactive GameObject will do nothing (its Update() functions won't be firing, etc).

    2) A Component has an enabled flag. This will turn off just that component. So in your first line you could do camera.enabled = false;

    GameObject.Find() won't return any inactive GameObjects. If you want to find a disabled one you will need to have stored a reference to it somewhere already (or via the inspector).

    "Switching" from one camera to another isn't a concept embedded in Unity. All active cameras will render all of the time. This is actually a very useful thing--you can do thing likes render a 3D GUI on top of your main camera, or render smaller cameras (think the little 3D faces of active units in an RTS game).

    If you have multiple "main" cameras, and want to switch between them, you simply disable all of the cameras but the one you want to display.
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    You CAN access it, just not through GO.Find. It's bad practice to constantly use Find anyway - very slow. Instead, store a reference to it like this:
    Code (csharp):
    1.  
    2. var theObject : GameObject;
    3. function Start() {
    4. theObject = GameObject.Find("The Object");
    5. }
    6. function Update() {
    7. //do stuff!
    8. theObject.active = false;
    9. theObject.camera.enabled=false;
    10. }
    11.  
    First off, check your terminology and it will probably help avoid confusion: a "prefab" is usually something in the project folder, whereas it's generally referred to as simply a "GameObject" when in the scene; components are "enabled" or not; GameObjects are "active" or not. This is probably your original problem too: a camera has .enabled, not .active.

    Second, even though the components appear enabled, if the GameObject is inactive, they will NOT do anything and are effectively disabled.
    Code (csharp):
    1.  
    2. //disable object
    3. theCameraObject.active=false;
    4. //disable its camera
    5. theCameraObject.camera.enabled=false;
    6.  
    You seem to be on the right track, enabling one and disabling the other. One cautionary note: be sure that the old one is disabled, and that the new camera is not simply rendering on top of it! This will easily halve your framerate. (Speaking from experience....)

    Edit: I found what may be a second possible problem, depending on how the components are being set up. "camera.enabled" will refer to the camera attached to the object the script is on, which i suspect will not be anything. To get the main camera, use Camera.main.enabled. If you're using two camera objects, that won't be very helpful either, so find the camera objects by name or by click-and-drag reference and use the first example to enabled/disable them.
     
  4. MrDude

    MrDude

    Joined:
    Sep 21, 2006
    Posts:
    2,569
    thanks for that

    Regarding the find operations, I just used that to troubleshoot my code. I like storing everything in a reference. So much so that after I am happy with an object's placement in the world and it's behavior etc, I create a prefab for it and load it at runtime. I have a file named Game which is responsible for loading the main elements of the game (levels) and each element is in charge of loading it's own stuff (buildings) recursively (buildings load furniture). Everything is available via code. Just my way of doing things... s'all.

    But, yeah, seems my problem arose from enabled and active. Thanks for clearing that up for me. My game was around 98% done last night but I was doing my main menu via GUI calls. The interface looked brilliant but the background never quite seemed to fit properly so I decided to do my main menu in a level of it's own and only load the complete level once the user selects play. Problem is, I wanted to retain some variables from the main screen so by doing the DontDestroyOnLoad thingy caused some of my scripts to cause problems with the loaded level's scripts. I tried to find a way around the conflicts and ended up with the game being around 90% finished after 6 hours of work... negative progress!

    I finally managed to solve all the conflicts and get everything working hunky dory but being aware of enabled and active sure would have saved me a lot of hair pulling...

    Jeez, sometimes my coding skills leave me in awe of my stupidity. I am some kind of savant. Give me the hard stuff but don't even bother asking me the simple stuff. I can send you to the moon using only a wheelbarrow and two tea bags but I can't figure out how to use the hand pump.

    Anyways, thanks for the help, Hopefully I can retain some hair now.