- Home /
I am looking to add a class as a component to a prefab and have that class be a requiredcomponent of the script. Is this possible or am I wasting my time?
I've been searching around online for the past 5 hours for ways to do this and I keep coming up with results that are seem like they are similar to what I want to do, but just haven't helped me in getting this working. I have a feeling I'm either trying to bite off WAY more then I should at the moment since I'm still trying to learn all the ins and outs of C# or trying to do something that personal edition of Unity just doesn't support/do. Here's the full rundown:
I have a few different prefab gameobject item templates in the resources folder of my project that get's loaded dynamically. Both require some custom information that is in their scripts for how they act in the game, but they also have some shared properties. These properties I have in a class called "Item" in separate class-holding script. I've got another script in the Editor folder that should properly extend the editor and create a property drawer for this class. For the inventory system I'm working on, the "Item" class is used to provide a way to give each item it's own int numerical ID & high-level item type through an enum.
The main problem I am running into is there is no errors, yet the Item class, which should added to each prefab object, which has in it's script "[RequireComponent(typeof(Item))]", doesn't seem to appear in the inspector.
I've included the Item script below as well as it's property drawer. Any help will be much appreciated. Also, as a side-note, I know the inspector side doesn't have anything for quantity. That doesn't need to be touched on the item prefabs. The item Type and the Item ID are the main two I want to set through this. The quantity is just there for after it's already in the inventory for another section of script.
Item
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
[System.Serializable]
public class Item : MonoBehaviour,IComparable<Item> {//is used
public int itemID;
public int quantity;
public ItemType itemType;
public Item(int id, int qty, ItemType type){
itemID = id;
quantity = qty;
itemType = type;
}
public int CompareTo(Item other){
if(other == null){
return 1;
}
return quantity-other.quantity;
}
}
Item Property Drawer
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
[CustomPropertyDrawer(typeof(Item))]
public class Editor_Item : PropertyDrawer {
Item _target;
void OnEnable(){
/*_target = (Item)target;
if (_target == null){
Debug.LogError ("There is no Item Attached to " + _target.gameObject.name);
}*/
}
public override void OnGUI(Rect pos, SerializedProperty property, GUIContent label){
GUILayout.BeginVertical();
GUILayout.Label("Item Script",EditorStyles.boldLabel);
_target.itemID = EditorGUILayout.IntField ("Item Identification Number",_target.itemID);
_target.itemType = (ItemType)EditorGUILayout.EnumPopup ("Item Type",_target.itemType);
GUILayout.EndVertical();
if(GUI.changed){
EditorUtility.SetDirty (_target);
}
}
}
I didn't include any of the scripts that have that since it looked simple enough in the scripting manual for requirecomponent. Here's the top few lines of one of the scripts.
using UnityEngine;
using System;
using System.Collections;
[RequireComponent(typeof(Item))]
public class Rune : $$anonymous$$onoBehaviour {
//Rune Stuff
}
Answer by ttRevan · Oct 04, 2015 at 07:51 AM
If I understand correctly, you want that your Item script being auto added to existing prefabs that have RequireComponent dependency on Item. However, RequireComponent only works for newly created prefabs, i.e. for prefabs that was created after putting RequireComponent in a script.
If you want to modify existing prefabs, you can write an Editor script that will scan for prefabs and add missing components to them. This script can be triggered via Editor menu extension or with InitializeOnLoad attribute. However, if you have just a few invalid prefabs, it will be faster to just add the Item script manually.
The idea ultimately was to be able to drag the type script (rune,waystone,etc) onto customized gameobjects and have them ready to be added to the resources folder of that type. I'm using a few different folders (one of each item type) in the resources area as a repository for all the games items. I'd wanted to be able to call a item based on it's type & id which is what the Item class was supposed to add.
Earlier today, I realized that that was more complicated then what I was looking for, and just tweaked the Item class to have a gameobject container. I need to learn how to use System.Linq more extensively now, as I have just a really, really rough understanding of how it works at the moment.
Answer by rasield · Oct 04, 2015 at 11:31 PM
I still don't know if this does work or how to go about it, but I've given up on it for the moment to use an alternate system. I've scrapped the propertydrawer altogether at the moment. Need to learn how to make Unity Custom Inspector GUIs at some point....
For now however, this question is semi-closed, however, I'd still like to know if this is possible/doable and if anyone knows of any methods to implement it properly.
Either way, to share & share alike, I'll be posting the code that I've moved to just in case it helps someone else. The code isn't in it's "final" state, as I'm still adding items to the enum ItemTypes and for each new type there should be a new foreach loop and static list of each new itemtype, but it should be fairly easy for someone to take an expand from here. Also, the gameplaydatamanager might be a tad over-engineered, but wanted to make sure I don't accidentally write to the item-type lists, so I made them read-only.
Item Class
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
public class Item : IComparable<Item> {
public int itemID;
public int quantity;
public ItemType itemType;
public UnityEngine.GameObject itemObject;
public Item(int id, int qty, ItemType type){
itemID = id;
quantity = qty;
itemType = type;
if (type==ItemType.Rune){
Item temp = GameplayDataManager.masterRuneList.First (item => item.itemID == id);
itemObject = temp.itemObject;
}else if (type == ItemType.Waystone){
Item temp = GameplayDataManager.masterWaystoneList.First (item => item.itemID == id);
itemObject = temp.itemObject;
}else{
}
}
public Item(int id, ItemType type, UnityEngine.GameObject obj){
itemID = id;
itemType = type;
itemObject = obj;
}
public int CompareTo(Item other){
if(other == null){
return 1;
}
return quantity-other.quantity;
}
}
GameplayDataManager
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GameplayDataManager : MonoBehaviour {
private static List<Item> _masterRuneList = new List<Item>();
private static List<Item> _masterWaystoneList = new List<Item>();
public static List<Item> masterRuneList{
get{
return _masterRuneList;
}
}
public static List<Item> masterWaystoneList{
get{
return _masterWaystoneList;
}
}
public static void UpdateLists(){
GameObject[] runeList = Resources.LoadAll<GameObject>("Runes");
GameObject[] waystoneList = Resources.LoadAll<GameObject>("Waystones");
print(runeList.Length);
print (waystoneList.Length);
foreach(GameObject entry in runeList){
print ("adding to RuneList " + entry.name);
_masterRuneList.Add(new Item(entry.GetComponent<Rune>().itemId, entry.GetComponent<Rune>().itemType,entry));
print ("MasterRuneList has " + masterRuneList.Count + " entries");
}
foreach(GameObject entry in waystoneList){
print ("adding to WaystoneList " + entry.name);
_masterWaystoneList.Add(new Item(entry.GetComponent<Waystone>().itemId, entry.GetComponent<Waystone>().itemType,entry));
}
}
}
Your answer
Follow this Question
Related Questions
Custom inspector, show string instead of component type 0 Answers
Inspector vs Script: Component best practice? 1 Answer
How do I change inspector values of other game objects using a custom Editor Window 0 Answers
Add two components of the same type using RequireComponent attribute 1 Answer
Inspector Component Icon - change for derived as well? 0 Answers