目录
步骤
一、项目准备
- 新建一个项目,使用第一人称游戏模板,勾选初学者内容包

- 新建一个蓝图类,父类选择"Actor组件"

这里命名为"Component_InventorySystem",表示库存系统组件

打开"Component_InventorySystem",添加两个函数。这里分别命名为"AddToInvertory"、"RemoveFromInventory"。分别表示"将物体添加到库存中"和"将物品从库存中移除"

添加一个整数类型变量,这里命名为"InventorySize",表示库存容量大小

- 我们还需要设置存储的内容,因此还需要添加一个数组变量。但是数组元素还没有定义,因此我们先创建一个结构,这里命名为"Struct_InventorySlot"

打开"Struct_InventorySlot",添加两个变量如下,命名为"ItemID"、"Quantity",分别表示物品ID、同类型物体的数量。

- 回到"Component_InventorySystem"中,添加一个变量,命名为"Content",表示库存的内容

变量类型设置为"Struct_InventorySlot"的数组形式。"复制"一项设置为"Replicated",表示当服务器改变了变量"Content"的值时,在所有客户端中组件"Component_InventorySystem"中的 "Content"的值也会跟着改变,但是必须在服务端来改变该值才行。

在组件的类默认值中,勾选"组件复制",这样组件就能适配多人游戏

二、制作数据表
数据表的作用是用于储存游戏中可被收纳到背包中的物品。
- 我们先打开第一人称角色蓝图"BP_FirstPersonCharacter"

添加上一步创建的组件"Component_InventorySystem"

设置"InventorySize"为16,表示角色背包有16个格子。"Content"一般通过其他程序设置,这里先空着。

- 新增一个结构,这里命名为"Struct_Item"

打开"Struct_Item",表示库存单位的一些属性。添加如下变量:
"Name"表示库存单位的名称;
"Description"表示库存单位的描述;
"Thumbnail"表示库存单位的外观缩略图;
"ItemClass"的作用是表示库存属于哪一种Actor;
"StackSize"表示一个格子最多可以放多少种同类的物品。

- 创建数据表格

行结构选择我们刚创建的"Struct_Item"

这里命名数据表格为"DataTable_Item",该数据表中将要存储的是背包中所有物品的具体信息。

目前数据表还是空的,等待后续添加数据。

三、与场景物体交互
- 在项目设置中新建一个检测通道,通道命名为"Interactive",默认响应为"忽略"

- 打开"Component_InventorySystem",添加一个函数,这里命名为"InteractrionTrace"

我们主要通过"按通道进行球体追踪"这个节点实现交互,该节点原理是一个球体从起点出发到终点然后将路线上碰到的第一个物体的碰撞信息返回,通过这种方式我们可以实现与场景中的物体交互。

完善函数逻辑如下,表示从摄像机的位置作为起点,沿着摄像机朝向向前走"InteractionRange"长度到达终点,对这一段路径上进行球体追踪,并且忽略组件"Component_InventorySystem"的拥有者自身的碰撞。

为了测试,我们可以在事件图表中设置通过T键调用函数"InteractrionTrace"

此时运行可以看到场景中多了如下一段圆柱,这就是球体追踪的路径。

向场景中添加一个方块,碰撞预设为Custom,碰撞响应中,Interactive设置为阻挡。

此时运行可以看到当追踪到方块时会显示绿色。

下面继续完善交互函数如下,当追踪到物体后再次判断追踪到的是否是同一个物体,如果不是同一个物体就将变量"Look at Actor"设置为追踪到的物体。

在事件图表中修改为每帧调用"Interaction Trace"

此时运行可以发现如果一直观察白方块也只打印一次"cube",而当玩家观察别的地方后再观察白方块则再次打印"cube"

- 当然,当追踪到物体后肯定不是打印这么简单,因此先删除打印节点,再添加一个蓝图接口,这里命名为"Interface_Interact"

打开"Interface_Interact",添加两个接口函数,分别命名为"LookAt"和"InteractWith"

"LookAt"函数添加一个文本类型的输出

- 回到组件"Component_InventorySystem"中,添加对接口函数的调用,这样当玩家看向一个Actor后,实现了接口"Interface_Interact"的Actor就会触发接口事件。

五、制作可交互的物品
- 新建一个父类为Actor的蓝图类,这里命名为"BP_TestItem"

打开"BP_TestItem",在类设置中实现接口"Interface_Interact"

双击左下角接口函数"Look At"来实现

这里先设置输出一句话

添加一个立方体组件

立方体的碰撞预设为custom,碰撞响应"Interactive"为阻挡

- 将"BP_TestItem"拖入场景中

此时运行可以看到当玩家看向"BP_TestItem",就会执行"LookAt"接口函数。

- 下面我们需要将这个可交互的物品与数据表挂钩。新建一个Actor组件,这里命名为"Commpent_ItemData"

打开"Commpent_ItemData",添加两个变量,分别命名为"ItemID"、"Quantity"

设置默认值
- 打开数据表"DataTable_Item",添加一行数据

- 回到蓝图"BP_TestItem",添加刚创建的组件"Commpent_ItemData"

设置组件的默认值

完善接口函数逻辑如下,当接口函数"LookAt"被调用后,就会根据设置的类默认值"ItemID"查询数据表中该物体的其它信息,然后打印出来。

此时运行可以看到当玩家看向可交互物品"BP_TestItem"时,就会打印"我是方块信息"
参考视频: