UE蓝图, C++入门笔记
EDC,Epic Developer Community 论坛
https://forums.unrealengine.com/categories?tag=unreal-engine
片段:别人写好的功能。
Epic开发者助手:虚幻引擎训练的垂直领域的AI
https://dev.epicgames.com/community/assistant/unreal-engine
蓝图入门
- 命名规范:使用类型大写字母前缀,下划线,名字。
输入
传统的输入映射已经弃用,现在是增强输入 Enhanced Input Action。
要创建简单移动,先创建 Input Action,比如 左右移动为一个 vector2d,摄像机旋转为一个vector2d;
再创建Input Mapping Context,在映射中选择创建好的 Input Action,再为其绑定键位/鼠标啥的。使用修改器 Modifiers 调整输入值。
使用输入控制角色:BeginPlay==get player controller-Enhanced Input Local Player Subsystem-(Target)Add Mapping Context。(使用Enhanced Input Action的固定流程)
再添加事件(直接搜索InputAction的文件名)Triggered-Add Movement Input/Add Controller Yaw Input
在蓝图中添加注释:框选后按C。
旋转描述
- 摄像机旋转描述:Pitch 点头 绕y旋转;Yaw 摇头 绕z旋转;Roll 歪头 绕x旋转
制作一个门:
新建 BP 类 继承 Actor,再给这个Actor添加 Static Mesh 和 BoxCollision。
添加Collision的Events到EventGraph中使用。
StaticMesh的碰撞体是附带的,打开StaticMesh后编辑。
Add Timeline:类似AnimationPlayer
流程控制节点
Flip Flop:一次触发执行A,一次触发执行B。
Do once:只执行一次。可以重置
Sequence:依次执行,每条执行完才执行其他的
Delay:延迟。
Sequence 分支不受其他分支的delay影响。比如 Then 0有个delay,那么delay开始倒计时后就去Then1了,倒计时结束再触发delay后的语句。
For Loop:循环
Gate:门。有点像没有else的自带标记的if。
角色动画:
Character的动画模式使用动画蓝图(ABP),动画蓝图里面编辑EventGraph;在AnimGraph使用动画混合空间BlendSpace。
BlendSpace里使用AnimSequence.
使用StateMachine,代替动画蓝图-AnimGraph中直接使用动画混合空间。
在StateMachine里设置State,在State里使用 动画混合空间 or 动画序列 AnimSequence(是的,不混合也能直接用)。动画序列记得设置 additive animation type 为 no additive。
给State之间设置过渡条件。
类关系:
Pawn->Character->BP_ChallengeCharacter(自己建的)
通过变换类型来调用子类的成员(函数/组件)。
可以从蓝图右键创建子蓝图类。变量public继承。
布娃娃效果需要 SkeletalMeshAsset 有 PhysicsAsset
构造函数:一开始就执行(废话)。在编辑器里拖到场景中就会执行。
蓝图节点-数学表达式:内部只读不可改,通过重命名为 (a+b)*c 之类的来使用。
蓝图通信:
cast to 转类型,这种调用方式比较性能不好,因为会把目标actor的变量都加载过来。所以用蓝图接口。
蓝图接口:前缀BPI_;可设置function,还有输入输出参数
装到BP上。然后在调用时,可以直接从 other actor 里拉出 dead(接口名)
事件分发器 EvenDispatcher:蓝图接口需要知道消息的接收方是谁,而事件分发器只需要接收方知道发送方是谁。
大量接收消息时,用事件分发器;点对点通信,用接口。
函数、宏
用 函数 or 宏 打包常用节点。
宏 Macro:在函数中不能使用timeline、delay,因为它们不能在一帧中完成(异步);而在宏当中可以,除了timeline也用不了。Timeline 本质上是与特定 Actor 实例绑定的特殊组件。
宏还可以有多个执行引脚。
trace
line trace by channel 按通道进行线条追踪
box trace by channel 当half size的x为0时,可以得到单纯的盒体。获得命中结果。总之就是射线检测。
Derived Data Cache
DDC,Derived Data Cache 派生数据缓存
和项目打开速度有关。项目多了会很大,建议放在SSD硬盘上。
get controller:不同角色会获得相应的控制器,适配多人游戏。返回值转化为playerController后->EnhancedInputLocalPlayerSubsystem->添加上下文映射(设置相应IMC)
每个Character都要有对应的Controller。(不然怎么动呢)
C++ 入门
和蓝图的对比:
C++适合编写底层操作代码,可以提供对蓝图无法访问的核心系统的控制
C++适合需要实现复杂的游戏系统或功能,频繁调用的函数
C++适合需要与外部交互 (网络)
C++适合定制功能
C++容易犯致命错误,对开发人员要求较高蓝图 适合不需要频繁修改的内容,如UI设计、游戏流程等
蓝图 适合快速迭代
蓝图 上手难度较低
蓝图 不适合过于复杂的业务,很容易变成意大利面
C++做蓝图,蓝图做游戏。
不要直接使用C++写的类,而是创建蓝图继承它再使用,这样方便在编辑器中修改参数。
不要使用原始指针。TObjectPtr<T>是虚幻引擎中的智能指针类型,相较于传统的原始指针,TObjectPtr避免了传统指针悬空(野指针,空指针)问题,其次可以实现自动内存管理,防止内存溢出。
使用VS debug
当你在 VS 中点击“本地 Windows 调试器”(或按 F5)时,你本质上是下达了这样一个指令:“启动 UnrealEditor.exe 这个程序,并让它加载我的 .uproject 文件”。调试结束会自动关闭引擎窗口
改用 “附加到进程(Attach to Process)” 调试:
先开引擎,再用 VS 附加上去(最常用)
- 先手动双击你的
.uproject文件,正常打开 UE 编辑器。 - 在 VS 中,点击顶部菜单的 “调试” > “附加到进程”(或按快捷键
Ctrl + Alt + P)。 - 在进程列表中,找到
UnrealEditor.exe(注意看底部路径,确保是你的项目),选中它。 - 点击 “附加”。
其实有三种场景,对应三种不同的操作,你绝大部分时间根本不用重新“附加”:
- 写代码时的“热重载”(最快,不用附加)
如果你只是修改了函数内部的逻辑(比如改了个伤害数值、加了个 PrintString),不需要重新附加。
- 在 VS 里直接按
Ctrl + Alt + F11(或者在编辑器里点“编译”)。 - 编译成功后,编辑器不会重启,你正在玩的游戏(PIE)也不会关。修改的代码直接生效,调试器依然牢牢挂着,断点照样能断住。
- 修改了头文件(.h)或新增了类(“分离+重附”)
如果你添加了新变量、新函数,或者新建了 C++ 类,必须重启编辑器才能加载新结构。
- 步骤:在 VS 里点 “调试” > “分离全部”(或者直接按
Shift + F5只停止调试,不关编辑器)。 - 关掉当前运行的 PIE(点编辑器里的“停止”)。
- 按
Ctrl + Alt + F11编译工程。 - 重新附加:按
Ctrl + Alt + P打开附加窗口。 - 省时技巧:在进程列表里随便点一下,然后按键盘上的
U键,光标会自动跳到UnrealEditor.exe上,直接点击“附加”。
- 只蓝图的逻辑,或者纯蓝图改动,不用附加
只有在你需要断点追踪 C++ 代码执行流程时,才需要去“附加”一下。
使游戏控制由我们创建的C++角色类
1.基于C++角色类来创建一个蓝图 BP_PlayerCharacter
2.创建基于GameMode的蓝图BP_PlayerGameMode
3.将BP_PlayerGameMode设置为游戏的GameMode
4.将BP_PlayerGameMode的Default Pawn Class赋值为BP_PlayerCharacter
C++类的创建与删除
创建很简单。
删除要关闭UE编辑器和VS(这是最重要的前提,否则文件被占用删不掉)。找到你项目里的Source文件夹,手动把对应的.h(头文件)和.cpp(源文件)删除。删除项目文件中的Binary和lntermediate文件夹。在文件管理器里右键项目名.uproject文件,选择Generate Visual Studio project files
UPROPERTY 和 UFUNCTION
UPROPERTY 是UnrealEngine中用于声明属性的宏,它用于标记某个属性是一个Unreal Engine 托管的属性,并且可以在编辑器中进行访问和操作。
UPROPERTY 宏提供了一系列参数,用于定义属性的属性和行为,例如是否可编辑、是否可序列化等。
EditAnywhere:允许在编辑器中编辑该属性。
EditDefaultsOnly:实例就不能修改了。
BlueprintReadWrite:允许在蓝图(EventGraph)中读写该属性。
VisibleAnywhere:在编辑器中显示该属性,但不允许编辑。
Transient:该属性不会被序列化保存,通常用于临时数据或不希望被保存的数据。
Category=“name”:指定在编辑器中显示的该属性所属的分类。
Meta:可以用来设置一些元数据,如文档、关键字等,meta=(AllowPrivateAccess=”true”)允许私有属性在编辑器中进行编辑
Replicated:属性在网络中进行复制。
UFUNCTION 是UnrealEngine 中用于声明函数的宏,它用于标记某个函数是一个UnrealEngine托管的函数,并且可以在编辑器中进行访问和操作。
UFUNCTION宏 提供了一系列参数,用于定义函数的属性和行为,例如是否是蓝图可调用的、是否可在网络中复制等。
BlueprintCallable:允许在蓝图中调用该函数。
BlueprintPure:声明该函数为纯函数,即不会修改对象的状态。
BlueprintlmplementableEvent:声明该函数为蓝图可实现的事件,在蓝图中可以实现该事件的具体逻辑。
Category:指定在编辑器中显示的该函数所属的分类。
Meta:可以用来设置一些元数据,如文档、关键字等。
Server、Client、Reliable:用于网络功能,指定该函数在服务器端、客户端执行,以及指定该函数是否可靠传输。
纯函数没有执行引脚。
两种打LOG的方式
UE_LOG 宏是UnrealEngine 中用于日志记录的标准方式。它可以输出日志信息到控制台和日志文件,支持多种日志级别(如Log,Warning,Error”)
UE_LOG(LogCategory, LogVerbosity, Format, …)
UE_LOG(LogTemp, Warning, TEXT("CameraBoom : TargetArmLength: %f"), CameraBoom->TargetArmLength);
GEngine->AddOnScreenDebugMessage可以在 游戏屏幕上 显示调试信息,通常用于快速查看和调试。
GEngine->AddOnScreenDebugMessage(Key, TimeToDisplay, Color, Message)
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Blue, Fsting::Printf(TEXT("Camera %f") CameraBoom->TargetArmLength));
Enhanced lnput
Input Mapping Context 输入映射上下文是一个定义了哪些输入键触发哪些输入动作的规则集合。它们通常与特定的游戏状态相关联,比如游戏中的主菜单、游戏中的行走状态等。可以通过编辑项目设置或蓝图脚本来创建和管理输入映射上下文。
InputAction 代表了玩家可以执行的某种动作,比如跳跃、射击、打开菜单等。输入动作通常与键盘按键、鼠标按钮或游戏手柄按钮相关联。在可以通过编辑输入映射来创建和管理输入动作,然后可以在蓝图或代码中监听这些输入动作,以便在玩家执行相应操作时触发相应的逻辑。
EnhancedlnputComponent的功能
1更灵活的输入处理:相比于传统的输入组件,EnhancedlnputComponent允许更加灵活地定义输入操作和处理逻辑。它支持更多种类的输入设备和输入方式,并提供了更多的定制选项。
2 输入绑定的优化:EnhancedlnputComponent 支持将输入绑定到函数、委托或蓝图中的事件,使输入处理变得更加直观和易于管理。
3 输入处理流程的改进:EnhancedlnputComponent 提供了更多的控制权,使开发者可以更精确地管理输入事件的触发和处理顺序,从而优化输入响应的流畅度和准确性。
虚幻引擎5(Unreal Engine 5)是一个高度面向对象的引擎,使用C++编程语言和其专属的反射系统来实现强大的对象管理和脚本功能。
虚幻也对C++的面向对象进行了一些修改,比如接口、反射系统等。
基本用不到std库。
常用类型
UObject:
基础类UObject是所有非Actor类的基类,几乎所有的UnrealEngine对象都继承自UObject。
AActor:
继承自UObject:AActor继承自UObject,并且是所有场景中对象(例如,角色、道具、灯光等)的基类
APawn:如果你需要一个可以被玩家或Al控制的对象,但不需要复杂的运动和动画系统。
1.可控制性:APawn可以通过玩家输入或AI控制器来操纵。
2.控制器:APawn通常与AController 或APlayerController 关联,以实现移动和交互。
3.不包含骨骼网格和动画:与ACharacter 不同,APawn 不包含骨骼网格和动画系统
ACharacter是一种特殊类型的APawn,它包含用于行走、跳跃、游泳等的运动功能。它是带有骨骼网格和动画系统的高级角色类
骨骼网格和动画:ACharacter 包含USkeletalMeshComponent 和动画蓝图,用于角色的外观和动画。
角色运动:包含UCharacterMovementComponent,支持复杂的角色运动(如行走、跑步、跳跃、游泳等)。
碰撞和胶囊体:默认包含一个胶囊碰撞体,用于角色的碰撞检测
AGameModeBase:
这是游戏模式的基类,它定义了游戏的规则、逻辑和行为。
可以通过创建自定义的游戏模式类来扩展它,并重写其中的方法来实现特定游戏的逻辑。AGameMode:
AGameMode 类是AGameModeBase的一个子类,它提供了更多的功能和控制权,例如玩家控制、团队管理、计分系统等。
可以使用AGameMode 类来实现更复杂的游戏逻辑和规则。GameSession
1.玩家连接管理:GameSession负责追踪和管理玩家的连接,包括玩家的加入、离开和断开连接等操作。它可以跟踪当前在线的玩家数量和列表。
2.会话状态管理:GameSession维护着游戏会话的状态,例如游戏是否正在进行、游戏是否已经结束等。它提供了方法来开始、结束和重启游戏会话。
3.权限和权限控制:GameSession可以处理玩家的权限和访问控制,例如确定哪些玩家具有管理游戏会话的权限、哪些玩家可以加入游戏等。
4.跨服务器通信:在多服务器游戏环境下,GameSession可能还负责管理服务器之间的通信和状态同步。
5.游戏状态同步:在一些需要同步游戏状态的游戏中,GameSession可能会负责协调和管理游戏状态的同步。Game State:
GameState 类代表了整个游戏的状态,是全局性的。
GameState 实例通常只有一个,它包含了整个游戏的状态信息,如当前得分、游戏时间、游戏模式等。
GameState用于跟踪和管理游戏的全局状态,而不是针对特定的玩家。Player State:
PlayerState 类代表了单个玩家的状态,是针对特定玩家的。
对于每个玩家在游戏中都有一个对应的 PlayerState 实例,它用于跟踪和管理该玩家的个人信息和状态,如玩家得分、生命值、队伍信息等。
DefaultPawnClass用于指定在没有特定玩家控制的情况下所使用的默认角色。通常情况下,Default Pawn Class 可以设置为游戏中的任何Pawn类或其子类。
- APlayerController:
APlayerController 类用于控制一个玩家的输入、视角、动作等。
在游戏模式中,玩家控制器通常用于处理玩家的输入和操作,并与游戏世界进行交互。 - AHUD:
AHUD类是用于显示游戏界面的基类。
它可以用来显示各种元素,如生命值条、得分、道具信息等。。
PlayerController中的OnPossess方法:
通常情况下,你只有在需要在玩家控制器(APlayerController)接管角色时执行特定的逻辑时才需要重写OnPossess函数
1.初始化角色状态:当玩家控制器接管一个角色时,你可能希望初始化该角色的状态,例如设置初始位置、初始属性等。
2.处理特定的角色切换逻辑:如果你的游戏中存在多个角色,并且需要在玩家控制器切换角色时执行特定的逻辑(例如切换角色时播放动画或切换HUD),那么你可以在OnPossess中处理这些逻辑。
3.触发特定事件:当玩家控制器接管角色时,可能需要触发一些特定的事件或系统,例如触发一个事件以启动角色的行为或系统。
运行顺序:Character的构造函数->Pawn OnPossess->Character的 BeginPlay
TArray
虚幻中的数组是TArray模板类,相当于标准库的vector。支持迭代器。
LineTrace
LineTrace是一种让游戏告诉你在游戏世界中两点之间是否有任何东西存在的方式。游戏将在这两个点之间射出一条由你指定的光线,并返回被击中的物体(如果有的话)、它们被击中的位置、角度等等。
组件基类
USceneComponent是场景组件的基类,它包含了位置、旋转和缩放信息,并且可以用于构建组件之间的层次结构。
USceneComponent可以被附加到AActor类的实例上,作为其子组件,用于表示对象的空间位置和转换信息。
USceneComponent可以作为其他组件的父级,,用于构建复杂的组件关系,例如在一个Actor上附加多个Mesh组件,并将它们统一移动、旋转或缩放。
UActorComponent 是组件的基类,它为组件提供了基本的功能,但不包含位置、旋转和缩放等场景相关的信息。
UActorComponent通常用于添加功能性或行为性的组件,例如处理输入、碰撞检测、音频播放等,而不涉及空间位置或层次结构。
UActorComponent不能直接表示对象的位置或旋转,而是依赖于其所附加到的
USceneComponent 或其他SceneComponent来确定其在场景中的位置和转换。
类名前缀规则
| 前缀 | 代表的基类 | 为什么你的类是这个前缀 |
|---|---|---|
| A | Actor(可放置在游戏世界中的实体) | Character 继承自 Pawn,Pawn 继承自 Actor,所以必须是 AEnemy。 |
| U | UObject(不继承自 Actor 的纯数据/功能对象) | SceneComponent 继承自 ActorComponent,而 ActorComponent 继承自 UObject,所以必须是 ULookComponent。 |
| F | Fundamental(纯数据结构,无反射) | 例如 FVector、FRotator,或你自己定义的结构体。 |
| E | Enum(枚举) | 例如 ENetRole、ECollisionEnabled。 |
| I | Interface(接口类) | 虚幻的接口必须以 I 开头。 |
| S | Slate(UI控件) | 继承自 SWidget 的类。 |
SpawnActor(Deferred)
SpawnActor:这个函数会立即生成并初始化一个新的Actor实例。它会立即调用Actor的构造函数,并在生成后立即将其放置在世界中。这意味着,一旦调用’SpawnActor,新的Actor实例就会立即出现在游戏世界中。
SpawnActorDeferred:这个函数会延迟生成Actor实例。它会返回一个FActorSpawnParameters’对象,您可以在稍后调用FinishSpawningActor时使用该对象来生成Actor实例。这使您有机会在生成Actor之前对其进行更多的设置或初始化。与’SpawnActor’不同,调用’SpawnActorDeferred’并不会立即在世界中生成Actor实例,直到您调用FinishSpawningActor为止。
自己添加的channel的在C++中使用时需要去配置文件查看(因为不是自己设置的名称)。
SphereComponent->OnComponentHit.AddDynamic(this, &ABallProjectile::OnHit);附加到 动态多播委托。
Interface
1.共享功能:通过接口,您可以定义一组方法,然后在多个不同的类中实现这些方法,使得它们可以共享相似的功能,而无需继承相同的基类。
2.减少依赖性:接口可以帮助减少类之间的直接依赖关系。类只需要实现所需的接口,而不需要知道其他类的具体实现。
3.多重继承:虽然C++不支持多重继承,但是通过接口,您可以在不同的类中实现多个接口,达到类似多重继承的效果。
UInterface 为蓝图接口,Ulnterface 主要是为了加入虚幻的反射系统,所以不需要修改,空壳。
llnterface 这是一个 C++ 接口,用于在 C++ 代码中声明一组纯虚函数
BlueprintNativeEvent 是UnrealEngine中用于声明蓝图原生事件(BlueprintNativeEvent)的宏。它的作用是在接口或基类中定义一个函数签名,使得蓝图类可以在蓝图中实现该函数,而不需要在C++中进行具体的实现。这样,蓝图类可以根据需要自定义该函数的行为,而不受C++实现的限制。
1 | UFUNCTION(BlueprintNativeEvent, Category = "Health") |
在声明一个蓝图原生事件时,需要同时提供一个C++的虚函数实现,这个虚函数名字以_Implementation结尾。这个实现函数作为默认实现,如果蓝图类没有提供特定的实现,将会调用这个默认的实现。这个约定让C++类的实现在没有蓝图特定实现时也能正常运作。
1 | IHealthInterface::Execute_Damage(OtherActor); |
Widget
虚幻引擎中的Widget是用于创建用户界面(Ul)的元素。它们可以用于构建游戏中的各种UI元素,例如菜单、按钮、文本框等等。
1.UMG(虚幻电影图形):UMG是虚幻引擎中用于创建和管理UI的系统。它提供了一个可视化的界面来设计和布局UI元素,并提供了一个图形化的脚本语言(蓝图)来定义UI的行为和交互。
2.WidgetBlueprint:Widget Blueprint是用于创建自定义Ul元素的蓝图类。你可以在Widget Blueprint中定义UI元素的外观和行为,并通过虚幻的蓝图系统来实现交互逻辑。
3.预制Widget组件:虚幻提供了许多预制的Widget组件,例如按钮、文本框、图片等等。你可以通过将这些组件拖放到UMG界面上来快速构建Ul。
4.动态生成:除了静态设计之外,你还可以通过蓝图或代码在运行时动态生成和管理Widget。这使得你可以根据游戏中的各种情况来动态更新UI。
5.样式和动画:虚幻的Widget系统支持样式和动画,你可以为UI元素定义各种外观样式,并通过动画来增强用户体验。
6.交互和事件:你可以通过蓝图或代码为Widget添加各种交互功能,例如点击事件、拖拽事件等等,以便与玩家进行交互。
更新.Build.cs中的模块后需要重新生成VS project files
一般是Controller调用HUD,HUD再更新Widget。(意思是不要用Controller直接控制Widget)
- 标题: UE蓝图, C++入门笔记
- 作者: 铁名_IronName
- 创建于 : 2026-08-18 10:23:11
- 更新于 : 2026-09-04 10:19:42
- 链接: https://blog.ironname.top/2026/UE/UE学习笔记1/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。