用C++搭建基本物品栏系统(附项目源代码)
在这部分中我会介绍如何建立一个基础物品栏系统,可以从玩家物品栏中拾起、选择、扔掉物品。请注意本教程是基于C++第一部分教程编写的,一些名字或者节点可能会与使用蓝图的第一部分教程略有不同,但是基本概念是相同的。
建立一个物品栏系统的难度不是初学者级别。你需要对蓝图和虚幻编辑器有基本的知识了解。为了保持教程的合理大小我不会深挖每一处节点,不过你当然可以在评论中询问任何问题!
概念
基于部分一中UsableActor的C++类,我们通过在角色(character)的物品栏中生成一个蓝图实例并将物品从游戏中移除来响应OnUsed事件(教程中的“E”键)。当丢掉一个物品时(教程中的“F”键), 我们将物体生成回游戏中。我将物品栏和世界中物体分为两个蓝图,这需要两者间的“映射”。这个“映射”可能对大项目不适合,未来我打算制作更先进的物品栏系统(使用数据表)来解决这个问题。
小编是一个有着6年工作经验的工程师,关于C++编程,自己有做材料的整合,一个完整的C++编程学习路线,学习资料和工具,能够进我的群10048,-83029收取,免费送给大家,希望你也能凭着自己的努力,成为下一个优秀的程序员
准备
首先我们创立蓝图以便我们统一实现功能。
创立一个基于UsableActor的新蓝图,命名为“BP_PickupActor”。这个actor在世界中可视,它回应OnUsed事件。
创立一个基于Actor的蓝图,命名为“BP_InventoryActor”。这个actor存储类似显示名称的物品信息,物品重量和物品预览图的信息。
输入映射
将以下输入映射添加到你的项目。被映射的动作可以在蓝图中找到(我们会在角色蓝图中实现这些。)
BP_PickupActor
该蓝图存在于游戏世界中,可以被玩家捡起。
创建一个Actor类型的新变量“InventoryClass”。该变量存储的类,是在该物品被玩家捡起来时创建的。在创建变量后,编译蓝图并将BP_InventoryActor设置为默认值。
OnUsed事件处理玩家在物品旁边摁E键时的反应。注意“AddItem”是角色中的一个待建立函数,我们会在之后的教程说明。如下图所示, 我的角色类的名字为BP_BasicInventoryCharacter,你可以将cast替换为你的角色类的名字(存储你物品的那个)。
小提示:如果你对CastTo节点有问题,可以从你想要转换的针脚/变量出引出一条线。
开始聚焦/结束聚焦事件改变静态网格物体中的“Render Custom Depth”。如果开启,物体会被画入到具有特定深度的渲染目标,我们自定义的后处理使用该目标画出物品轮廓。关于更多的自定义深度的信息,点击这里。
接下来我们设置该actor的默认值。开启“Simulate Physics(物理模拟)”是可选的,根据你的游戏而定。如果你不开启物理模拟,也许在后面的教程中你需要调整你的丢弃函数,让它向地板做一个跟踪以找到合适的物品掉落地点,而不是让它直接坠落地面。
BP_InventoryActor
该蓝图存储物品的特定信息,例如HUD中的显示名称,掉落时应该产生的类等。
变量
- DisplayName(类型:text)
- PickupClass(类型:Actor类)
编译该蓝图,将BP_PickupActor设置为PickupClass的默认值,然后为DisplayName设置一个名称,否则它将不会出现在你的HUD中。
再编译一次,这张蓝图就完成了。
角色
角色拥有物品栏数组,处理捡起/掉落的逻辑。
添加以下变量:
- InventoryItems(类型:BP_InventoryActor)点击类型旁的格状图标使之成为数组
- SelectedItem(类型:int)
你可以设置它的分类为“Inventory”,这样一目了然。
角色函数:SetSelectedItemIndex
建立一个输入参数为整形的新函数,将输入参数改名为“NewIndex”(查看图片)。该函数将选中物体的索引限定在0到物品栏的物品总数之间。该函数在你将物品栏的物品扔回游戏世界后会被调用。
角色函数:AddItem
创建一个名为“AddItem”的新函数。进入到函数中选择“Add Item”节点,我们需要加入一个类型为“Actor”类的新输入参数“InventoryClass”。还记得BP_PickupActor蓝图调用该函数吗?现在可以更新那个函数了。
接下来如下图所示实现该函数的逻辑。
我们生成一个新的物品栏actor,然后将它加入到玩家的物品栏。MakeTransform节点只需默认值即可,因为物品栏物品在世界中本身不可见(我们可以选择更基础的类,例如Object或者使用不含位置变量的结构体,为了简洁我选择使用actor)。
小提示:想要转换“SpawnActor”的返回值你必须从返回值处拉出一条线并确认“Context Sensitive”处于开启状态。否则“Cast To X”节点不会出现!
角色函数:DropItem
创建一个名为“DropItem”的新函数。该函数得到选定物体的索引,在游戏世界中玩家面前生成一个actor(如果物品栏中有任何物体)。在物体生成后我们移除物品栏的物品。
事件图表(根)
在角色事件图表中我们实现DropSelectedItem事件(之前我们在输入设置中映射过该事件)。我们只需调用DropItem函数然后更新选中物体的索引,这样如果需要的话可以移除物品栏的最后一个物品。
剩下的两个事件实现鼠标滚轮上下翻动物品栏。索引被限定不能超出物品总数量的范围。
BP_HUD
HUD画出了目前物品栏中的物品。选中的物体会画得稍大一些。
变量
添加两个浮点型变量InventorySpacingY和InventoryLocationY。编译蓝图设置它们的默认值:
事件图表
以上蓝图看上去像这样,选中的物品会稍大些
BP_GameMode
创建一个新游戏模式或者升级现有游戏模式蓝图。确认它使用BP_HUD。
点击Window->World Settings确认正确设置关卡的游戏模式。
物品高亮的后处理
选择关卡(使用全局后处理体积“Global PostProcess”的默认地图)的主要后处理体积或者新建一个新体积。
确认选择Unbound使得该体积对任何位置的玩家都有效果。在Blendable数组中选择引擎自带的PP_OutlineCustomDepth材料。
完成了!
现在你可以试试你的物品栏系统了。
创建额外的物品
如果你想要创建例如武器的额外物品,你需要创建BP_InventoryItem和BP_PickupItem的子蓝图。在你的新蓝图中更新它们的默认值并分配一个新模型。
正如在教程开始提到的那样,一个更先进的系统可以使用DataTables。
问题解决
- 确认你设置了所有的默认值(DisplayName和InventoryClass/PickupClass变量)
- 检查你的输入映射是否分配了所有的按键(E,F,滚轮上下)
- 检查是否使用了正确的游戏模式以及HUD的设置。
- 如果你的物体下落时穿过地板了,检查它们的碰撞体积是否正确设置。
如何使用“Cast To”节点
源代码可以在GitHub上找到。