我正在为我的2D游戏制作一个模块化的武器系统,我被下面的问题卡住了。
假设我有一个抽象的基类,名为 Weapon
public abstract class Weapon : MonoBehaviour
{
public int damage { get; set; }
public int durablity { get; set; }
public Sprite sprite { get; set; }
public abstract void Initialize(WeaponData weaponData);
}
和a Pistol
继承自 Weapon
public class Pistol : Weapon {
PistolData pistolData;
void Start() {
Initialize(pistolData);
}
public override void Initialize(PistolData pistolData) {
//do something
}
}
像你可以看到这两个类在Initialize MethodFunction中使用了以下两个类。A WeaponData
类。
public abstract class WeaponData : ScriptableObject
{
public int durability;
public int damage;
}
和a PistolData
继承自 WeaponData
[CreateAssetMenu(fileName = "new PistolData", menuName = "MyAssets/PistolData", order = 0)]
public class PistolData : WeaponData
{
public Vector2 pivotPoint;
public Vector2 firePoint;
public GameObject bulletPrefab;
public float bulletForce;
public Sprite weaponSprite;
public float fireRate;
}
我的问题:我得到一个错误,因为Initialize需要一个 WeaponData
而非 PistolData
. 我认为这将工作,因为 PistolData
实际上是 WeaponData
通过继承... 至少我是这么认为的。
有什么方法可以让这种继承成为可能吗?如果没有,我应该如何解决呢?
Im very new to Unity and C# and I have no Idea left how I could Manage my Weapon System if not like this.
使用泛型和泛型约束应该可以得到你所需要的东西。
public abstract class Weapon<TWeaponData> : MonoBehaviour
where TWeaponData : WeaponData
{
public int damage { get; set; }
public int durablity { get; set; }
public Sprite sprite { get; set; }
public abstract void Initialize(TWeaponData weaponData);
}
那你的手枪班可以这样做
public class Pistol : Weapon<PistolData>
{
PistolData pistolData;
void Start() {
Initialize(pistolData);
}
public override void Initialize(PistolData pistolData) {
//do something
}
}
你可以让这个方法不需要参数,只需使用字段
public override void Initialize()
{
// do something with pistolData since you seem to have it as field
}
你也可以添加一个类型检查,比如
public class Pistol : Weapon
{
[SerializeField] PistolData _pistolData;
void Start()
{
Initialize(pistolData);
}
public override void Initialize(WeaponData weaponData)
{
if (!(weaponData is PistolData pistolData))
{
Debug.LogError("I expected a " + nameof(PistolData), this);
return;
}
// use pistolData
}
}
或者您可以在 Weapon
武器应该做什么,并在你的继承中使用非覆盖方法。
public abstract class Weapon : MonoBehaviour
{
public int damage { get; private set; }
public int durablity { get; private set; }
public Sprite sprite { get; set; }
protected void Initialize(WeaponData weaponData)
{
damage = weapondData.damage;
durability = weaponData.durability
}
}
然后
public class Pistol : Weapon
{
public void Initialize(PistolData pistolData)
{
base.Initialize(pistolData);
// do pistol specific stuff
}
}