Unreal C++ 玩法
编写正确的 UE5 玩法 C++:将 C++ 连接到编辑器和蓝图、Gameplay Framework 类角色以及模块依赖的反射宏。目标为 UE 5.8。
何时使用
- 在创建 C++ 玩法类(
AActor、APawn、ACharacter、AGameModeBase、 - 当项目具有使用
UCLASS的Source/树,包含*.h/*.cpp和*.Build.cs时使用。
UActorComponent)、使用 UPROPERTY/UFUNCTION 暴露属性/函数、设置 GameMode 的默认类,或在 *.Build.cs 中添加模块依赖时使用。
**何时*不*使用:**面向设计者的可视化逻辑 → unreal-blueprints。玩家输入 绑定细节 → unreal-enhanced-input。AI 逻辑 → unreal-behavior-trees。此技能拥有 这些内容所构建的 C++ 类/反射基础。
核心工作流
- 使用正确的前缀命名。
A= 派生自 Actor,U= 派生自UObject/组件, - 使用反射宏声明类。 在类上方放置
UCLASS(),在类体首行放置GENERATED_BODY(), - 使用
UPROPERTY暴露数据(编辑器和蓝图可见性*以及*垃圾回收跟踪), - 在构造函数中创建组件,使用
CreateDefaultSubobject<T>(TEXT("Name"))并 - 了解框架角色:
AGameModeBase设置规则 + 默认类;APawn/ - 添加模块依赖到
*.Build.cs(例如EnhancedInput),否则会出现未解析符号链接错误。 - 验证:通过编译(函数体使用 Live Coding
Ctrl+Alt+F11;头文件/UPROPERTY 更改需要完整重新构建)
F = 普通结构体,E = 枚举,I = 接口。前缀必须与基类匹配。
并将 #include "ClassName.generated.h" 作为头文件中的最后一个 include。
并使用 UFUNCTION(BlueprintCallable 等)暴露行为。
设置 RootComponent。
ACharacter 是可控身体;APlayerController 是玩家的意志; UActorComponent 是可复用行为。
并检查类和属性是否出现在编辑器中。
模式
1. 最小 Actor 类(头文件 + 源文件)
// Pickup.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Pickup.generated.h" // MUST be the last include
UCLASS()
class MYGAME_API APickup : public AActor // MYGAME_API = your module's export macro
{
GENERATED_BODY()
public:
APickup();
// EditAnywhere = tweak per-instance & on the CDO; BlueprintReadWrite = BP get/set.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pickup")
int32 ScoreValue = 10;
// UPROPERTY on a UObject* pointer is what keeps it from being garbage-collected.
UPROPERTY(VisibleAnywhere)
TObjectPtr<UStaticMeshComponent> Mesh; // UE5: TObjectPtr instead of raw UStaticMeshComponent*
UFUNCTION(BlueprintCallable, Category = "Pickup")
void Collect();
protected:
virtual void BeginPlay() override;
};
2. GameMode 连接其默认类
// MyGameMode.cpp — set in the constructor so the engine spawns your classes.
AMyGameMode::AMyGameMode()
{
DefaultPawnClass = AMyCharacter::StaticClass();
PlayerControllerClass = AMyPlayerController::StaticClass();
}
3. Build.cs 中的模块依赖
// MyGame.Build.cs
PublicDependencyModuleNames.AddRange(new string[]
{
"Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput"
});
陷阱
generated.h不是最后 / 缺失 — 编译错误,例如 "Cannot find generated header" 或- 忘记
GENERATED_BODY()— UHT(Unreal Header Tool)错误;它必须放在类体第一行。 - **没有
UPROPERTY的裸UObject*** — 垃圾回收器看不到它,可能会在你不知情时将其销毁。 - 使用 Live Coding 编辑头文件/UPROPERTY — Live Coding 处理函数体,但
- 错误的类前缀 — 将 Actor 命名为
UFoo(或将组件命名为AFoo)会破坏 UHT; - 链接时未解析外部符号 — 提供该 API 的模块未列入
Build.cs的 - 在重写的
BeginPlay/Tick/等中未调用Super::会跳过引擎设置。
"Expected an include"。它必须是头文件中的最终 include。
使用 UPROPERTY 跟踪每个 UObject 指针(在 UE5 中使用 TObjectPtr)。
更改 UCLASS/UPROPERTY/头文件需要完整重启编辑器 + 重新构建。
前缀必须匹配基类型。
PublicDependencyModuleNames。
参考
- 如需了解
UActorComponent创建/附加、UPROPERTY垃圾回收所有权规则 - 主要文档:"Unreal Engine CPP Quick Start" 和 "Gameplay Framework"
(TObjectPtr、TArray<TObjectPtr<>>、AddToRoot)以及复制入门,请阅读 references/components-and-gc.md。
(https://dev.epicgames.com/documentation/en-us/unreal-engine/gameplay-framework-in-unreal-engine)。
相关技能
unreal-blueprints— 向设计者暴露 C++;BP/C++ 互操作。unreal-enhanced-input— 在 C++ Pawn/Character 中绑定输入。unreal-behavior-trees— 由行为树驱动的 C++ AI 任务。