Unity3D中包含ScriptableObjects的复杂数据结构

yhived7q  于 2022-12-27  发布在  其他
关注(0)|答案(1)|浏览(198)

我正在尝试创建一个如图所示的structure数据库,在那里我可以轻松地添加和删除奖励类型。这是一个类似于盗贼的升级系统,基本上我想从一个特定的稀有物品中为一个特定的角色(如战士或 Mage )获得奖励。
我对Lua比Unity更有经验,在Lua语言中,它看起来像这样,

`{
    ["Melee"] = 
    
    {
        [1] = {
            [1] = {"Stat", "Strength", 10},
            [2] = {"Ability", "Swirl", 1},
            
        },
        
        [2] = {
            [1] = {"Stat", "Strength", 50},
            [2] = {"Stat", "PhysicalDefense", 10},
        },
    },
    
    ["Healer"] = 
        {
        [1] = {
            [1] = {"Stat", "MagicalAttack", 5},
            [2] = {"Ability", "Regeneration", 1},
        },

        [2] = {

            [1] = {"Stat", "MagicalDefense", 15},
            [2] = {"Ability", "Regeneration", 1},
        },
    },
}`

那么为了得到一个特定的奖励,我会做reward = ["Melee][1][1]。然而,在Unity中,使用字典会禁用scriptableobject在编辑器中添加元素的功能。那么我如何创建一个scriptableobject,以便在编辑器中添加具有相同结构的元素呢?

lstz6jyr

lstz6jyr1#

您不需要字典来按索引访问项目。
只需使用普通数组或List并执行以下操作

public class Warrior : ScriptableObject
{
    public Rarity[] rarities;
}

public class Rarity : ScriptableObject 
{
    public Reward[] rewards;
}

public class Reward : ScriptableObject
{
    public enum RewardType { Stat, Ability }

    public RewardType type;
    public int value;
}

最后在

public Warrior[] warriors;

然后如果第一级确实需要,你仍然可以在运行时设置一个字典,比如。

public Dictionary<string, Warrior> Warriors = new ();

private void Start ()
{
    foreach(var warrior in warriors)
    {
        Warriors.Add(warrior.name, warrior);
    }
}

然后您可以访问其余部分,例如:

var reward = Warriors["Melee"].rarities [0].rewards[1];
Debug.Log($"{reward.type} - {reward.name} - {reward.value}");

请记住,在c#中,索引是从0开始的
然而,如果你更熟悉你的方式,更喜欢一般的字典方法,你完全可以这样做!
您可以简单地将其编写为JSON,然后在各种JSON库中进行选择,将其再次转换为字典。

{
    "Melee" : [
        [ 
            {
                "type":"Stat", 
                "name":"Strength", 
                "value":10
            },
            {
                "type":"Ability", 
                "name":"Swirl",
                "value":1
            }            
        ],
        ...
    ],
    "Healer" : ...
}

那么您将不使用ScriptableObject,而只使用例如

[Serializable]
public class Reward
{
    public enum RewardType { Stat, Ability }

    public RewardType type;
    public int value;
    public string name;
}

然后将其解串为例如

var Warriors = JsonConvert.DeserializeObject<Dictionary<string, Reward[][]>>(theJsonString);
var reward = Warriors["Melee"][0][0];
Debug.Log($"{reward.type} - {reward.name} - {reward.value}");

其中theJsonString可以从文件或web请求等读取
本例使用Newtonsoft JSON.Net,Unity可通过软件包管理器使用该软件包。
就我个人而言,我宁愿使用显式命名的字段和类,而不是像以前那样使用锯齿状数组

{
    "Melee" : {
        "rarities" : [
            {
                "rewards" : [ 
                    {
                        "type":"Stat", 
                        "name":"Strength", 
                        "value":10
                    },
                    {
                        "type":"Ability", 
                        "name":"Swirl",
                        "value":1
                    }  
                 ]
            } 
        ]
    },

    "Healer" : ...
}

相关问题