I Have number of objects within the scene that conform to the naming convention:
male_portrait_
Where n is the number of that piece of portrait geometry. When the player clicks on a collider around the portraits, I am activating the next portrait and deactivating the current.
Given that only one can be shown at a time, I've been deactivating all but the first and then in code I was using GameObject.Find("/male_portrait_"), but I was surprised to find that this did not find inactive objects.
I was wondering if there was a way of finding inactive objects?
NOTE: It occurs to me now that I could have turned the mesh renderer and toggle this state in code as the player clicks and still be able to find the objects as I tried to above.
NOTE: my solution was to fix my code so that the objects were all active and I then deactivated the ones that should be hidden.
Solution 1
I left everything active, discovered all the items programatically and turned off the ones I didn't need.
Solution 2
I could hide the mesh renderer in the editor and discover the objects as above.
The confusing thing for me is that within the editor I can drag an inactive object onto the member variable of another script, thereby linking that inactive instance to that script, but I cannot do the same programmatically.
The idea here is using either a non-ideal way of getting all rootGameObjects or Tagged objects, as a place where to begin finding. Specially on the first way, this should be slower than regular GameObject.Find, but it will go through inactive objects.
static public GameObject GameObjectHardFind (string str) {
GameObject result = null;
foreach ( GameObject root in GameObject.FindObjectsOfType(typeof(Transform)) ) {
if (root.transform.parent == null) { // means it's a root GO
result = GameObjectHardFind(root, str, 0);
if (result != null) break;
}
}
return result;
}
static public GameObject GameObjectHardFind (string str, string tag) {
GameObject result = null;
foreach ( GameObject parent in GameObject.FindGameObjectsWithTag(tag) ) {
result = GameObjectHardFind(parent, str, 0);
if (result != null) break;
}
return result;
}
static private GameObject GameObjectHardFind (GameObject item, string str, int index) {
if (index == 0 && item.name == str) return item;
if (index < item.transform.childCount) {
GameObject result = GameObjectHardFind(item.transform.GetChild(index).gameObject, str, 0);
if (result == null) {
return GameObjectHardFind(item, str, ++index);
} else {
return result;
}
}
return null;
}
Keep in mind this is compatible with Unity 4 (just tested it on beta 7) but should still be avoided and it is even more unnecessary, due to how U4 now handles active and inactive game objects.
If I get what your saying. You want to disable a object and enable the rest. use SetActiveRecursively if true it will enable the item/activate and that object children aswell. if false it will deactive the object and it's children.
If you want to only disable one part of the object use active.
Heres an example. C#
public GameObject currentlyenabled = GameObject.FindWithTag("enabled");
public GameObject currentlydisabled = GameObject.FindWithTag("disabled");
//After your collision script enter this
currentlyenabled.SetActiveRecursively(false);
currentlydisabled.SetActiveRecursibely(true);
JavaScript
var currentlyenabled = GameObject.FindWithTag ("enabled");
var currentlydisabled = GameObject.FindWithTag ("disabled");
//After your collision script enter this
currentlyenabled.SetActiveRecursively(false);
currentlydisabled.SetActiveRecursibely(true);
Using the tags keep it a bit tidy compared to having multiple game objects going on and off just tag the one enabled with "enabled" and all the ones that are disabled currently "disabled".
If your asking how you can find and turn something on/off that should work.
If your asking to find something inactive and access scripts from I am fairly sure you cannot do that, but what I would do in that case is turn that objects render off.
I am a bit stumped on what your asking.
Peace,
EDIT: Did you test it with the tag method that I posted before instead of just using Gameobject.Find ?
If that does not work another method would be to make a Gameobject variabled in which you then manually put what object it is into the inspector and then SetActiveRecursively it (this will work).
Example C#:
public GameObject male_portrait;
male_portrait.SetActiveRecursively(true);
Example Java:
var male_portrait : Gameobject;
male_portrait.SetActiveRecursively(true);
Can set up an array at the start with links to them all. Then you never need to run a Find while running, so no worries about inactive. That also puts all the naming stuff in one place.
public GameObject[] Portrait;
// maybe set size in the inspector and drag all in, or:
void initPortraits() {
Portrait = new GameObject[10];
string pBase = "male_portrait_";
for(int i-0;i<10;i++) {
Portrait *= GameObject.Find(pBase+i); // Ex: male_portrait_0*
Portrait*.active=false;* } } The regular code can now say things like: Portrait[curPort].active=false; curPort++; Portrait[curPort].active=true;
Okay. A little late but I hope my answer could be of service to those who’re still facing this apparently age-old conundrum.
My original problem when I countered this was I had an Event Trigger attached to a Text in the UI that catches pointer downs. So when you click on the Text, something happens. The problem is, the user might click the Text more than once, leading to a series of problems since the trigger is tied to an InvokeRepating() method. So to solve this, I have had to catch the pointer down event only once. My chosen solution was to disable the Text Game Object after being pressed and just activate it later again when I need it to be. The problem with this is, as you’ve guessed, we can’t find a disabled Game Object via its tag.
My solution? Find its parent and access it from there. This was the code the used:
I had the same problem with cameras which had to be inactive at the start and I wanted a decent way to retrieve them afterwards.
Basically what I did is make an empty (!active!) gameobject with a standard name for which I can search, then search for that gameobject and retrieve its components. So if it is an option to put all inactive objects you want to retrieve in a parent object, this might be a way to go.
void Start(){
GameObject cameras = GameObject.Find("Cameras");
cams = cameras.GetComponentsInChildren<Camera>(true);
front = FindCam("FrontCamera");
side = FindCam("SideCamera");
perspective = FindCam("Perspective");
…
---- FindCam just for being complete ----
private Camera FindCam(string name){
foreach(Camera c in cams){
if(c.name == name){
return c;
}
}
return null;
}
I use next trick. Create empty game object with name example “ContainerGUIPause” and put my inactive gameobject with name “guipausemenu” as child “ContainerGUIPause”.
And use code
GameObject.Find(“ContainerGUIPause”).transform.FindChild(“guipausemenu”);
If you use Unity 4.5x after version
you can use this code, In my case this is helpful to me,
if ‘activeInHierarchy’ has compile error, change to ‘activeSelf’;