- Home /
Populating list of custom class through inspector
HI!
I have a list of my abstract custom class "Stat" on my items in a game i'm making. I want to be able to populate this list through the inspector so that i can make multiple, different items easily. The problem is that i can't create instances of the "Stat" class through the inspector.
"Stat" class with sublasses:
using UnityEngine;
using System.Collections;
[System.Serializable]
abstract public class Stat : MonoBehaviour {
public int value;
public Stat (int value) {
this.value = value;
}
abstract public string Print() ;
}
[System.Serializable]
public class FireRateStat : Stat {
public FireRateStat(int value) : base(value) {
this.value = value;
}
public override string Print() {
return "Fire rate: " + value + "/n";
}
}
[System.Serializable]
public class DamageStat : Stat {
public DamageStat(int value) : base(value) {
this.value = value;
}
public override string Print() {
return "Damage: " + value + "/n";
}
}
[System.Serializable]
public class HealthStat : Stat {
public HealthStat(int value) : base(value) {
this.value = value;
}
public override string Print() {
return "Health: " + value + "/n";
}
}
[System.Serializable]
public class HealthRegStat : Stat {
public HealthRegStat(int value) : base(value) {
this.value = value;
}
public override string Print() {
return "Health regen: " + value + "/n";
}
}
[System.Serializable]
public class ShieldStat : Stat {
public ShieldStat(int value) : base(value) {
this.value = value;
}
public override string Print() {
return "Shield: " + value + "\n";
}
}
[System.Serializable]
public class ShieldRegStat : Stat {
public ShieldRegStat(int value) : base(value) {
this.value = value;
}
public override string Print() {
return "Shield Regen: " + value + "/n";
}
}
[System.Serializable]
public class MoveSpeedStat : Stat {
public MoveSpeedStat(int value) : base(value) {
this.value = value;
}
public override string Print() {
return "Move Speed: " + value + "/n";
}
}
Item class:
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
public enum Category
{
None,
Engine,
Shield,
Weapon,
Chassis,
}
public class ShipPart : MonoBehaviour {
PlayerStats player;
[TextArea]
public string description;
[TextArea]
public string partName;
public int buyValue;
public int sellValue;
public List<Stat> stats;
[HideInInspector]
public ItemImage itemImage;
[HideInInspector]
public string statsText = "";
public Category category;
public void UnassignSelf(bool removeItem = true) {
if(itemImage != null)
{
itemImage.UnassignItem(removeItem);
}
}
private void CreateStatsText () {
foreach (Stat stat in stats) {
statsText += stat.Print();
}
}
public void UnapplyStats() {
Debug.Log("Not implemented yet");
}
public List<Stat> GetStats() {
return stats;
}
public void Start () {
CreateStatsText();
}
}
Current inspector:
Answer by Bunny83 · Aug 11, 2019 at 01:21 AM
What you want to do doesn't work. At the moment your "Stat" class is a MonoBehaviour derived class and not a custom serializable class. MonoBehaviours do support inheritance but are components and have to be attached as component to a gameobject.
Actual custom serializable classes must not be derived from MonoBehaviour. However they do not support inheritance at all. Custom serializable classes are serialized inline based on the variable type. They are not serialized as seperate objects. Unity just serializes the fields as sub fields of the hosting monobehaviour class. No type information is stored for custom serializable classes.
MonoBehaciour derived classes do support inheritance but they are seperate object instances and will not be serialized or displayed inline in the inspector. They need to be attached as seperate components to a gameobject. When you have a field to a "stat" class it will only be a serializable reference just like you see in your screenshot. So you can drag in a reference to an attached component.
Your exact usecase is not clear. How you want to manage or use those stat classes. Note that if you want to use actual components you can not define a custom constructor as the objects are created by dragging the script of such a component onto a gameobject in the inspector or by using gameObject.AddComponent<YourStatType>()
. Keep in mind that MonoBehaviour derived types need to be located in their own script file and the file name need to match the class name contained in the file.