虚幻引擎-设计场景物体哲学-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++类想要被场景道具使用, 需要被加载入蓝图,然后实例化蓝图创建场景实体

蓝图实例:

蓝图和蓝图实例的关系就像:类和对象的关系,蓝图实例是蓝图的 “具体化产物”,通过修改蓝图内暴露的参数可以创造出各种各样的蓝图实例.


 

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,并且取名为GlassStatue

2.创建一个锁角色类:

假设我们需要用一个玻璃雕像放在一个底座上开启一个门,那么我们可以把玻璃雕像GlassStatue理解成一把钥匙key,为了方便管理,我们在建模时把底座也加入我们的锁蓝图,这样放置时会很方便.

第一步: 在C++类文件中添加一个类,继承自Actor,然后取名为Lock

第二步: 在构造函数中添加标签

第三步: 导入Lock所需的相关组件的头文件, 并且声明相关的指针, 然后在构造函数中初始这些指针
这样就可以在代码中把外部组件添加到我们自己的组件,而不需要在蓝图中手动添加(而且蓝图中添加组件是无法在函数中访问的).

#include"TriggerComponent.h"
#include"Components/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 = CreateDefaultSubobject<USceneComponent>(TEXT("Root Comp"));
	SetRootComponent(RootComp);//此函数设定RootComp为根组件

	TriggerComp = CreateDefaultSubobject<UTriggerComponent>(TEXT("Trigger Comp"));
	TriggerComp->SetupAttachment(RootComp);//此函数把TriggerComp指向的组件附加到RootComp

	KeyItemMesh = CreateDefaultSubobject<UStaticMeshComponent>(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),这个锁可以控制门的开/关,且当锁激活时,其玻璃雕塑就会显示,在锁未被激活时,玻璃雕像不可见.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值