首页 > 解决方案 > 使用或不使用 ScrtiptableObects?

问题描述

我有一个关卡预制件,其中包含敌人预制件。这些 Enemy Prefab 包含行为脚本组件,其中包含控制特定敌人行为的某些值。问题是这些值对于每个敌人来说几乎总是独一无二的。

我应该在我的情况下使用 ScriptableObjects,如果是,那么究竟如何?

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

标签: unity3d

解决方案


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

在您的情况下,假设您有一个EnemyAI脚本附加到您的 Enemy 预制件。在你的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领域,这将决定敌人的行为方式。

因此,您基本上删除了EnemyAIMonoBehaviour 上的所有字段(攻击性、武器类型等)——可能还有主Enemy脚本上的最大生命值、速度等——并将这些字段移动到 ScriptableObject 上。 或者,您可以为敌人 AI 参数创建一种类型的 ScriptableObject,为敌人统计数据创建一种类型的 ScriptableObject。这样,您可以在具有不同统计数据的多个敌人之间共享 AI 参数。

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

优点

  • 如果您有几个不同的敌人并且您希望他们都充当狙击手,您可以将“狙击手”资产拖到他们的enemyInfo领域。现在,如果您决定狙击手应该更具攻击性,您可以aggressiveness在 Unity 编辑器中更改“狙击手”资源,它将适用于所有狙击手类型的敌人。另一种选择是必须单独穿过每个狙击型敌人并改变他们的所有侵略性。也许您会错过一些预制件,或者您可能会不小心为不同的狙击型敌人设置不同的值。您甚至可以在游戏测试期间执行此操作。
  • 您可以在游戏运行期间通过在 Unity 编辑器中为敌人分配不同的 ScriptableObject 资产来热交换敌人的行为。
  • 如果您在一个敌人上有多个脚本都需要访问相同的敌人数据,您可以将该EnemyInfo资产分配给每个脚本,而不是在同一个敌人上有几个不同的脚本,它们都有自己的MaxHealth,WeaponType等字段,或者有让脚本都相互交叉引用以访问字段。
  • 您可以成为 ScriptableObjects 酷儿童俱乐部的一员。

这是关于 ScriptableObjects 的一个非常好的演示文稿


推荐阅读