Unreal Engine 中类前缀规则
之前,我们建立了第一个继承 Object 的类,这里首先看一下 Unreal Engine 中类的前缀规则。
派生自 Actor 的类带有 A 前缀,如 AOneActor。
派生自 Object 的类带有 U 前缀,如 AOneObject。
Enums 的前缀是 E,如 EOneType。
Interface 的前缀通常是 I,如 IOneInterface。
Template 的前缀是 T,如 TArray。
派生自 SWidget 的类(Slate UI)带有前缀 S,如 SButton。
结构体、其他类的前缀为字母 F,如 FVertor。
C++和蓝图中创建继承 Actor 的类
Unreal 的坐标系和单位
在工程中,导入一个坐标系模型,以方便理解 UE4 的坐标系跟单位。人物模型身高 1.8米 左右。
UE4 缺省坐标系统为左手坐标系统,x向后,y向右,z向上
每一个Unreal单位,对应现实单位1厘米,100就是1米。

C++ 中的创建继承 Actor 的类 OneActor
创建 继承于 Actor 的类 OneActor 开始我们正题,创建一个类名为 OneActor 的类,让其继承于 Actor。注意,在 UE4 引擎中,无法创建 VS 工程中的代码文件夹,这里我们创建 OneActor 新类时,多给定了新的 Actor 文件夹目录,这样就实现了代码文件夹的创建。

创建继承 OneActor 的蓝图类 BP_OneActor
跟 OneObject 不同,OneActor 可以直接创建蓝图类

创建 BP_OneActor 蓝图类,继承于 OneActor

虚幻4 几个常用属性说明
BlueprintReadWrite:This property can be read or written from a Blueprint. This operator is incompatible with the BlueprintReadOnly specifier.
BlueprintReadWrite:在蓝图(节点)里面可以读写(get和set方法)。
BlueprintReadOnly:This property can be read by Blueprints, but not modified. This operator is incompatible with the BlueprintReadWrite specifier.
BlueprintReadOnly:在蓝图(节点)里面只读。
EditAnywhere:Indicates that this property can be edited by property windows, on archetypes and instances.
EditAnywhere:在资源和实例的属性窗口都可以编辑。与Visible*标识符冲突。
EditDefaultsOnly:Indicates that this property can be edited by property windows, but only on archetypes. This operator is incompatible with the Visible* specifiers.
EditDefaultsOnly:只能在资源的属性窗口编辑。与Visible*标识符冲突。
EditInstanceOnly:Indicates that this property can be edited by property windows, but only on instances, not on archetypes. This operator is incompatible with the Visible* specifiers.
EditDefaultsOnly:只能在实例的属性窗口编辑。与Visible*标识符冲突。
VisibleAnywhere:Indicates that this property is visible in property windows, but cannot be edited at all. This operator is incompatible with the Edit* specifiers.
VisibleAnywhere:在资源和实例的属性窗口可视,但不可编辑。与Edit*冲突。
VisibleDefaultsOnly:Indicates that this property is only visible in property windows for archetypes, and cannot be edited. This operator is incompatible with the Edit* specifiers.
VisibleDefaultsOnly:在资源的属性窗口可视,但不可编辑。与Edit*冲突。
VisibleInstanceOnly:Indicates that this property is only visible in property windows for instances, not for archetypes, and cannot be edited. This operator is incompatible with the Edit* specifiers.
VisibleDefaultsOnly:在实例的属性窗口可视,但不可编辑。与Edit*冲突。
虚幻4 常用属性的不同之处
我们先编写代码,给各个变量指定不同的属性
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "OneActor.generated.h"
UCLASS()
class UECPPBASICPROJECT_API AOneActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AOneActor();
// EditAnywhere:在资源和实例的属性窗口都可以编辑。与Visible*标识符冲突。
UPROPERTY(VisibleAnywhere, Category = "One Actor Components")
UStaticMeshComponent* OneStaticMesh; // 网格模型
// EditDefaultsOnly:只能在实例的属性窗口编辑。与Visible*标识符冲突。
UPROPERTY(EditInstanceOnly, Category = "One Actor Properties | Vector")
FVector InitLocation; // 游戏开始时 初始化位置
// VisibleDefaultsOnly:在实例的属性窗口可视,但不可编辑。与Edit*冲突。
UPROPERTY(VisibleInstanceOnly, Category = "One Actor Properties | Vector")
FVector PlacedLocation; // UE4 编辑器中 放置的位置
// EditDefaultsOnly:只能在资源的属性窗口编辑。与Visible*标识符冲突。
UPROPERTY(EditDefaultsOnly, Category = "One Actor Properties | Vector")
bool bGotoInitLocation; // 是否 编辑器放置的位置 移动到 初始位置
// VisibleDefaultsOnly:在资源的属性窗口可视,但不可编辑。与Edit*冲突。
UPROPERTY(VisibleDefaultsOnly, Category = "One Actor Properties | Vector")
FVector WorldOrigin; // 世界原地坐标
// ClampMin、 ClampMax 设置 TickLocoationOffset 的大小范围。
// UIMin、 UIMax 在UI中体现出 大小范围。
UPROPERTY(EditAnywhere, Category = "One Actor Properties | Vector", meta=(ClampMin=-5.0f, ClampMax=5.0f, UIMin=-5.0f, UIMax=5.0f))
FVector TickLocationOffset; // Tick时 移动位置偏移大小。
UPROPERTY(EditAnywhere, Category = "One Actor Properties | Vector")
bool bCanTickMove; // 是否在Tick中移动
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
双击 BP_OneActor,打开蓝图编辑器。指定一个多边形模型。搜索查看"One Actor Properties"。

编辑好 BP_OneActor 相关属性后,将 BP_OneActor 蓝图拖放在 UE4 编辑器中,搜索查看"One Actor Properties"。

通过说明、代码和图片的标注,对UE4中的反射,应该有了一定的了解~~
BP_OneActor 的物理
IcoSphere 添加碰撞 如果要对蓝图 BP_OneActor 有物理效果,首先应该对 IcoSphere 这个多边形模型添加碰撞。双击模式,进入模型编辑,生成一个简单的凸包碰撞。

BP_OneActor 添加物理

编写代码,添加力和力矩
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "OneActor.generated.h"
UCLASS()
class UECPPBASICPROJECT_API AOneActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AOneActor();
UPROPERTY(VisibleAnywhere, Category = "One Actor Components")
class UStaticMeshComponent* OneStaticMesh; // 网格模型
... // 略掉上边相关位置设置代码
// 力
UPROPERTY(EditInstanceOnly, Category = "One Actor Properties | Physics")
FVector InitForce;
// 力矩
UPROPERTY(EditInstanceOnly, Category = "One Actor Properties | Physics")
FVector InitTorque;
// 是否忽略质量?
UPROPERTY(EditInstanceOnly, Category = "One Actor Properties | Physics")
bool bAccelChange;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
#include "OneActor.h"
// 添加 UStaticMeshComponent 头文件
#include "Components/StaticMeshComponent.h"
// Sets default values
AOneActor::AOneActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
OneStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OneStaticMesh"));
// 物理
InitForce = FVector(0.0f);
InitTorque = FVector(0.0f);
bAccelChange = false;
}
// Called when the game starts or when spawned
void AOneActor::BeginPlay()
{
Super::BeginPlay();
// 给予力 可以使物体运动, bAccelChange 视为忽视质量,这样 InitForce 不用给的特别大
OneStaticMesh->AddForce(InitForce, "NAME_None", bAccelChange);
// 给予力矩 可以使物体旋转
OneStaticMesh->AddTorque(InitTorque, "NAME_None", bAccelChange);
}
// Called every frame
void AOneActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
我们给多边形模型一个2000的力和100的力矩。多边形受力和力矩的影响,缓慢向-y轴移动,我们可以用角色去撞击多边形,让其有更大的力。


BP_OneActor 的碰撞扩展
在场景中在创建一个 BP_OneActor蓝图 让场景中同时有两个 BP_OneActor蓝图实例,并且赋予不同颜色的材质。我们试图做一下,让两个多边形同时延-y轴运动,当两个多边形同时碰撞到墙面时,红色的多边形穿越墙面,而蓝色的因碰撞停留在墙上。
关闭两个多边形的物理检测,并且去掉力、力矩代码。让多边形通过Tick代码改变位置。
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "OneActor.generated.h"
UCLASS()
class UECPPBASICPROJECT_API AOneActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AOneActor();
// EditAnywhere:在资源和实例的属性窗口都可以编辑。与Visible*标识符冲突。
UPROPERTY(VisibleAnywhere, Category = "One Actor Components")
class UStaticMeshComponent* OneStaticMesh; // 网格模型
// EditInstanceOnly:只能在实例的属性窗口编辑。与Visible*标识符冲突。
UPROPERTY(EditInstanceOnly, Category = "One Actor Properties | Vector")
FVector InitLocation; // 游戏开始时 初始化位置
// VisibleDefaultsOnly:在实例的属性窗口可视,但不可编辑。与Edit*冲突。
UPROPERTY(VisibleInstanceOnly, Category = "One Actor Properties | Vector")
FVector PlacedLocation; // UE4 编辑器中 放置的位置
// EditDefaultsOnly:只能在资源的属性窗口编辑。与Visible*标识符冲突。
UPROPERTY(EditDefaultsOnly, Category = "One Actor Properties | Vector")
bool bGotoInitLocation; // 是否 编辑器放置的位置 移动到 初始位置
// VisibleDefaultsOnly:在资源的属性窗口可视,但不可编辑。与Edit*冲突。
UPROPERTY(VisibleDefaultsOnly, Category = "One Actor Properties | Vector")
FVector WorldOrigin; // 世界原地坐标
// ClampMin、 ClampMax 设置 TickLocoationOffset 的大小范围。
// UIMin、 UIMax 在UI中体现出 大小范围。
UPROPERTY(EditAnywhere, Category = "One Actor Properties | Vector", meta=(ClampMin=-50.0f, ClampMax=50.0f, UIMin=-50.0f, UIMax=50.0f))
FVector TickLocationOffset; // Tick时 移动位置偏移大小。
UPROPERTY(EditAnywhere, Category = "One Actor Properties | Vector")
bool bCanTickMove; // 是否在Tick中移动
/*
// 力
UPROPERTY(EditInstanceOnly, Category = "One Actor Properties | Physics")
FVector InitForce;
// 力矩
UPROPERTY(EditInstanceOnly, Category = "One Actor Properties | Physics")
FVector InitTorque;
// 是否忽略质量?
UPROPERTY(EditInstanceOnly, Category = "One Actor Properties | Physics")
bool bAccelChange;
*/
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
#include "OneActor.h"
// 添加 UStaticMeshComponent 头文件
#include "Components/StaticMeshComponent.h"
// Sets default values
AOneActor::AOneActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
OneStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OneStaticMesh"));
InitLocation = FVector(0.0f);
PlacedLocation = FVector(0.0f);
bGotoInitLocation = false;
WorldOrigin = FVector(0.0f);
TickLocationOffset = FVector(0.0f);
bCanTickMove = true;
// 物理
//InitForce = FVector(0.0f);
//InitTorque = FVector(0.0f);
//bAccelChange = false;
}
// Called when the game starts or when spawned
void AOneActor::BeginPlay()
{
Super::BeginPlay();
PlacedLocation = GetActorLocation();
if (bGotoInitLocation)
{
SetActorLocation(InitLocation);
}
// 给予力 可以使物体运动, bAccelChange 视为忽视质量,这样 InitForce 不用给的特别大
//OneStaticMesh->AddForce(InitForce, "NAME_None", bAccelChange);
// 给予力矩 可以使物体旋转
//OneStaticMesh->AddTorque(InitTorque, "NAME_None", bAccelChange);
}
// Called every frame
void AOneActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (bCanTickMove)
{
// 获取碰撞信息
FHitResult HitResult;
AddActorLocalOffset(TickLocationOffset * DeltaTime, true, &HitResult);
}
}
修改红色多边形的碰撞规则,让其忽略 WorldStatic ,世界中静态物体,墙都是静态的。






