ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

虚幻引擎-设计场景物体哲学-C++

2026/8/5 21:44:46 拓冰建站 浏览量
虚幻引擎-设计场景物体哲学-C++ 前言:我们将要学会如何在C中设计一些特殊的游戏场景道具,这些场景道具具有特殊的游戏特性,要想设计这些场景道具,必须深刻明白Actor和Component和蓝图以及蓝图实例的概念:Actor:例子1和例子2都是Actor例子1:我们可以制造一个锁(Lock),激活它可以开门或者关门,在激活之前它不可见,激活后可见;例子2:设计一个物体(MovePlatform),可控制其 三维移动, 速度, 方向, 最远距离, 旋转, 等等Component:AActor物体调用组件Component的方式有多种:1.直接写一个AActor类,然后在类中引用组件的头文件,然后在里面声明或者定义组件2.创建一个蓝图,然后在蓝图里,调用建模,调用组件,把组件绑定进去,然后就可以直接使用了例子3的Mover就可以被某个Actor调用,只要包含了其头文件Mover.h就行.例子3:设计一个组件(Mover),用这个组件来控制物体的三维移动蓝图:1. UE 的可视化编程工具,类的元素的初始化可以在成员变量声明时, 构造函数中, 蓝图中,BeginPlay()中,而且覆盖层级递增(BeginPlay()是运行时初始化不涉及编译期默认值覆盖).写游戏逻辑的C程序员会把类写好,然后把所有代码层面的东西打包到蓝图里,只暴露出接口方便美术师使用,这样美术也可以自己修改蓝图的内容生成各种各样的蓝图实例,而无需去修改源代码.2. 蓝图是单继承的,只能继承一个Actor或者继承一个Component,但是蓝图可以继承一个Actor但是挂载多个Component,这样可以使用多个功能(这个过程也可以在Actor类的C代码中实现,且效果可能会更好,因为Actor的函数可以直接访问组件的元素), 这种语法叫做组合(composition)3. 大多数情况下C类想要被场景道具使用, 需要被加载入蓝图,然后实例化蓝图创建场景实体蓝图实例:蓝图和蓝图实例的关系就像:类和对象的关系,蓝图实例是蓝图的 “具体化产物”,通过修改蓝图内暴露的参数可以创造出各种各样的蓝图实例.蓝图的本质披着外衣的 C 类C 是代码蓝图Blueprint是编辑器里的资产表面上看确实是“两个维度的东西”。但实际上在虚幻引擎的眼里它们本质上是同一个东西它们都是“类Class”。当你创建一个蓝图 WBP_HUD 时第一步是什么系统会问你“Parent Class父类是谁”你选了UHUDWidget你写的那个 C 类。这一刻血缘关系就建立了C 类 (UHUDWidget)是父亲。蓝图 (WBP_HUD)是儿子。关键点来了当你点击蓝图编辑器左上角的“编译 (Compile)”按钮时虚幻引擎在后台做了一件惊天动地的事它把你的蓝图节点、设置的属性转换编译成了一个真正的类在内存中表现为 UClass 对象。所以在引擎的内存看来C 写出来的类 一个 UClass。蓝图编译出来的类 也是一个 UClass。它们在“维度”上是完全平级的。1.如何创建一个可拾取的物品蓝图思路:给物体添加一个标签,拾取动作可以通过判定其标签,确定是否可以拾取,如果没有此标签的物体是无法被拾取的.第一步: 在C类中新建C类第二步; 选择Actor父类, 取名为:CollectableItem第三步: 在头文件中声明成员变量,并且在cpp文件中的构造函数中为自己添加标签之后的拾取动作可以通过判定其标签,确定是否可以拾取,如果没有此标签的物体是无法被拾取的.//CollectableItem.h public: UPROPERTY(EditAnywhere) FString ItemName; --------------------------------------------------- //CollectableItem.cpp ACollectableItem::ACollectableItem() { PrimaryActorTick.bCanEverTick true; Tags.Add(CollectabelItem); }第四步:在存放自己东西的文件夹中,添加一个蓝图,取名为:BP_GlassStatue,继承CollectableItem类第五步:进入蓝图后添加一个mesh,并且取名为GlassStatue2.创建一个锁角色类:假设我们需要用一个玻璃雕像放在一个底座上开启一个门,那么我们可以把玻璃雕像GlassStatue理解成一把钥匙key,为了方便管理,我们在建模时把底座也加入我们的锁蓝图,这样放置时会很方便.第一步: 在C类文件中添加一个类,继承自Actor,然后取名为Lock第二步: 在构造函数中添加标签第三步: 导入Lock所需的相关组件的头文件, 并且声明相关的指针, 然后在构造函数中初始这些指针这样就可以在代码中把外部组件添加到我们自己的组件,而不需要在蓝图中手动添加(而且蓝图中添加组件是无法在函数中访问的).#includeTriggerComponent.h #includeComponents/StaticMeshComponent.h //头文件务必在#include Lock.generated.h的上面!!! UPROPERTY(VisibleAnywhere) USceneComponent* RootComp;//场景组件,也是根组件,其他组件挂在这上面 UPROPERTY(VisibleAnywhere) UTriggerComponent* TriggerComp;//触发器组件 UPROPERTY(VisibleAnywhere)//指向静态网格体的指针 UStaticMeshComponent* KeyItemMesh;//钥匙模型//设置构造函数,初始化所需的组件 ALock::ALock() { PrimaryActorTick.bCanEverTick true; Tags.Add(Lock); //指针 创建一个名为TEXT(Root Comp),类型为USceneComponent的组件 RootComp CreateDefaultSubobjectUSceneComponent(TEXT(Root Comp)); SetRootComponent(RootComp);//此函数设定RootComp为根组件 TriggerComp CreateDefaultSubobjectUTriggerComponent(TEXT(Trigger Comp)); TriggerComp-SetupAttachment(RootComp);//此函数把TriggerComp指向的组件附加到RootComp KeyItemMesh CreateDefaultSubobjectUStaticMeshComponent(TEXT(Key Item Mesh)); KeyItemMesh-SetupAttachment(RootComp);//此函数把KeyItemMesh指向的组件附加到RootComp }第四步:现在开始配置一下这个蓝图在蓝图中添加一个底座, 用SM_TableRound作为底座;然后点击Key Item Mesh,查看细节面板的静态网格体组件, 添加一个SM_Statue网格体,调整状态让其和底座组合在一起;然后点击Trigger Comp,把这个组件的碰撞范围调整以覆盖Key Item Mesh最终效果:第五步: 设置钥匙的碰撞效果,如果此时把这个TestDoorLock放入场景,那么这个钥匙会和玩家有碰撞阻碍,通过设置可以取消;打开BP_TestDoorLock, 选中玻璃摆件,在细节面板找到碰撞--碰撞预设--Custom--Pawn--改成忽略;编译后退出响应方式含义忽略Ignore两个物体碰撞时 “无任何交互”既不阻挡、也不触发任何碰撞 / 重叠事件重叠Overlap物体可以互相穿过但会触发重叠事件比如蓝图里的 “开始重叠”“结束重叠”阻挡Block物体无法互相穿过会产生物理阻挡同时可触发碰撞事件比如 “碰撞开始”第六步: 设置钥匙的可见性使用静态网格体的内置函数:void USceneComponent::SetVisibility(bool NewValue);void ALock::SetIsKeyPlaced(bool NewIsKeyPlaced) { IsKeyPlaced NewIsKeyPlaced;//设置钥匙是否插入 TriggerComp-Trigger(NewIsKeyPlaced);//设置触发器是否触发,此触发器可控制一个物体的移动 KeyItemMesh-SetVisibility(NewIsKeyPlaced);//设置物体的可见性 }总结:通过以上步骤,我们创建了一个锁蓝图(BP_PressurePlate),这个锁可以控制门的开/关,且当锁激活时,其玻璃雕塑就会显示,在锁未被激活时,玻璃雕像不可见.