我有一个关卡预制板,里面装有敌人的预制板。这些敌人预制件包含行为脚本组件,这些组件包含某些值,该值控制此特定敌人的行为。 问题在于,对于每个敌人来说,这些值几乎总是唯一的。
在这种情况下我应该使用ScriptableObjects吗?如果可以,那么使用它到底是什么?
我提出这个问题的原因是我对ScriptableObjects完全陌生,所以我想问专家在这种情况下是否有一种利用它们的方法,因为我想为我的项目使用最好的方法/工具/功能离开。
答案 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
,它将应用于所有狙击型敌人。替代方案是必须分别穿越每个狙击型敌人并改变其所有攻击性。也许您会错过一些预制件,或者您会意外地对不同的狙击型敌人设置不同的值。您甚至可以在游戏测试期间执行此操作。aggressiveness
资产分配给每个脚本,而不要在同一个敌人上拥有多个不同的脚本,而每个脚本都有自己的脚本EnemyInfo
,MaxHealth
等字段,或者必须让所有脚本相互交叉引用才能访问字段。