使用继承的类作为参数进行重写



我正在为我的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);
}

以及从Weapon继承的Pistol

public class Pistol : Weapon {
PistolData pistolData;
void Start() {
Initialize(pistolData);
}
public override void Initialize(PistolData pistolData) {
//do something
}
}

就像你可以看到这两个类在初始化方法/函数中使用以下两个类一样。WeaponData类:

public abstract class WeaponData : ScriptableObject
{
public int durability;
public int damage;
}

以及继承自WeaponDataPistolData

[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;
}

我现在的问题:我收到错误,因为初始化需要WeaponData而不是PistolData。我认为这会起作用,因为PistolData实际上是通过继承WeaponData。至少我是这么认为的..

有没有办法使这种继承成为可能?如果没有,我应该如何解决?

我对 Unity 和 C# 非常陌生,如果不是这样,我不知道如何管理我的武器系统。

您可以使该方法无参数,并简单地使用字段中的值

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
}
}

使用泛型和泛型约束应该可以满足你在这里的需求

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
}
}

最新更新