unity c#继承/泛型接口升级不同子类

Unity c# Inheritance / generic Interface to upgrade different subclasses

我正在尝试通过使用接口升级特定的加农炮,我面临的问题是由于某种原因函数被正确调用并且没有错误,但实际上参数没有“升级” " 符合预期。

BaseWeapon.cs

public class BaseWeapon : MonoBehaviour
{

public new string name;
public int level = 1;
public int damage;
public int cost;
private BaseEnemy target;
public IDoDamage damageType;
public IDoUpgrade upgradeType;

public int TryDoDamage(BaseEnemy target, int damage)
{
    this.target = target;
    int dmg = (int)damageType?.DoDamage(target, damage);
    target.UpdateHealth();
    return dmg;
}
public void TryDoUpgrade(BaseCannon cannon)
{
    Debug.Log("Inside TryDoUpgrade SUCCESS");    // This debug works
    upgradeType?.DoUpgrade(cannon);
    Island.Instance.Spend(cannon.cost);
}

以上调试有效,并且金币按预期从玩家身上减去。

DefCannon.cs我用这个实例化了一个继承自BaseWeaponBaseCannon,带有自定义参数,这是默认的大炮,我也有一个FireCannon作为例如,它们都继承自 BaseCannon,后者又继承自 BaseWeapon.:

public class DefCannon : BaseCannon
{
public void Init(int level)
{
    name = "Defcannon";
    this.level = level;
    cannonMat = Cannonballs.cbCannonMat["Default"];
    damage = 50 * level;
    ballMat = Cannonballs.cbMat["Default"];
    cbSpeed = Cannonballs.cbSpeed["Default"];
    minPrecision = 0.91f;
    maxPrecision = 1.11f;
    minReload = 0.5f;
    maxReload = 1.0f;
    damageType = new DefDamage(level);
    upgradeType = new DefUpgrade(this, level);
}
}

我觉得问题可能也出在这里upgradeType = new DefUpgrade(this, level);

this = DefCannon.cs // which inherits from BaseCannon

但是 DefUpgrade(BaseCannon baseCannon, int level) DefUpgrade 要求 BaseCannon,而我们给它一个 BaseCannon 的 child,在这种情况下是 DefCannon,可能这就是它不起作用的原因吗?我将如何解决这个问题,我没有从 child 脚本中引用 BaseCannon 脚本,有没有办法做到 this.BaseCannon,(调用 parent class不知何故?)

澄清一下,上面的脚本只是用来设置参数的,我有一个prefabCannon,没有脚本,当我实例化那个prefabCannon时,我添加了脚本DefCannonFireCannon,取决于我想实例化哪门大炮,这样我就可以让它们都使用它们都需要的通用函数,但每个都有自定义参数等。

DefUpgrade.cs 这是问题所在,BaseWeapon 脚本中的 Debug.Log 有效,但下一步是进入 DefUpgrade.cs 并尝试调用 DoUpgrade() 失败,因为从未调用该脚本中的 Debug.Log

public class DefUpgrade : IDoUpgrade
{
public int level;
public DefUpgrade(BaseCannon baseCannon, int level)
{
    this.level = level;
    baseCannon.cost = DefUpgradeDictionary.cost[level];
}
public void DoUpgrade(BaseCannon baseCannon)
{
    Debug.Log("Inside DoUpgrade SUCCESS");   // This debug is never reached/called
    var baseDamage = baseCannon.damage / baseCannon.level;
    baseCannon.level++;
    baseCannon.damage = baseDamage * level;
    var lvl = baseCannon.level;
    baseCannon.damageType = new DefDamage(lvl);       //CHECK IF IT WORKS
    baseCannon.minPrecision = DefUpgradeDictionary.minPrecision[lvl];
    baseCannon.maxPrecision = DefUpgradeDictionary.maxPrecision[lvl];
    baseCannon.minReload = DefUpgradeDictionary.minReload[lvl];
    baseCannon.maxReload = DefUpgradeDictionary.maxReload[lvl];
    baseCannon.cost = DefUpgradeDictionary.cost[lvl];

}
}

我使用了完全相同的界面结构来造成伤害,因为所有大炮都需要造成伤害,但再次使用不同的参数,在那个结构中我没有问题,但是当我为升级重新创建它时它似乎不起作用但是让这如此混乱的是没有控制台错误,没有丢失引用,它调试函数 A 然后调用函数 B,但是函数 B 中的调试永远不会被调用!

IDoUpgrade.cs界面

public interface IDoUpgrade
{
    void DoUpgrade(BaseCannon cannon);
}

呼叫TryDoUpgrade()

baseCannon = PlayerRays.Instance.baseCannon;
    if (PlayerRays.Instance.safe && Island.Instance.gold >= baseCannon.cost)
    {
        PlayerRays.Instance.baseWeapon.TryDoUpgrade(baseCannon);
        
    }

最后这 2 个脚本工作正常,问题似乎不存在。

感谢您对此进行调查,我非常感谢,因为我已经尝试解决这个问题将近 2 天了。

更新 1:添加了 BaseCannon.cs:

public class BaseCannon : BaseWeapon
{
    private Transform cannon, cylinder, spawn, closestEnemy;
    private MeshRenderer mesh;
    private GameObject flame;
    private List<Transform> enemyShips;
    public Material cannonMat, ballMat;
    public float cbSpeed;
    private float aliveTime = 15f;
    public float minPrecision, maxPrecision, minReload, maxReload;

    void Start()
    {
        cannon = transform.Find("Cannon");
        cylinder = cannon.transform.Find("Cylinder");
        spawn = cylinder.transform.Find("Spawn");
        flame = spawn.transform.Find("Flame").gameObject;
        flame.SetActive(false);
        mesh = cannon.GetComponent<MeshRenderer>();
        mesh.material = cannonMat;
    }
}

我认为错误出在 BaseWeapon class 上。 (如果我对结构的理解正确的话)你传递的是其中定义了 upgradeType 的 BaseCannon,但你是从 BaseWeapon 调用方法。

public class BaseWeapon : MonoBehaviour
{

public new string name;
public int level = 1;
...
public IDoUpgrade upgradeType;


public void TryDoUpgrade(BaseCannon cannon)
{
    Debug.Log("Inside TryDoUpgrade SUCCESS");    // This debug works
    upgradeType?.DoUpgrade(cannon);
    
    // in fact the upgrade is null as it's defined in the cannon
    // not the weapon. 
    if (upgradeType == null)
    {
        Debug.Log("No upgrade defined. Create from cannon");
        // set the upgrade from the cannon, and then call it
        upgradeType = cannon.upgradeType;
        upgradeType?.DoUpgrade(cannon);
    }
}
}