首先在学习虚幻C++前,我建议有一定的蓝图基础和C++基础。
需要知道一些基础的虚幻C++类的作用(所有类的基类是Object)
ueC++跟C++的一些区别
- 派生自Actor的类带有A前缀,如AController
- 派生自Object的类带有U前缀,如UComponent
- Enums的前缀是E,如EFortificationType
- Interface的前缀是I,如IAbilitySystemInterface
- Template前缀是T,如TArray
- 派生自SWidget类的(Slate UI)带有前缀S,如SButton
- 其他类前缀为F,如FVector
使用宏进行标识,UE的UHT系统会帮我们进行垃圾回收像下图的UCLASS() 是为了标识其是一个虚幻C++类配合GENERATED_BODY()这个宏是为了标记代码生成的地方。(初学者记住是我为了标识是虚幻C++类,实现反射机制和垃圾回收即可)
上图中的UPROPERTY()作用把变量表示为把下面变量识别为虚幻能够使用的变量。UFUNTION()也是差不多的。主要还是虚幻C++的反射机制。
GamePlay
GameInstance
这里可以理解成游戏的单例,一个游戏里默认就只有一个GameInstance
!所有在这个系列里我们可以单做游戏开发的入口!
GameInstance
提供了几个比较实用的可重载的接口!
- ApplicationXXXDelegate 是UE监听的各种事件的委托;eg:进入后台等!
- Init 初始化的函数!
- Shutdown 游戏关闭的函数!
- StartGameInstance 开始!其中会调用
OnStart
- OnStart 启动!
World
world不是Level(即不是创建的地图!);一个World里可以有多个Level的!你可以理解这是个宇宙!
Level
这个就能简单粗暴地先理解成地图,如果World
是宇宙的话,那么一个Level
就是一个星球!而星球内就有很多大陆(也是Level)!
GameMode
一个World
就对应一个GameMode
;可以简单地理解成宇宙的基本法则,定义world运行的规则!(包含了玩家出生的规则等)
比较常用的就是指定以下属性
- HUDClass
游戏UI界面
- PlayerStateClass
为游戏连接的每一个用户的状态数据!(可以是本地的单机的,也可以是走
UE Dedicate Server
的)
- DefaultPawnClass
这里暂时可以理解成玩家角色模型的生成蓝图!(暂定,实际上不是!)
- PlayerControllerClass
玩家控制器,监听玩家输入,引用玩家hud,角色模型等!
HUD
玩家的界面;一般的用法是PlayerControllerClass
接受到玩家的输入后,通过HUD
对ui进行处理的!
Pawn
这里暂时可以理解成玩家角色模型的生成蓝图!(暂定,实际上不是!后面会在例子中逐步展开)
Controller
PlayerControllerClass
就是集成于它(虽然很多pawn能做的,他也能做,但是还是简单把其当做是控制器就可以了!)。
Debug输出方法
控制台输出方法
- UE_LOG(参数1, 参数2, 参数3);
- 参数1:
- 参数2:
屏幕输出方法
在C++中利用debug打印变量值
//屏幕打印变量方式
Gengine->AddOnScreenDebugMessage(-1,5.0f.FColor::Yellow,FString::printf(TEXT("MyVariable: %f"),MyVariable));
//控制台打印变量
UE_LOG(LogTemp,Warnig,TEXT("MyVariable: %f"),MyVariable);
枚举和结构体
枚举声明
使用命名空间包裹枚举,并使用 UENUM()
宏进行标记。这种方式定义的枚举可以包含多个枚举值。
UENUM(BlueprintType)
namespace EMyTestEnum
{
enum Type
{
One,
Two,
Three
};
}
利用 C++11 的 enum class
特性,定义具有作用域限制的枚举类型,并通过 UENUM()
宏进行标记。
UENUM(BlueprintType)
enum class EMyTestEnumClass : uint8
{
One,
Two,
Three
};
如果需要为枚举值添加额外的元数据(如显示名称),可以使用 UMETA
宏。这通常在蓝图系统中非常有用,因为显示名称将作为用户在编辑器中看到的选项。
UENUM(BlueprintType)
enum class EWeapon : uint8
{
EW_Handgun UMETA(DisplayName = "Handgun"),
EW_Shotgun UMETA(DisplayName = "Shotgun")
};
枚举UENUM()
在 Unreal Engine 的类中,您可以使用 TEnumAsByte<YourEnumType>
模板来声明一个属性,该属性将在编辑器中显示为可编辑的枚举类型。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyCategory")
TEnumAsByte<EWeapon> WeaponType;
EMyEnum currentType = EMyEnum::TypeA;
switch (currentType)
{
case EMyEnum::TypeA:
// ...
break;
case EMyEnum::TypeB:
// ...
break;
// ...
}
结构体
- USTRUCT:定义结构
- BlueprintType(蓝图可用)
- 主体需添加:GENERATED_USTRUCT_BODY
USTRUCT(BlueprintType)
struct FMyStruct
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyCategory")
FString MyString;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyCategory")
int32 MyInt;
// 可以在这里添加更多的UPROPERTY成员
};
对象的创建
UWorld::SpawnActor
- 在世界中创建 Actor
UWorld::SpawnActorDeferred
- 在世界中创建 Actor
- 配套 xxx->FinishSpawn() 调用后才会调用 BeginPlay 等进行初始化的函数,即延迟调用(在此之前可设置一些其它初始化参数)
CreateDefaultSubobject
- 为 Actor 创建组件(
只能在构造函数使用
) - T:类型
- TEXT:一个标识,当前类中不能重复
NewObject
- 仅在运行时构建 UObject 使用(
构造函数不要用
) - 主要指 UObject 的派生类(非 Actor、非 ActorComponent)
- objects-in-unreal-engine
AActor::AddComponentByClass
- 动态为 Actor 创建一个组件
- AActor 所实现,内部其实也是调用 NewObject 创建(所以构造函数应当也不要用)
纯 C++ 类的创建
- 纯C++类(指非继承自 UObject 的类,如 UE 中一般以 F 开头的)
- 可以通过 new 来创建对象,并使用 TSharedPtr 和 TSharedRef 来管理对象
TSharedPtr<MyClass> MyClassPtr = MakeShareable(new MyClass())
材质
Actor:BaseMesh
- BaseMesh->CreateAndSetMaterialInstanceDynamic
- UMaterialInstanceDynamic->SetVectorParameterValue()
定时器
TimeManager.h
- GetWorldTimerManager().SetTimer(FTimeHandler,this,callback,timeRate,isLoop)
- GetWorldTimerManager().ClearTimer(FTimeHandler)
组件
- USceneComponent:空组件
- UStaticMeshComponent:mesh 组件
- USpringArmComponent:悬臂组件(相机平滑跟随)
- UCameraComponent:相机
- UParticleSystem:粒子
- UDecalComponent:贴花
资源加载
UObject::StaticLoadObject
- 加载资源文件(静态对象、非蓝图资源)
- 应该算是资源加载 API 中最底层的了?
UObject::StaticLoadClass
- 可用于加载蓝图类资源
- 内部调用 LoadObject
LoadObject<T
>
- 封装
StaticLoadObject
,可以当做其泛型版本 - 可用来加载非蓝图资源,比如动画、贴图、音效等
- 内部会先执行 FindObject(查找已加载对象)
LoadClass<T
>
- 封装
StaticLoadClass
,用来加载 UClass,可以当做其泛型版本 - 可以用来加载蓝图并获取蓝图类
ConstructorHelpers
- FClassFinder:可以用来加载蓝图类资源
- FObjectFinder:对 LoadObject() 的封装,加载非蓝图普通资源
只能在构造函数使用
- 查找某个对象的对象和类
FSoftObjectPath
- 包含资源路径字符串的结构体
- 根据给定的资源路径找到对应的资源
- ResolveObject 内部封装
FindObject<UObject>(nullptr, PathString)
调用 - TryLoad 内部封装
StaticLoadObject
或LoadObject
调用 - 可配合 StreamableManager 进行资源异步加载
- TSoftObjectPtr :看起来可以管理 FSoftObjectPath
FSoftClassPath
- 继承自 FSoftObjectPath,可用于加载蓝图资源
- 提供 TryLoadClass 实际调用 LoadClass
FSoftObjectPtr
- 封装对 FSoftObjectPath 操作
- (也提供了 LoadSynchronous 同步加载方法,实际是调用 FSoftObjectPath.TryLoad)
TSoftClassPtr
- 与 TSoftObjectPtr 类似
FStreamableManager
- 可用于资源异步加载
- 异步加载:
- RequestAsyncLoad,返回 FStreamableHandle
- 同步加载:
- RequestSyncLoad(多个或单个加载,返回 FStreamableHandle)
- LoadSynchronous(单个加载,实际调用 RequestSyncLoad,直接返回 UObject)
- 看起来主要是与 FSoftObjectPath 配合使用
- 官方建议定义在类似单例之类对象中使用
- 注:FStreamableHandle 是同步或者异步加载的句柄,只要句柄处于激活状态,资源就会一直存在于内存
ObjectLibrary
- 资源加载库:设定一个路径,然后让它自动扫描
- 可用于在指定路径中加载所有资源数据,之后选择性加载实际资源
- 其中存储的 FAssetData 提供 GetSoftObjectPath() 接口返回 FSoftClassPath
调用关系
LoadObject
->UObject::StaticLoadObjectUObject::StaticLoadClass
->LoadObject->UObject::StaticLoadObjectLoadClass
->UObject::StaticLoadClass->LoadObject->UObject::StaticLoadObjectConstructorHelpers::FObjectFinder
->LoadObject->UObject::StaticLoadObjectConstructorHelpers::FClassFinder
->UObject::StaticLoadClass->LoadObject->UObject::StaticLoadObjectFSoftObjectPath
->ResolveObject->UObject::FindObjectFSoftObjectPath
->TryLoad->UObject::StaticLoadObjectFSoftClassPath
->TryLoadClass->LoadClass->UObject::StaticLoadClass->LoadObject->UObject::StaticLoadObject
模板
TSubclassOf<T
>:定义类类型属性时,使引擎面板过滤类型,只能选择 T 类本身或继承自它的类。 - 注:直接定义类类型指针,将能选择场景中类型对象
TArray:动态容器 Cast<T
>:类型转换
字符串
- FString::FromInt
- FString::SanitizeFloat
- FString::Printf
代理
代理通常有四种
- 不带形参,不带返回值
- 带形参,不带返回值
- 带返回值,不带形参
- 带返回值,带形参的
代理的创建
//声明委托 不带形参,不带返回值
DECLARE_DELEGATE(FDelegateTestA);
//声明委托 带形参,不带返回值,类似的一共有9个宏,最大带9个形参 如:DECLARE_DELEGATE_NineParams
DECLARE_DELEGATE_OneParam(FDelegateTestB,bool);
//声明委托带 带返回值,不带形参
DECLARE_DELEGATE_RetVal(bool,FDelegateTestC);
//声明委托 带返回值,带形参的,类似的一共有9个宏,最大带9个形参 如:DECLARE_DELEGATE_NineParams
DECLARE_DELEGATE_RetVal_OneParam(int32,FDelegateTestD,FString&);
声明并绑定代理
(空了再写................................................................)