Deferent children by name SetActive/ true,false

I’m trying to work something with the polygon assets I have, there are a number of gameobjects that are under the prefab that I want to set on and off base on the armor config equipped by their name. I have an enum on the armor config and a component that takes in the transformation that has the game objects.
Armor config

        [SerializeField] Armor equippedPrefab = null;
        [SerializeField] GearMade gearMade = GearMade.SetBase;

        [SerializeField]
        Modifier[] additiveModifiers;
        [SerializeField]
        Modifier[] percentageModifiers;
        
        const string armorName = "Armor";

        [System.Serializable]
        struct Modifier
        {
            public Stat stat;
            public float value;
        }

the BodyStuff script

        [SerializeField] Transform hipGear = null;
       private void AttachArmor()
        {
            foreach (GameObject child in hipGear)
            {
                if (currentArmorConfig.GetGear() == GearMade.SetBase)
                {
                   child.Find("SetBase").SetActive(true);
                }
            }

        }

I stopped here, getting an error on (child.Find), I still don’t know how to fully use foreach or if it’s not to be used that way. I would use the same method for the weapon prefab from the course, but the gameoject in this asset has a root transform built-in, so spawning it causes it to not work. I’ve tested turning the object on and off from the inspector and the asset still works fine, now I’m just trying to do so from the script base on the armor config’s enum.

I ran into this very issue when I made Beneath using Modular Fantasy Heroes. The trouble is that transform.Find() doesn’t work on inactivated children…

Here’s a quick and dirty locator replacement for Find

GameObject FindItem(transform parent, string itemToFind)
{
    foreach(transform t in parent)
   {
       if(t.gameObject.name==itemToFind) return t.gameObject;
   }
   return null;
}

Ok so instead of using Find(), I will use this FindItem instead. So my code would look like this?

        private void AttachArmor()
        {
            foreach (Transform child in hipGear)
            {
                if (currentArmorConfig.GetGear() == GearMade.SetBase)
                {
                   FindItem(child, "SetBase").SetActive(true);
                }
            }
        }
       GameObject FindItem(Transform parent, string itemToFind)
        {
            foreach (Transform t in parent)
            {
                if (t.gameObject.name == itemToFind) return t.gameObject;
            }
            return null;
        }

I tried some things but im getting a NullReferenceException on the FindItem(child, “SetBase”).SetActive(true); line, thinking it’s me trying to setactive the transform instead of the object?

It would appear that it’s not finding an object named “SetBase” in the gear that matches.
I think I need to know more about the structure of the system you’re using. I’m familiar with InfinityPBR’s Humans and Synty’s Modular Fantasy Heroes, neither of which has gameobjects named SetBase… Can you show a screenshot of the models on the character expanded? (I’m not as interested in the skeleton objects as the gameObjects we’re turning on and off to define a character).

I was going to change the name of the object to SetBase but I used its original name.

        private void AttachArmor()
        {
            foreach (Transform child in hipGear)
            {
                if (currentArmorConfig.GetGear() == GearMade.SetBase)
                {
                   FindItem(child, "Chr_Hips_Male_00").SetActive(false);
                }
            }
        }
        GameObject FindItem(Transform parent, string itemToFind)
        {
            foreach (Transform t in parent)
            {
                if (t.gameObject.name == itemToFind) return t.gameObject;
            }
            return null;
        }

the goal was to get the child of the “Male Hip 10” , putting it in

[SerializeField] Transform hipGear = null;

then get the other gameoject by their name.


I want to Setactive on and off base on the equipped item, because of the objects Root Bone i cant spawn it like the weapon(doesn’t get the RootBone).

I set the gameoject on and off from the inspector while the game was in play, and the asset still works, with no problems. But passing in the gameoject name i still get a null reference.

Ok, so you’re using the Modular Fantasy Heroes set. I happen to have a little experience with that set.

There are actually a couple of things you need to deal with when activating/deactivating items in this set. I strongly recommend taking a good look at the Random Character Generator for a start in customizing this set.

Here’s an overview of what I did:

First, my script gathers every item in the set by category and stores it in a Dictionary. Unfortunately, there’s a LOT of boilerplate work to make this happen in an organized way. In my case, I hard coded an array with all of the categories. I used this array to drive the gathering script which stores a List of GameObjects for each category.

Dictionary<string, List<GameObject> catalog;
Each string represents the broader categories Male_00_Head, etc.

Then every GameObject in the dictionary is SetActive(false);

To turn on any specific object, you need the Category and the index
This means that your Chr_Hips_Male_00 is referenced by:
catalog["Male_10_Hips"][0];

I then created variables to represent a default character… Because in my game, you can choose either Male or Female, this means that I had to make a function for each category, here’s an example:

void ActivateHead(int index)
{
    DeactivateParts(gender==male?"Female_00_Head":"Male_00_Head");
    ActivatePart(gender==male?"Male_00_Head":"Female_00_Head", index);
}

void ActivatePart(string category, int index)
{
    DeactivateParts(category);
    categories[category][index].SetActive(true);
}

void DeactivateParts(string category)
{
     foreach(GameObject go in categories[category]) //categories[category] is a List<GameObject>
    {
         go.SetActive(false);
    }
}

Each of the other body parts has similar setups, with every category being covered.

Now for the juice: (and I’m hoping you’re using the RPG Inventory course)
I made fields in the EquipableItem.cs for the items to activate (category, int) and the categories to deactivate. (Example: If you’re using a Helmet, you probably want to deactivate the hair)

Then I subscribe to the OnEquipmentChanged event.

  1. Reset the character to the base elements.
  2. Iterate over the items in Equipment.cs, activating the items in each EquipableItem.

This sounds complex, and I won’t lie to you, it is… Hold your breath… my CharacterGenerator script (everything you see here + customizing the colors also set in Equipment.cs) weighs in at 807 lines, and that’s after I optimized it three times).

If you want to see the complete (unfortunately, not commented) script, I have all the code for my game Beneath on Github. Here’s the link to CharacterGenerator.cs

O.O I have some work to do lol, I don’t plan on using all the parts in that detail but I will see what I can do lol.

So I took a look at the CharacterRandomizer script and notice something in the code, I got it to work doing this:

        private void AttachArmor()
        {
            if (currentArmorConfig.GetGear() == GearMade.SetBase)
            {
               GameObject part2 = hipGear.Find("Chr_Hips_Male_00").gameObject;
               part2.SetActive(true);
            }
    
        }


Next will be the buildlist and use it in place but that will definitely take some time studying your code and the asset’s lol.

The issue that will stall you is that you presumably have some other Chr_Hips_Male_xx active when you do this, so you have to find the current Hips and deactivate it.

Yes, that’s what I’m trying to do now lol, I think once I get this build list down it will help make it easier hopefully.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms