使用还是不使用ScrtiptableObects?

时间:2019-03-05 14:39:25

标签: unity3d

我有一个关卡预制板,里面装有敌人的预制板。这些敌人预制件包含行为脚本组件,这些组件包含某些值,该值控制此特定敌人的行为。 问题在于,对于每个敌人来说,这些值几乎总是唯一的。

在这种情况下我应该使用ScriptableObjects吗?如果可以,那么使用它到底是什么?

我提出这个问题的原因是我对ScriptableObjects完全陌生,所以我想问专家在这种情况下是否有一种利用它们的方法,因为我想为我的项目使用最好的方法/工具/功能离开。

1 个答案:

答案 0 :(得分:3)

将ScriptableObjects视为仅具有属性而没有方法的C#类。它们用作数据容器,您可以通过Unity编辑器将其分配给游戏对象组件。

根据您的情况,假设您有一个EnemyAI脚本附加到您的敌人预制件上。在EnemyAI脚本中,您可以执行以下操作

public class EnemyAI : MonoBehaviour
{
    // The ScriptableObject asset that is assigned through the Unity editor
    public EnemyInfo enemyInfo;

    private EnemyBehavior currentBehavior;

    void Update()
    { 
        // If this agent has no behavior assigned or it has completed its 
        // previous behavior, choose a new behavior and assign it to this
        // agent
        if (this.currentBehavior == null)
        {
           if (Random.Range(0, 1) <= this.enemyInfo.aggressiveness)
           {
              if (this.enemyInfo.weaponType == "melee")
              {
                 this.currentBehavior = new ChargePlayerBehavior();
              }
              else if (this.enemyInfo.weaponType == "ranged")
              {
                 this.currentBehavior = new ShootPlayerBehavior();
              }
              else
              {
                 throw new Exception("This enemy needs a weapon to attack with!")
              }
           }
           else
           {
              this.currentBehavior = new AvoidPlayerBehavior();
           }
        }

        this.currentBehavior.Update();
    }
}

public class EnemyInfo : ScriptableObject
{
   public float aggressiveness;
   public string weaponType;
   // other fields - max health, speed, etc.
}

然后,您将在项目中为每种敌人行为类型创建EnemyInfo资产。例如:

  • 狙击手,拥有远程武器,但攻击性不强
  • 具有远程武器并具有中等侵略性的士兵
  • 狂战士,拥有近战武器而且非常好斗
  • 没有武器,零侵略的小偷

然后,对于每个拥有的敌人预制件,可以将这三个EnemyInfo资产之一插入其enemyInfo字段中,这将决定敌人的行动方式。

因此,您基本上要删除EnemyAI MonoBehaviour上的所有字段(攻击性,武器类型等),并且可能会删除主要{{1 }}脚本-并将这些字段移到ScriptableObject上。 或者您可以为敌人的AI参数创建一种类型的ScriptableObject,为敌人的统计信息创建一种类型的ScriptableObject。这样,您可以在具有不同统计数据的几个敌人之间共享AI参数。

即使您的价值观在所有敌人之间都是独一无二的,您也并没有真正失去任何东西(除了创建ScriptableObject资产时可能需要做一些额外的工作)。您只是将敌人的数据字段放入ScriptableObject中,而不是作为MonoBehaviour上的字段。而且将来您可能会发现想要重复使用敌人的行为,例如让标准兵和精锐兵各有相同的AI特征。

优势

  • 如果您有几个不同的敌人,并且希望他们全部充当狙击手,请将“狙击手”资产拖到他们的Enemy字段中。现在,如果您决定让狙击手更具攻击性,则可以在Unity编辑器中更改“狙击”资产的enemyInfo,它将应用于所有狙击型敌人。替代方案是必须分别穿越每个狙击型敌人并改变其所有攻击性。也许您会错过一些预制件,或者您会意外地对不同的狙击型敌人设置不同的值。您甚至可以在游戏测试期间执行此操作。
  • 您可以在游戏进行过程中通过在Unity编辑器中为敌人分配不同的ScriptableObject资源来热交换敌人的行为。
  • 如果在一个敌人上有多个脚本都需要访问相同的敌人数据,则可以将aggressiveness资产分配给每个脚本,而不要在同一个敌人上拥有多个不同的脚本,而每个脚本都有自己的脚本EnemyInfoMaxHealth等字段,或者必须让所有脚本相互交叉引用才能访问字段。
  • 您可以成为ScriptableObjects酷儿童俱乐部的成员。

This is a very good presentation on ScriptableObjects