- Home /
GetType is Monoscript, how to implement correctly? store type in variable?
Hello,
I'm trying to find a good way to do the following.
I got a game, with numerous items, so like 30 scripts, that implements an interface IITem.
I am trying to make a system that drop those items randomly, here is the actual code :
GameManager.cs ( the script that handle where to drop items etc) GameObject droppedItem = Instantiate(DroppablePrefab, SpawnLocation, Quaternion.identity);
This drop a prefab that looks like this : Drop.cs [System.Serializable] public class Item { public Object type; public Sprite sprite; public float ratio; }
public class Drop : MonoBehaviour {
public Item[] items;
SpriteRenderer spriteRenderer;
Object itemType;
// Use this for initialization
void Start () {
spriteRenderer = transform.GetChild(0).GetComponent<SpriteRenderer>();
Item item = GetRandomItem();
spriteRenderer.sprite = item.sprite;
itemType = item.type;
}
// Update is called once per frame
void Update () {
}
Item GetRandomItem()
{
return items[0];
}
private void OnTriggerEnter2D(Collider2D collider)
{
if (collider.transform.CompareTag("Player"))
{
collider.transform.GetComponent<Player>().Drop(itemType);
}
Destroy(gameObject);
}
}
So I chose a random item ( for the moment always item 0) and I pass the item script to the player The inspector looks like this (which is what i want, a simple drag and drop to add dropable items)
Now I want to add the script to the player and I do that : Player.cs
public void Drop(Object itemType)
{
pAbilities.item = gameObject.AddComponent(itemType.GetType()) as IItem;
}
But this returns me the following
I understand why, but I don't know how to fix so that I can have what I want. How to store a variable type? Many multiple script, that I can drag and drop from the inspector, and instantiate them on the player so he can use them, and destroy the item while used.
Do I have to make multiples prefab one for each items and kind of append them to the player while he use them? Isn't there a good solution?
Thanks
Answer by Bunny83 · Jan 12, 2018 at 12:41 PM
There seems to be several things wrong here. First of all the MonoScript class is a pure editor class. So you can't use it in any runtime script as the class is only available in the editor. Unity doesn't have any serializable type that can hold a "type" information.
If you want / need a serializable approach that can be edited in the inspector you have to create a prefab for each of your concrete class so you can reference the instance from your array.
If you just want to find all types that implement a certain interface you can use the helper methods i posted over here. "AllTypesDerivedFrom" gives you a collection of all types which are derived from the given type. Of course any class could implement an interface so if you only need components you want to filter the list to types which are derived from Component as well.
edit
If you want / need a drag and drop solution for script types you can use the property drawer and the attribute class i've posted over here
so I guess easiest way would be to forget about the inspector and modify all via code directly ?
Well it highly depends on what an "Item" actually represents. The usual approach in Unity is to use prefabs. Prefabs can be instantiated and added as a child object to the player. However you can also just access the script instance on the prefab to get the type of the script in order to use AddComponent.
The property drawer i linked at the end of my answer can be used to easily drag and drop $$anonymous$$onoScripts into the inspector and have it converted into a class name. That class name can be used with Type.GetType to get the System.Type object for the class which can be used in AddComponent.
Your answer
Follow this Question
Related Questions
Instantiate an object every x meters between two others. 1 Answer
Object spawn issues 1 Answer
Instantiate problems 1 Answer
Instantiate duplicates script in subsequent Objects 2 Answers