0

我有这个 ScriptableObject,我想在创建时为每张卡片添加一个效果;我有一个名为“EffectManager”的脚本,它有一些方法作为效果。

这是我的卡片脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "New Card", menuName = "Card")]
public class Card : ScriptableObject
{
    public string m_cardName;
    public Sprite m_sprite;

    public int m_manaCost;
    public int m_health;
    public int m_attack;
}

这是我的 EffectManager 脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class EffectManager : MonoBehaviour
{
    Deck dk;
    Hand hnd;
    Player p1;
    
    private void Awake()
    {
        dk = GameObject.FindObjectOfType<Deck>();
        hnd = GameObject.FindObjectOfType<Hand>();
        jg1 = GameObject.FindObjectOfType<Player>();
    }

    public void draw(int num)
    {
        jg1.DrawCards(num);
    }

    public void discard()
    {
        hnd.hand.RemoveAt(0);
    }

    private void mill()
    {
        dk.deck.RemoveAt(0);
    }
}

我怎样才能使我创建的每张卡都具有与之关联的效果,该效果会在满足条件时激活?(在这种情况下,它会在卡片被召唤时)

4

1 回答 1

0

您可以使用我喜欢称之为“可编写脚本的行为”的模式,它基本上只是由另一种ScriptableObject类型组成并实现不同的效果,例如

public abstract class CardEffect : ScriptableObject
{
    // You can give that the signature (parameters and return type) you want/need of course
    // Every type inherited from this HAS TO implement this method
    public abstract void ExecuteEffect (EffectManager effectManager);
}

现在您可以实现某些可配置的效果,例如

public class DrawEffect : CardEffect
{
    // Adjust how many cards are drawn
    public int amount;

    public override void ExecuteEffect (EffectManager effectManager)
    {
        effectManager.draw(amount);
    }
}

或者例如

public class DrawAndDiscardEffect : DrawEffect
{
    public override void ExecuteEffect (EffectManager effectManager)
    {
        // First do whatever the parent class implements
        base.ExecuteEffect(effectManager);

        // Additionally discard the same amount of cards
        for(var i = 0; i < amount; i++)
        {
            effectManager.discard();
        }
    }
}

最后,您将在卡定义中有一个附加字段。就我个人而言,我什至会使用一个数组,这样你就可以完全灵活地组合不同类型的效果,而不必从另一个继承

public class Card : ScriptableObject
{
    public CardEffect[] effects;

    ...

    public void Summon(EffectManager effectManager)
    {
        foreach(var effect in effects)
        {
            effect.ExecuteEffect(effectManager);
        }
    }
}

现在剩下的就是你的设置中的某些东西实际上调用了它

// Wherever you get these from
EffectManager effectManager;
Card someCard;

someCard.Summon(effectManager);

这可以很容易地扩展到您需要的协同性。例如,您可以不使用Summon方法,而只有一个效果集合具有另一个调用的 ScriptableObject 类型EffectCondition,并实现不同类型的条件,然后这些条件将运行它们附加的效果集合。

然后中央控制器可以遍历所有卡片,而不是调用例如CheckCondition,然后每张卡片都经过所有附加的条件设置,检查是否满足相应的条件,然后执行绑定到该条件的所有效果;)

于 2021-11-15T07:59:02.170 回答