虚幻C++学习笔记

首先在学习虚幻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::StaticLoadObject
  • UObject::StaticLoadClass->LoadObject->UObject::StaticLoadObject
  • LoadClass->UObject::StaticLoadClass->LoadObject->UObject::StaticLoadObject
  • ConstructorHelpers::FObjectFinder->LoadObject->UObject::StaticLoadObject
  • ConstructorHelpers::FClassFinder->UObject::StaticLoadClass->LoadObject->UObject::StaticLoadObject
  • FSoftObjectPath->ResolveObject->UObject::FindObject
  • FSoftObjectPath->TryLoad->UObject::StaticLoadObject
  • FSoftClassPath->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&);

声明并绑定代理

 (空了再写................................................................)

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DPAJ_L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值