You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调用自定义脚本重写CardBG类虚函数实现卡牌功能?

解决方案:卡牌行为与ScriptableObject关联的两种实现方式

ScriptableObject是数据容器,无法挂载MonoBehaviour脚本,因此你需要将卡牌的行为逻辑与数据对象关联起来,以下是两种实用的实现方案:

方法1:用ScriptableObject封装卡牌行为(策略模式)

创建抽象的能力基类SO,将卡牌行为定义为抽象方法,每个卡牌的独特能力对应一个SO子类,最后在CardBG中引用该SO,触发事件时调用对应方法。

代码示例

// 抽象能力SO基类
public abstract class CardAbilitySO : ScriptableObject
{
    public abstract void OnDamage(CardBG card);
    public abstract void OnDie(CardBG card);
    public abstract void OnAttack(CardBG card);
    public abstract void OnEndTurnP1(CardBG card);
}

// 具体卡牌能力SO(例如火焰法师卡牌)
[CreateAssetMenu(fileName = "FireMageAbility", menuName = "CardAbilities/FireMage")]
public class FireMageAbilitySO : CardAbilitySO
{
    public override void OnDamage(CardBG card)
    {
        // 火焰法师受伤时的逻辑:反弹2点伤害给攻击者
        Debug.Log("火焰法师受伤,触发伤害反弹");
    }

    public override void OnDie(CardBG card)
    {
        // 死亡时触发全场AOE伤害
        Debug.Log("火焰法师死亡,释放全场火焰伤害");
    }

    public override void OnAttack(CardBG card)
    {
        // 攻击时点燃目标
        Debug.Log("火焰法师攻击,点燃目标");
    }

    public override void OnEndTurnP1(CardBG card)
    {
        // 玩家1回合结束时,自身回复1点生命值
        Debug.Log("玩家1回合结束,火焰法师回复生命值");
    }
}

修改CardBG类,关联能力SO并触发对应逻辑:

public class CardBG : MonoBehaviour
{
    [SerializeField] private CardAbilitySO _cardAbility;

    protected virtual void OnDamage()
    {
        _cardAbility?.OnDamage(this);
    }
    
    protected virtual void OnDie()
    {
        _cardAbility?.OnDie(this);
    }
    
    protected virtual void OnAttack()
    {
        _cardAbility?.OnAttack(this);
    }
    
    protected virtual void OnEndTurnP1()
    {
        _cardAbility?.OnEndTurnP1(this);
    }
}

之后在你的卡牌数据库SO中,为每张卡牌绑定对应的CardAbilitySO即可,触发事件时会自动执行该SO定义的行为。

方法2:使用CardBG子类预制体

如果更习惯用继承实现行为,可以为每张卡牌创建CardBG的子类,重写虚函数后挂载到卡牌预制体上,最后在数据库SO中存储该预制体。

代码示例

// 战士卡牌子类
public class WarriorCard : CardBG
{
    protected override void OnAttack()
    {
        // 战士攻击时给自己加护盾
        Debug.Log("战士攻击,获得2点护盾");
    }

    protected override void OnDie()
    {
        // 死亡时为队友提升攻击力
        Debug.Log("战士死亡,队友攻击力+1");
    }
}

创建战士卡牌预制体,挂载WarriorCard脚本,在数据库SO中添加public GameObject cardPrefab字段并赋值该预制体。生成卡牌时直接实例化预制体,其自带的子类脚本会处理对应行为。

两种方式对比

  • 方法1适合能力复用:多张卡牌共享同一种能力时,只需创建一个SO即可,数据与行为分离更清晰。
  • 方法2适合复杂组件交互:如果卡牌行为需要频繁操作自身动画、粒子等组件,子类继承的方式更直观。

内容的提问来源于stack exchange,提问作者lucasmix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:03:20