What is the proper way to link a loot table and an enemy ?

Hello,

I would like my enemies to drop some items when they die.

To do so, I created a class, LootTable, which contains a container (a List of items along with a probability for each item) , and the logic (a Drop() function that returns me a List of items that are dropped). Every kind of enemy will have a loot table associated and will be able to generate drops from it.

Then, my abstract Enemy class that is extended by each of my enemy scripts has a public static LootTable lootTable. What seems to be left is linking my items prefab and these LootTables in the Unity editor, and assigning probabilities.

But my LootTable won’t show in the Unity editor when I click on a GameObject that extends my Enemy class, and it seems that the “static” keyword causes this problem.
However, since I do not want to instantiate my LootTable everytime I instantiate an Enemy in my scene, I really want this Loot Table to be static for each enemy type.

For example, my “Goblin” enemy will have a LootTable containing a “Goblin Dagger” (along with its probability) and a “Ruby”, and another enemy “Sorcerer” will have a LootTable containing “Wand” and “Gold”. My “Goblin” prefab should hold my static LootTable and it should be editable in the editor, but I definitely do NOT want this table to be instantiated for every single Goblin in my scene.

What would be the proper way to implement this in Unity, since this static variable (LootTable) does not want to show up in the editor ?

Thanks for reading, and happy coding :slight_smile:

There are a lot of possibilities! Two main ones that occur to me:

  1. Make your LootTable a ScriptableObject. It would then be an asset in the project that you could edit in the inspector, and you could create a serialized reference to it on your enemy prefabs. Potential drawbacks: Any run-time modifications to this LootTable will affect the asset in the project.
  2. Make your LootTable accessible on a MonoBehaviour singleton (see this example). You then would make sure there’s always an instance of a LootTable prefab in the scene and access something like LootTable.instance. Potential drawbacks: You need to make sure you always have one of these (active) in the scene any time you’re trying to access it.

My personal preference for this sort of thing is the first option, but always just depends on your specific circumstances.

To keep your static but still be able to use the inspector, without changing too much of your code, you could use a public variable that gets assigned in the inspector, then simply set the static accordingly by script.

public LootTable inspectorTable;
public static LootTable globallyAccessibleVar;

void Update (){
  if(globallyAccessibleVar != inspectorTable)
    globallyAccessibleVar = inspectorTable;
}

You will want to use a more efficient method of updating the global possibly through a custom inspector, but the overhead from something like this should be minimal.