- Home /
SetActive() not working on child objects
I'm trying to enable/disable weapon models on my player model when he picks up a new weapon. This is the code that doesn't seem to work.
void exchangeWeapon(int newWeapon){
if (newWeapon == 1) {
Debug.Log ("Changing weapons to "+m4a1_equip.gameObject.name);
ak47_equip.gameObject.SetActive(false);
m4a1_equip.gameObject.SetActive(true);
ak47_loot.gameObject.SetActive(true);
m4a1_loot.gameObject.SetActive(false);
}
if (newWeapon == 2) {
Debug.Log ("Changing weapons to "+ak47_equip.gameObject.name);
ak47_equip.gameObject.SetActive(true);
m4a1_equip.gameObject.SetActive(false);
ak47_loot.gameObject.SetActive(false);
m4a1_loot.gameObject.SetActive(true);
}
if (newWeapon == 0) {
ak47_equip.gameObject.SetActive(false);
m4a1_equip.gameObject.SetActive(false);
}
}
There are no errors when this code is executed. I'm disabling the model on the ground and enabling the model in the player's hands. The Debug.Logs execute properly, so I know the code is being run and the gameObject is being read correctly. The model on the ground disappears/reappears properly. The gun model in the player's hands doesn't appear, though.
Without errors, I'm a bit lost as to what I've done wrong.
Answer by Owen-Reynolds · Dec 23, 2014 at 06:53 PM
In general, setActive on child objects works fine. I toggle them on/off, mostly like you're doing, all the time.
Pause the game and check the Inspector. Focus on one gun (sometimes they both don't work, but for different reasons.)
Look at the "held" nug. Is it set active? If so, it will still be inactive if any parents are -- maybe an empty parent is inactive. Click everything to make sure it can be visible. Unchild it (if needed) and double-click to it. Maybe it's visible but 50 meters above you by mistake.
If it's not active, make the variable public (stop and run it again) and click to find it. Maybe m4a1_equip is also set to the ground object. Check the loot's are set up correctly (and not aimed at the held guns by mistake.)
If it's all hooked-up correctly and still not being made active, maybe code elsewhere is messing it up. Comment out a bunch of lines, put the SetActive's in Start if needed. Check for other SetActives.
It seems that I'm having trouble finding the child gameObjects I'm looking for. I see the error this time. ak47_equip and m4a1_equip are deeply nested child objects of the player character (They're childed to the right hand).
void Start () {
ak47_loot = GameObject.Find ("ak47");
m4a1_loot = GameObject.Find ("$$anonymous$$4A1 Sopmod");
ak47_equip = transform.FindDeepChild ("ak47_equip").gameObject;
m4a1_equip = transform.FindDeepChild ("$$anonymous$$4A1_equip").gameObject;
...
}
This is the code I'm using to find those game objects. I've got a class called FindDeepChild in my project.
public static class TransformDeepChildExtension
{
//Breadth-first search
public static Transform FindDeepChild(this Transform aParent, string aName)
{
var result = aParent.Find(aName);
if (result != null)
return result;
foreach(Transform child in aParent)
{
result = child.FindDeepChild(aName);
if (result != null)
return result;
}
return null;
}
It's been fairly confusing trying to figure out how to find and activate those guns. I feel like it's something simple or maybe I'm just doing it wrong.
Are you finding the wrong ak47_equip? If you weren't finding anything, I think SetActive would error-out.
FindDeepChild seems fine(*). But you can look directly: transform.Find("body/rArm/hand/gun1");
. Or you can make them public vars and drag them in pre-game. You might find the problem that way, them convert back to DeepChild after.
(*)It says breath-first, but it's really depth-first. Just saying.
There's only one ak47_equip object in the scene. I'll see if I can look directly at it. I didn't know that was possible. That would alleviate a lot of headache.
I've got the code finding the objects, but the objects on the character don't actually enable. I know the code reaches the point where they SHOULD be enabled
void exchangeWeapon(int newWeapon){
if (newWeapon == 1) {
Debug.Log ("Changing weapons to "+m4a1_equip.gameObject.name);
ak47_equip.gameObject.SetActive(false);
m4a1_equip.gameObject.SetActive(true);
ak47_loot.gameObject.SetActive(true);
m4a1_loot.gameObject.SetActive(false);
}
if (newWeapon == 2) {
Debug.Log ("Changing weapons to "+ak47_equip.gameObject.name);
ak47_equip.gameObject.SetActive(true);
m4a1_equip.gameObject.SetActive(false);
ak47_loot.gameObject.SetActive(false);
m4a1_loot.gameObject.SetActive(true);
}
if (newWeapon == 0) {
ak47_equip.gameObject.SetActive(false);
m4a1_equip.gameObject.SetActive(false);
}
}
The Debug.Log lines execute, the _loot objects appear/disappear properly, but the _equip weapons still don't appear. There are no errors in the console, either. Any suggestions?
I finally got it. I moved the Find lines to find the _equip weapons to the exchangeWeapon method and it works now. Not sure what that's all about, but it's working. I might have to find another $$anonymous$$4 model, though... when I equip this one, my frames go to absolute hell. But, that's another issue :)
Answer by wieryeveska · Nov 29, 2016 at 08:17 AM
In my case... check if scale, width, height... etc of any parent or parent's parent is not 0 while playing check any other condition of rect transform is properly set while playing
If any one of them is not properly set then it wouldn't work properly too. Parent object must be set enough with the settings in order to process whats in the children