# Enemies and item drops issue

Disclaimer: I'm relatively new to developing games so bear with me.

In my scene I have enemies and when they die, they drop items. No matter which item is dropped, the same prefab (the physical representation of the dropped item) is instantiated. That physical orb on the ground may represent different items. It could be a pile of coins, a sword, etc. Depending on which item is dropped, I want its name to appear in a UI label attached to the top of the item. Basic ARPG stuff really. The problem I'm running into is that I can't seem to get the references right.

DisplayItemNameLabel is a script which is attached to each item when it is dropped. I did it this way so each item can be in charge of its own UI label.

ItemDrops is attached to each enemy. SpawnItem(Item item) is a function which is called when the enemy dies.

The last relevant Monobehaviour script is the ItemData script which is attached to an Item Manager game object which is there from the beginning and persists forever. This class just defines the different items that are possible in the game.

So basically the structure is that when an enemy dies, if the random number generated is within some range, then some item will drop.

If (randomNumber < 0.5)
{
SpawnItem(itemData.coin);
}


where SpawnItem(Item item) is something like...

private void SpawnItem(Item item)
{
itemDropped = true;
nameOfDroppedItem = item.itemName;

Instantiate(itemPrefab, transform.position - offset, Quaternion.identity);
}


Again, this is attached to each enemy.

In the DisplayItemLabel script then, I would like to set itemNameText.text to that nameOfDroppedItem. But the DisplayItemLabel script is attached to each item. I don't think I can make each item a child of each enemy because enemies are destroyed when they are killed so the scripts would be destroyed. I also can't use GameObject.FindGameObjectWithTag("Enemy").GetComponent<ItemDrops>(); because it wouldn't always grab the enemy I want. I thought maybe I could set the text in SpawnItem but it would have to reference the correct item, so I couldn't use GameObject.FindGameObjectWithTag...

What should I do?

You need to have your Item as prefab:

and item has ItemLabel as it's child:

What you could do now is:

public class EnemyOrSomething: MonoBehaviour {

public Item itemPrefab;

private void SpawnItem(Item item)
{
itemDropped = true;
nameOfDroppedItem = item.itemName;

Item item = Instantiate(itemPrefab, transform.position - offset, Quaternion.identity);
item.transform.parent = null; // unparent it so it won't get destroyed with the enemy
item.label.SetTextOnLabelOrSomewhere(item.name);

}
}


You just have to add some functionality to the ItemLabel, add a Text component or something.

Is this what you meant?

• My ItemLabel script is a child of the prefab Item. But the Item class in SpawnItem(Item item) is not a game object so it doesn't have a transform. The prefab Item is just a physical orb on the ground, but I want it to represent different things depending on which Item item is passed as a parameter in SpawnItem. – embracethefuture Jun 16 '17 at 23:32

It looks like you just want this:

private void SpawnItem(Item item) {
itemDropped = true;

// Capture the new instance you've spawned:
var itemInstance = Instantiate(
itemPrefab,
transform.position - offset,
Quaternion.identity);

// Get the label component on it.
// (You can combine this with the step above
// if your prefab variable is of the component
// type that you want in the first place)
var label = itemInstance
.GetComponent<DisplayItemLabel>();

// Push your name to the label.
label.SetDisplayName(item.name);

// You probably also want to push the
// item instance itself, so when the player
// collects the item, you know what to award
// to them, without a string lookup.
}