添加一把 bank 的完整流程:

1. 创建Attribute

创建一个空类vp_InventoryItemsAttribute : PropertyAttribute,继承自PropertyAttribute代表实现一个叫vp_InventoryItems的Attribute(编译器扩展的一个属性)

所以现在我们能够在一个脚本中通过 [ InventoryItems ] 来调用我们自己实现的编译器扩展属性,但是这个Attribute目前没有实现任何绘制逻辑,因为我们没实现它的PropertyDrawer对象

2. 实现Drawer

实现vp_InventoryItems(Attribute)的PropertyDrawer,实现绘制的逻辑

[CustomPropertyDrawer(typeof(vp_InventoryItemsAttribute))]

public class vp_InventoryItemsDrawer : PropertyDrawer

在这个类中我们就要实现绘制的逻辑了,因为我们目的是绘制背包inventory的面板,所以我们通过

OnGUI(Rect pos, SerializedProperty prop, GUIContent label)

这个prop属性是我们调用这个编译器扩展Attribute的属性。

比如:在vp_Inventory类中

[vp_InventoryItems]

public float itemList; 那么在这里我们的prop就是这个itemList对象,所以我们能通过

vp_Inventoryinventory=((vp_Inventory)prop.serializedObkect.targetObject)

通过这个属性对象来找到他的脚本物体,也就是inventory对象。

 

3. 实现OnGUI

在这里我们实现

(1).绘制所有内部的bank实例

                   1. bank实例中封装的bank对象的名称(对应的asset文件名,并加上''internal '')

                   2.这个bank对象的图标(存在于item对象中)

                   3.绘制这个bank实例的unit数量(内部bank的id无意义)

                   4.绘制一个×,用于移除这个bank实例

 

(2).绘制背包中的所有外部bank实例集合

                            1. bank实例中封装的bank对象的名称(对应的asset文件名)

                            2.这个bank对象的图标(存在于item对象中)

                            3.绘制这个bank实例的unit数量及它的id的值

                            4.绘制一个×,用于移除这个bank实例

(3).绘制背包中所有item实例集合

                                     1. item实例中封装的item对象的名称(对应的asset文件名)

                                     2.这个item对象的图标

                                     3.绘制这个item实例的id的值

                                     4.绘制一个×,用于移除这个bank实例

(4).绘制一个框,用于拖拽添加新的item对象进背包

                             1. 调用inventory.TryGiveItem方法

 

(5). 创建一个item对象,用asset文件保存

现在我们知道item对象是联系背包的基础,item对象是item类的实例化,我们可以通过MFPS菜单来直接创建一个item对象,这个item对象以asset文件的形式存在,直接生成在我们unity文件下,我们来看看其中的流程

                   1. UFPSMenu类:设置菜单,类中有这么一个方法

[MenuItem("UFPS/Wizards/Create Item Type/Item", false, 101)]

public static void CreateItemTypeVpItemType()

    vp_ItemType asset =   

    (vp_ItemType)vp_EditorUtility.CreateAsset("UFPS/Base/Content/ItemTypes" ,typeof(

  vp_ItemType) );  

}

                 2. CreateAsset方法:(最主要的2行)

//创建一个item对象

Object asset = ScriptableObject.CreateInstance(type); 

//将 item 对象序列化,并用一个Asset文件保存

AssetDatabase.CreateAsset(asset, "Assets/" + fileName + ".asset");

        3. 再来看Item类:

[System.Serializable]

vp_ItemType : ScriptableObject

                   首先,你要保存item对象,那肯定要序列化吧,能序列化才能把一个对象变成一串二进制流数据,然后,你想将这串二进制数据保存到asset文件中,所以item类必须继承

ScriptableObject类,unity才能把序列化后的数据写入到asset文件中

                   4. 修改item对象的字段值

           我们现在在文件夹下有一个以asset文件存在的item对象,既然这是一个对象,那么我们就能够对他的字段的值进行赋值与更改,(就好比你把一个脚本类拖拽到游戏物体上,这个脚本就变成了对象,你就可以在编辑器上对脚本中的各字段进行更改与赋值),同理的,我们也能在右边编辑器面板上对这个asset文件进行编辑,自己修改其中各字段的值(具体的实现通过item的编辑器扩展)

 

(6). 将这个item对象(asset文件)添加到背包

      1. 将asset文件拖拽到我们的inventory的添加框中,unity会自动识别这个asset文件成一个item对象(解析?)并作为参数传入,然后背包调用inventory.TryGiveItem方法,将这个item对象封装成一个item实例(就多了一个id,id默认为0,表示不使用),然后将这个item实例添加进背包的ItemInstances集合中

           2. 容量限制:

实现一个vp_InventoryCapsAttribute和vp_InventoryCapsDrawer

                            1.绘制一个框,连接cap功能是否启用

                            2.绘制背包内所有的ItemCap对象(在item对象上加一个cap) 

                                               1.item对象名+ item类型(item,bank,unit)

                                               2.点击自动找到引用的item对象(asset文件)

                                               3.绘制一个cap字段和输入框,更改ItemCap的容量cap

                            3.绘制一个拖拽框

                                            当我们将一个item对象(asset文件),拖拽到它上面,调用   inventory.SetItemCap,(如果没有ItemCap)创建一个新的ItemCap对象,这个ItemCap对象的item对象引用直接指向我们的asset文件(item对象),然后设置默认的cap,我们直接通过面板属性调整cap的值即可(PS:如果我们再次拖拽这个item,因为我们背包中已经有这个item对象的itemCap了,只需要调整后面的cap值即可,所以弹出一个提示框)

            3. 背包空间限制:

原理同上,这个就比较简单了,每个item对象都有space属性(默认为0),我们绘制一个space的输入框,修改背包的空间,然后绘制一个进度条,表示背包空间的使用量

            4. 再次添加:

当我们再次将我们的asset文件(item对象)拖拽到添加框中,我们先检查空间space是否足够,然后进行cap的检查,找到我们的itemCap对象,获取容量限制,然后获取我们背包中这个item的数量,比较,最后添加

 

 

(3)比方:

bank对象)

                            我们手上的asset文件(bank对象)代表:榴弹枪,我们设置榴弹枪的容量,10发,设置榴弹枪的子弹:火焰弹(也是一个unit对象),这种枪允许重装子弹,不会子弹没了就消失,ok,配置完榴弹枪了

bankInstance)

TryGiveUnitBank(unitBankType, unitBankType.Capacity, id),ok现在我们就成功向背包添加了一把榴弹枪了,这把枪当前的子弹为10(最大容量)