简体   繁体   English

从 ScriptableObject 引用 class

[英]Reference a class from a ScriptableObject

I have an EnemyData ScriptableObject that holds data about enemies.我有一个EnemyData ScriptableObject 保存有关敌人的数据。 I'd like to have a field on EnemyData that references some logic about how this enemy behaves on its turn (in turn-based card game).我想在EnemyData上有一个字段,它引用一些关于这个敌人在其回合中如何表现的逻辑(在回合制纸牌游戏中)。 My current attempt at this is to structure that as a ScriptableObject too, basically like this:我目前的尝试是将其构建为 ScriptableObject,基本上是这样的:

public class EnemyData : ScriptableObject
{
    public int health;
    public EnemyAIBase enemyAI;
}

public abstract class EnemyAIBase : ScriptableObject
{
    public abstract void PlayTurn(Enemy thisEnemy);
}

public class PirateShipAI : EnemyAIBase
{
    public override void PlayTurn(Enemy thisEnemy)
    {
        thisEnemy.Heal();
        AttackPlayer();
    }
}

So as an example, I've got a "PirateShip" asset of type EnemyData , whose enemyAI field points to a "PirateShipAI" asset of type PirateShipAI .举个例子,我有一个 EnemyData 类型的“ EnemyData ”资产,其敌人AI 字段指向 PirateShipAI 类型的“ PirateShipAI ”资产。

But this feels wrong, every time I code up a new enemy's AI I have to also instantiate an asset just so it can be referenced by an EnemyData .但这感觉不对,每次我编写一个新敌人的 AI 时,我都必须实例化一个资产,以便它可以被EnemyData引用。 I feel like EnemyAIBase shouldn't even be an SO, it's not like it has any variables that different assets will override.我觉得EnemyAIBase甚至不应该是一个 SO,它不像它有任何变量会被不同的资产覆盖。 There will be a 1-to-1 mapping between EnemyData assets and custom AI for that enemy. EnemyData资产和该敌人的自定义 AI 之间将存在一对一的映射。 So this SO is just a container for some logic, which doesn't feel right.所以这个 SO 只是一些逻辑的容器,感觉不对。 But I don't know any other way to reference that logic in my EnemyData SO.但我不知道在我的EnemyData SO 中引用该逻辑的任何其他方式。

I guess I wish an SO could reference a C# class directly, but I don't think this is possible.我想我希望 SO 可以直接引用 C# class ,但我认为这是不可能的。

One option is that I could build an Editor that hides the EnemyAI asset as a sub-asset of the EnemyData asset, kinda like I did over here: Building an Editor for nested ScriptableObjects to compose abilities in a card game一种选择是我可以构建一个编辑器,将EnemyData资产隐藏为EnemyAI资产的子资产,就像我在这里所做的那样: 为嵌套的 ScriptableObjects 构建一个编辑器以在纸牌游戏中组合能力

But that feels really wrong here, because I don't intend to make any of this AI generic.但这感觉真的不对,因为我不打算让任何这种人工智能通用。

How can I attach behavior/logic to a ScriptableObject?如何将行为/逻辑附加到 ScriptableObject?

You can indeed simply make it not a ScriptableObject .您确实可以简单地使其不是ScriptableObject To define different behaviors I would use a generic here:要定义不同的行为,我会在这里使用泛型

public abstract class EnemyData<T> : ScriptableObject where T : EnemyAIBase
{
    public int health;
    public T enemyAI;
}

public abstract class EnemyAIBase
{
    public abstract void PlayTurn(Enemy thisEnemy);
}

And then from these create your actual implementations然后从这些创建您的实际实现

[CreateAssetMenu]
public class PirateShip : EnemyData<PirateShipAI>{ }

public class PirateShipAI : EnemyAIBase
{
    public override void PlayTurn(Enemy thisEnemy)
    {
        thisEnemy.Heal();
        AttackPlayer();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM