Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity中的项目生成系统-如何在脚本实例化后保留可编写脚本的对象编辑功能_C#_Unity3d_Save_Decorator_Wrapper - Fatal编程技术网

C# Unity中的项目生成系统-如何在脚本实例化后保留可编写脚本的对象编辑功能

C# Unity中的项目生成系统-如何在脚本实例化后保留可编写脚本的对象编辑功能,c#,unity3d,save,decorator,wrapper,C#,Unity3d,Save,Decorator,Wrapper,我目前正在开发一款游戏,我的设计遇到了一些问题。即我的物品和能力系统 我从使用继承开始向我的项目添加功能,比如说拥有一个Item基类,并从中继承ConsumableItem和设备。但后来我开始想要那些既有消耗品又有设备的东西(比如一组箭头)。因为我使用Unity 3D和C#我不能从多个类继承,而且我读到它可能会导致问题 我听说了接口,它可以解决我的问题,但仍然需要我手工硬编码每个属性组合 我开始阅读有关设计模式的书籍,想知道是否可以使用装饰器模式来组合属性和方法,在编辑器中创建自定义对象 我希望

我目前正在开发一款游戏,我的设计遇到了一些问题。即我的物品和能力系统

我从使用继承开始向我的项目添加功能,比如说拥有一个
Item
基类,并从中继承
ConsumableItem
设备。但后来我开始想要那些既有消耗品又有设备的东西(比如一组箭头)。因为我使用Unity 3D和C#我不能从多个类继承,而且我读到它可能会导致问题

我听说了接口,它可以解决我的问题,但仍然需要我手工硬编码每个属性组合

我开始阅读有关设计模式的书籍,想知道是否可以使用装饰器模式来组合属性和方法,在编辑器中创建自定义对象

我希望能够创建一个基本的
ItemBlueprint
类,该类可以将一系列功能作为
enum
值。然后,我将该
ItemBlueprint
对象传递给另一个类,该类将有一个名为
Build
的方法,并通过将所有相关属性和方法添加到
item
对象来构建该项。然后,输出产品可以作为组件添加到游戏对象上的场景中,或者作为脚本对象直接保存到资源中。然后我就可以手动编辑公共字段了

到目前为止,我已经能够使用下面的代码生成项目。但是,unity inspector中显示的唯一字段是与上次应用的装饰符相对应的属性字段。因此,当
说明设置为blueprint Characteristics数组中的最后一个条目时,我无法修改
说明
,但不能修改
设备插槽
属性

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class ItemBuilder : MonoBehaviour {
    public ItemBluePrint bp;

    private List<Decorator> items;

    public void OnValidate()
    {
        items = new List<Decorator>();
    }

    [ContextMenu("Build Item")]
    public void Build ()
    {
        // Create Item and Decorators
        DiscreteItem newItem = ScriptableObject.CreateInstance<DiscreteItem>();

        for (int i = 0; i < bp.properties.Length; i++) {
            if (i == (int) ItemProperties.Consumable) {
                items.Add(ScriptableObject.CreateInstance<ConsumableItem>());
            }
            if (i == (int) ItemProperties.Equipable) {
                items.Add(ScriptableObject.CreateInstance<EquipableItem>());
            }
        }

        // Link decorators
        Item previousItem = (Item) newItem;
        for (int i = 0; i < items.Count; i++) {
            items [i].SetItem (previousItem);
            previousItem = (Item) items [i];
        }

        AssetDatabase.CreateAsset (previousItem, "Assets/MynewItem.asset");
        Debug.Log ("Item created !");
    }

    abstract class Item : ScriptableObject
    {
        public abstract void Operation();
    }

    class DiscreteItem : Item
    {
        public override void Operation()
        {
            Debug.Log("Use item.");
        }
    }

    abstract class Decorator : Item
    {
        protected Item item;

        public void SetItem(Item item)
        {
            this.item = item;
        }

        public override void Operation()
        {
            if (item != null)
            {
                item.Operation();
            }
        }
    }

    class ConsumableItem : Decorator
    {
        public string description;

        public override void Operation()
        {
            base.Operation();
            Debug.Log("I consume the item.");
        }
    }

    class EquipableItem : Decorator
    {
        public int equipementSlot;

        public override void Operation()
        {
            base.Operation();
            AddedBehavior();
            Debug.Log("I equip the item.");
        }

        void AddedBehavior()
        {
            Debug.Log("I added the item to my equipment.");
        }
    }
}

你应该:给出一个真实的例子,说明你想如何使用它,以及你遇到的问题。(你的问题标题没有反映内容)这实际上是我想要实现的目标,除了我有比消耗品和装备更多的特点。我将编辑标题。你说的是标题中的编辑,但问题中没有提到,在inspector中你的意思是??是的,从
AssetDatabase.CreateAsset
调用创建的scriptableobject在Unity编辑器中是不可编辑的。这就是为什么接口很棒的原因。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum ItemProperties
{
    Consumable = 0,
    Equipable = 1,
}

[CreateAssetMenu(fileName= "Item", menuName="Item")]
public class ItemBluePrint : ScriptableObject {
    public ItemProperties[] properties;
}