# Unitys [SerializeField] and parallel inheritance

I have the following:

public class Item
{
[SerializeField]ItemData _data;

public ItemData data { get { return _data; } }
}

public class Weapon : Item
{
[SerializeField]WeaponData _data;

public WeaponData data { get { return _data; } }
}

public class ItemData : ScriptableObject { }
public class WeaponData : ItemData { }


It seems like a pretty common setup to me, data is separated from logic classes - and I can use single scriptable objects to define stats for alot of items.

However, Unity gives me this error message:

The same field name is serialized multiple times in the class or its parent class. This is not supported:

I understand what's going wrong, but I don't get how to work around it, I want the data objects to inherit so I don't need to keep two (or more, further into inheritance) separate data objects per weapon.

I also need the item inheritance for inventory/merchant list management. Using hiding screws up the serialization of the baseclass, which means I can't create default items - not feasible.

The issue is the same when using public instead of [SerializeField].

Any pointers?

• My immediate thought is "if you need to do this, you're almost certainly doing something wrong." e.g. if I have a Weapon object instanced, called weap and I do weap.data, what should I get back? An ItemData or a WeaponData? – Draco18s Nov 30 '17 at 2:28
• You are on the right track(logic-wise), but looking at the code I think some misunderstanding of inheritance concept is taking place. Serialization message just misleads you from the real problem(redeclaration of the same field in derived class?). I strongly advice looking at Unity provided example of inheritance, this might help unity3d.com/learn/tutorials/topics/scripting/inheritance – metamorphling Nov 30 '17 at 2:28
• Whether or not this is the right approach, usually serialization issues like this stem from the variable name itself. Typically auto serialization generates a getter and setter based on the variable name. Just like in a class you cant have two variables with the same name in the same scope, the same applies to inheritance without override. – Stephan Nov 30 '17 at 3:26

It looks to me like you might actually want an IItem interface, or abstract class, a bit like this:

// Establish the contract that any "Item-ish"
// object must be able to provide ItemData
// through a standard property (could be abstract
// instead of an interface if you have code or
// members you want to share between item types.
public interface IItem
{
public ItemData data { get; };
}

public class Item : IItem
{
// Expose an inspector field of the concrete
// type we want - this will accept ItemData
// or any type inheriting from it.
[SerializeField] ItemData _data;

// Return this inspector-set property as our
// IItem-mandated data property
public ItemData data { get {return _data; } }
}

public class Weapon : IItem
{
// Expose an inspector field of the concrete
// type we want - this will accept only WeaponData
// not ItemData instances that aren't weapon-specific.
[SerializeField] WeaponData _data;

// Return this specialized WeaponData as an ItemData
// when requested.
public ItemData data { get {return _data; } }
}


Now any code can work with a mixed group of Items and Weapons by treating them all as items. It can also use casts or the as keyword to get at Weapon/item-type-specific data when it knows it has a particular item type.

If you go much further with this, you may want to consider applying the principle of Composition Over Inheritance. Especially in Unity's setup, this can give you a lot more flexibility - letting you make things like a spiked shield that has both a DefensiveItem component and a WeaponItemComponent, without needing to refactor two separate branches of the inheritance hierarchy to handle such exceptions and hybrids.