虚幻背包系统制作教程-2

8,460 阅读4分钟

OK,和之前项目组的同事领导恰过晚饭(可惜木有喝酒,写的不给劲),开始写第二期,这一期实现的是背包系统的核心,背包本身!

思路

首先还是对整体的数据结构进行分析

上一期说明了背包是由一个个插槽Slot组成的,而插槽中持有物品实例,但是这就带来一个问题,插槽如何和外界沟通?Slot作为structure没法在蓝图中使用指针,而如果直接拷贝,又过于庞大和消耗

参照GAS中的做法,我们通过一个中间的数据结构SlotHandle作为钥匙去访问背包中的Slot

有了钥匙和储物柜,那么接下来还需要实现将物品放入储物柜,取出储物柜,通过钥匙获取储物柜的物品等功能,换句话说就是增删查改,相信各位都是老司机了,一定比我写的要好。

有了整体的思路,代码的实现不过是时间的消耗而已,接下来就开始实现。

代码实现

InventoryItemSlot

插槽Slot

ItemSlotFilter和SlotTags可以忽略,这是之后实现的功能,用于定义插槽的类别以及插槽存放物品的要求。

插槽重要的数据为:

  1. ItemInstance指针,指向物品实例。
  2. SlotId为插槽的编号,一个背包内每个插槽的Id都是唯一的。
  3. Owner为持有插槽的Inventory Component的指针,即持有插槽的背包。

InventoryItemSlotArray

存放插槽的数组

Arc Inventory和GAS中处理Spec结构体都采用了类似的写法,应该是为了网络同步,我对此了解的还不够深入,就不发表看法了,照着学就完事

InventoryItemSlotHandle

插槽的钥匙

重要的数据为SlotId,钥匙和它对应的柜子Id应该是一致的。这是用于根据Handle寻找对应的Slot的索引!

构造函数

equal和not equal的实现。目前其它的部分都可以忽略,核心的是判断SlotId是否一致!

InventoryComponent

首先给背包添加的数据为:插槽数组和钥匙数组

插槽Id生成器,背包每生成一次插槽,计数器+1,确保所有插槽的Id都不相同

下一步需要创建几个工具函数

IsValidItemSlot

用于判断SlotHandle-插槽钥匙是否有效

GetItemSlot

输入SlotHandle,获取对应的Slot。根据钥匙,找到对应的柜子。

方法也很简单,遍历柜子,一个个对一遍Id,如果编号一样,就说明找到了对应的柜子

创建和移除插槽

PostInventoryUpdate函数会在当背包系统插槽发生变化调用,比如新增或移除插槽

PopulateSlotReferenceArray用于对插槽重新排序

CreateInventorySlot

忽视SlotTags和Filter,目前没有作用

创建插槽的代码很简单,就算创建插槽的结构体然后添加到插槽数组当中,然后计数器+1,确保所有插槽的Id都不相同,然后调用背包更新函数

RemoveInventorySlot

移除插槽

PostInventoryUpdate

首先清空存放钥匙的数组,然后重新生成

PopulateSlotReferenceArray

按照当前的插槽重新生成钥匙数组

增删查改

接下来实现的传统艺能,增删查改。有一些代码我就不贴了,大致理解思路自己实现即可。

增加物品

LootItem函数的作用是找到背包中第一个空的插槽,调用PlaceItemIntoSlot将物品实例放入插槽

AcceptsItem函数的功能为判断指定的插槽Item Instance指针是否为空,如果为空则返回true,说明可以放入新的物品

PlaceItemIntoSlot函数的作用为,将物品放入指定的插槽当中

首先通过钥匙获取对应的Slot,然后通过代码Slot.ItemInstance=Item将物品存入Slot中

OnInventoryUpdate和OnItemSlotUpdate为背包内物品发生变化的消息委托,在这一期可以忽略

移除物品

移除指定插槽的物品

移除所有物品

查找物品

GetAllSlotHandles返回当前背包所有的插槽钥匙

GetItemInstanceInSlot获取指定插槽内存放的物品

蓝图测试

随便找一个actor,添加刚才实现的Inventory Component

然后在beginplay中添加以下代码。

  1. 创建物品instance
  2. 将instance通过LootItem函数放入背包中,因为当前背包都为空,所以会放到第一个插槽内
  3. 获取当前背包所有的插槽钥匙,然后获取第一个插槽的钥匙
  4. 获取第一个插槽内的物品
  5. 可以看到物品实例成功的放入插槽内了

这一块只是简单的实现了往背包内塞入物品的功能,下一期会正式的说明如何生成一件装备,并且让他成功的修改角色的属性。