charlieyin
charlieyin

Reputation: 411

How do I get a reference to a randomly generated child Gameobject's script in Unity?

I am making a shop in a game. I have 3 pedestals in the shop, and each time you start the game, the shop will randomly generate three different items from an item pool that will be placed on each of the pedestals. These items will be child GameObjects on each pedestal.

I am trying to reference the child's script, so that I can call a method from it that would apply the item's effects to the player. However, I am unsure on how to reference this script component. I can successfully reference the child GameObject using transform.GetChild(0).gameObject but I am unsure on how to access the script component of the child since each child will have its own unique script with its own unique effects.

Here is my parent GameObject's script:

    public GameObject item;

    void Start()
    {
        item = transform.GetChild(0).gameObject;
    }   
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            BuyItem();
        }
    }  
    void BuyItem()
    {
        Destroy(item);
        // call "ApplyItem()" from child gameobject's script
    
    }

Child GameObject script:

public void ApplyItem()
{
    player.fireRate -= 0.1f;
    player.bulletSpeed += 50;
}

Upvotes: 1

Views: 140

Answers (3)

Tibère B.
Tibère B.

Reputation: 1226

I would consider using an interface, I try to avoid using abstract classes in favor of them.

I belieive it's also generally a good practice to have interfaces between interacting components.

(Since Unity 5, you can get interfaces through the GetComponent function)

Here's the slightly modified pedestal script :

public class Pedestal : MonoBehaviour
{
    public IShopItem Item;

    private GameObject _itemGameObject;
    private void Start()
    {
        _itemGameObject = transform.GetChild(0).gameObject;
        Item = _itemGameObject.GetComponent<IShopItem>();
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            BuyItem();
        }
    }
    private void BuyItem()
    {
        Destroy(_itemGameObject);
        Item.ApplyItem();
    }
}

IShopItem interface :

public interface IShopItem
{
    public void ApplyItem();
}

And finally a script to attach to an item :

public class SwordOfDoom : MonoBehaviour, IShopItem
{
    public void ApplyItem()
    {
        // Do thingy with player
    }
}

Upvotes: 1

Shrimp
Shrimp

Reputation: 612

So you get GameObject via this:

GameObject item = transform.GetChild(0).gameObject;

Similarily, you can get any other component with GetComponent

YourScriptType itemScript = transform.GetChild(0).gameObject.GetComponent<YourScriptType>();

and then call

itemScript.ApplyItem();

Edit: ok, so your scripts are different, you need to make it accessible via OOP features like abstract classes or interfaces. For example create an abstract script:

public abstract class AbstractCustomObject : MonoBehaviour{}

and then create your custom object classes deriving from that:

public class CustomObject1 : AbstractCustomObject{}
public class CustomObject2 : AbstractCustomObject{}
public class CustomObject3 : AbstractCustomObject{}

then in script call

transform.GetChild(0).gameObject.GetComponent<AbstractCustomObject>();

Keep in mind, that this solution is probably not what as there should be better ways to design your systems (having separate script per object is usually not the way to go).

Upvotes: 0

Nishchhal Bakshi
Nishchhal Bakshi

Reputation: 242

You can also use GetComponentInChildren() to directly get access to the script. This will return you the first element of "YourScriptName" from the children and later you can call GetComponentInChildren().ApplyItem()

Upvotes: 0

Related Questions