Hi,
I’m trying to use scriptable objects for my items in a diablo style game i’m making, but i have a problem accessing the information inside the objects to use in my game.
In my item object i have a list of attributes.
[System.Serializable]
public class Item : ScriptableObject {
public List<ItemAttribute> attributes = new List<ItemAttribute>();
which are themselves scriptable objects.
[System.Serializable]
public abstract class ItemAttribute : ScriptableObject {
public string test = "Tested";
#if UNITY_EDITOR
public virtual void DoLayout() { }
#endif
}
Each attribute object in the list is derived from a base attribute object has a variable which are all different such as name (string), value(int) or icon(texture2d).
[System.Serializable]
public class NameAttribute : ItemAttribute {
public string ItemName = "New Item";
#if UNITY_EDITOR
public override void DoLayout()
{
ItemName = EditorGUILayout.TextField ("Name", ItemName as string);
}
#endif
}
now my problem is i can’t access the variables of the attributes, i tired making some sort of generic getter like this
public virtual T GetAttrib<T>() { return default (T);}
public override T GetAttrib<T>(){return attrib};
but i get errors saying
Assets/Scripts/Inventory/ItemReference.cs(10,64): error CS0411: The type arguments for method `ItemAttribute.GetAttrib()’ cannot be inferred from the usage. Try specifying the type arguments explicitly
so how would i go about retrieving the variable info from my attributes? is there something i’m overlooking or am i just using scriptable objects completely wrong and they shouldn’t actually be used for item info.
Are you trying to get the variables in a custom editor or at runtime?
If it’s in a custom editor, you shouldn’t need a generic getter. The virtual DoLayout method should take care of it.
If it’s at runtime, you could add some virtual methods to your base ItemAttribute class that return information about the attribute. For example:
public class ItemAttribute : ScriptableObject {
... // (your existing code)
public virtual string[] GetVariableNames() {
return new string[0]; // Base class has no variables.
}
}
public class NameAttribute : ItemAttribute {
... // (your existing code)
public override string[] GetVariableNames() {
return new string[] { "Name" };
}
}
This is essentially a purpose-built form of reflection, without having to fiddle with .NET reflection. If you want to know what variables an attribute instance has, you can just call its GetVariableNames() method.
The code is just off the top of my head, probably not the most efficient way, but hopefully it offers some ideas.
Its at runtime that i would like to be accessing the information mainly for things like getting the damage value from the damage attribute to know how much damage to deal to a monster.
I don’t really understand what getting the type from there would do in helping me get the information from the variable.
i’ve sorted it (i think) by just putting a bunch of getters for each variable type i’ll be using in the base class, although this seems inefficient and hopefully i can come back and change it to a single generic getter later on.