欢迎光临散文网 会员登陆 & 注册

UE4笔记1

2022-10-18 11:12 作者:芯无波澜  | 我要投稿

Unreal note

参照Unreal官方文档 C++编程教程

网址:https://docs.unrealengine.com/latest/CHN/Programming/Tutorials/index.html

/*---------------------------------------------------基础类介绍---------------------------------------------------------------*/

虚幻基础类:

Unreal对象 :UObject 虚幻中大部分类都继承于此类
 

/*---------------------------------------------------编程风格---------------------------------------------------------------*/

派生自Actor的类前缀为A,如AController

派生自"对象(UObject)"的类前缀为 U,如 UComponent。

"枚举"的前缀为E,如 EFortificationType。

"接口(interface)" 类的前缀通常为 I,如 IAbilitySystemInterface。

"模板(template)" 类的前缀为 T,如 TArray。

派生自 SWidget(Slate UI)的类前缀为 S,如 SButton。

其余类的前缀均为 字母 F ,如 FVector。

因为不同平台基础类型的尺寸不同,如 short、int 和 long,UE4 提供了以下类型,可用作替代品:

int8/uint8 :8 位带符号/不带符号 整数

int16/uint16 :16 位带符号/不带符号 整数

int32/uint32 :32 位带符号/不带符号 整数

int64/uint64 :64 位带符号/不带符号整数

标准 浮点 (32-bit) 和 双倍(64-bit)类型也支持浮点数。

详情可查看URL : https://docs.unrealengine.com/latest/INT/API/Runtime/Core/Math/TNumericLimits/index.html

打印log记录 : 使用UE_LOG()宏

/*----------------------------------------------------字符串处理-----------------------------------------------------------------*/

字符串处理使用FString,类似于std::string

使用 TEXT() 宏可新建一个 FString:

FString MyStr = TEXT("Hello, Unreal 4!").

除了FString,还有一个FText可使用,其功能与FString相似,但是是用于本地化文本的。

使用 NSLOCTEXT 宏可新建一个 FText。此宏拥有默认语言的命名空间、键和一个数值。例如:

Text MyText = NSLOCTEXT("Game UI", "Health Warning Message", "Low Health!")

FName 将经常反复出现的字符串保存为辨识符,以便在对比时节约内存和 CPU 时间。

FName文档:

https://docs.unrealengine.com/latest/INT/API/Runtime/Core/UObject/FName/index.html

TCHAR : 宽字符版

UE4 字符串在后台使用 TCHAR 阵列将数据保存在 UTF-16 编码中。使用返回 TCHAR 的重载解引用运算符可以访问原始数据。

类似于std::string::c_str();

FChar:窄字符版

/*---------------------------------------------------容器类(全部是模板类)---------------------------------------------------------------*/

与std里面的容器相似,但是此处多出了许多功能

TArray:

用法:

TArray<AActor*> ActorArray = GetActorArrayFromSomewhere();

// 告知当前 ActorArray 中保存的元素(AActors)数量。

int32 ArraySize = ActorArray.Num();

/*--------------------------------------分割线------------------------------------------*/

// TArrays 从零开始(第一个元素在索引 0 处)

int32 Index = 0;

/*--------------------------------------分割线------------------------------------------*/

// 尝试获取在给定索引处的元素

TArray* FirstActor = ActorArray[Index];

/*--------------------------------------分割线------------------------------------------*/

// 在阵列末端添加一个新元素

AActor* NewActor = GetNewActor();

ActorArray.Add(NewActor);

/*--------------------------------------分割线------------------------------------------*/

// 只有元素不在阵列中时,才在阵列末端添加元素

ActorArray.AddUnique(NewActor); // 不会改变阵列,因为 NewActor 已被添加

/*--------------------------------------分割线------------------------------------------*/

// 移除阵列中所有 NewActor 实例

ActorArray.Remove(NewActor);

/*--------------------------------------分割线------------------------------------------*/

// 移除特定索引处的元素

// 索引上的元素将被下调一格,以填充空出的位置

ActorArray.RemoveAt(Index);

/*--------------------------------------分割线------------------------------------------*/

// RemoveAt 的高效版,但无法保持元素的排序

ActorArray.RemoveAtSwap(Index);

/*--------------------------------------分割线------------------------------------------*/

// 移除阵列中的所有元素

ActorArray.Empty();

注解(重要):

1、需注意:TArray 是当前唯一能被标记为 UPROPERTY 的容器类。这意味着无法复制、保存其他容器类,或对其元素进行垃圾回收。

2、如果想要保存在里面的元素自动清理垃圾,比如容器里面保存的是指针,可以在上面加上一个宏 UPROPERTY,

这将假定 TArray 被标记为 UPROPERTY,并存储 UObject 派生的指针。具体示例如下所示:

UPROPERTY()

TArray<AActor*> actorArray;

TMap:

它是键值对的集合,与std::map相似。

具体API文档URL:

https://docs.unrealengine.com/latest/INT/API/Runtime/Core/Containers/TMapBase/index.html

TSet:

TSet 保存唯一值的合集,与 std::set 相似。TArray 通过 AddUnique 和 Contains 方法可用作集。然而 TSet 可更快实现这些操作,

但无法像 TArray 那样将它们用作 UPROPERTY。TSet 不会像 TArray 那样将元素编入索引。

示例:

TSet<AActor*> ActorSet = GetActorSetFromSomewhere();

int32 Size = ActorSet.Num();

// 如集尚未包含元素,则将其添加到集

AActor* NewActor = GetNewActor();

ActorSet.Add(NewActor);

// 检查元素是否已包含在集中

if (ActorSet.Contains(NewActor))

{

    // ...

}

// 从集移除元素

ActorSet.Remove(NewActor);

// 从集移除所有元素

ActorSet.Empty();

// 创建包含 TSet 元素的 TArray

TArray<AActor*> ActorArrayFromSet = ActorSet.Array();

迭代器:

void RemoveDeadEnemies(TSet<AEnemy*>& EnemySet)

{

    // 从集的开头开始迭代到集的末端

    for (auto EnemyIterator = EnemySet.CreateIterator(); EnemyIterator; ++EnemyIterator)

    {

        // * 运算符获得当前的元素

        AEnemy* Enemy = *EnemyIterator;

        if (Enemy.Health == 0)

        {

            // RemoveCurrent 由 TSets 和 TMaps 支持

            EnemyIterator.RemoveCurrent();

        }

    }

}

// 将迭代器移回一个元素

--EnemyIterator;

// 以一定偏移前移或后移迭代器,此处的偏移为一个整数

EnemyIterator += Offset;

EnemyIterator -= Offset;

// 获得当前元素的索引

int32 Index = EnemyIterator.GetIndex();

// 将迭代器重设为第一个元素

EnemyIterator.Reset();

For-each 循环

迭代器很实用,但如果只希望在每个元素之间循环一次,则可能会有些累赘。每个容器类还支持 for each 风格的语法在元素上进行循环。

TArray 和 TSet 返回每个元素,而 TMap 返回一个键值对。

// TArray

TArray<AActor*> ActorArray = GetArrayFromSomewhere();

for (AActor* OneActor :ActorArray)

{

    // ...

}

// TSet - 和 TArray 相同

TSet<AActor*> ActorSet = GetSetFromSomewhere();

for (AActor* UniqueActor :ActorSet)

{

    // ...

}

// TMap - 迭代器返回一个键值对

TMap<FName, AActor*> NameToActorMap = GetMapFromSomewhere();

for (auto& KVP :NameToActorMap)

{

    FName Name = KVP.Key;

    AActor* Actor = KVP.Value;

    // ...

}

着色器开发文档:

https://docs.unrealengine.com/latest/CHN/Programming/Rendering/ShaderDevelopment/index.html

界面设计使用UMG(Unreal Motion Graphics)

参考文档:

https://docs.unrealengine.com/latest/CHN/Engine/UMG/index.html

除此之外,还有Slate用户界面框架

参考文档:

https://docs.unrealengine.com/latest/CHN/Programming/Slate/Architecture/index.html

/*-----------------------------------------------调试时使用断言------------------------------------------------------------*/

断言:

check(expression);

check(Mesh != nullptr);

check(bWasInitialized && "Did you forget to call Init()?");

checkf(expression, ...);

checkf() 宏允许您将一个表达式断言为 true,并在调试时打印有帮助的额外信息。在编译行为方面,它和 check() 行为相同。

checkf(WasDestroyed, TEXT( "Failed to destroy Actor %s (%s)"), *Actor->GetClass()->GetName(), *Actor->GetActorLabel());

checkf( TCString<ANSICHAR>::Strlen( Key ) >= KEYLENGTH( AES_KEYBITS ), TEXT( "AES_KEY needs to be at least %d characters" ), KEYLENGTH( AES_KEYBITS ) );

verify(expression);

启用 DO_CHECK 后,此宏的行为与 check() 完全相同。然而 DO_CHECK 被禁用后表达式仍然在执行。

可使用它确认变量的指定符合假设。

verifyf(expression, ...);

verify() 宏固定执行表达式,verifyf() 也是如此。和 checkf(); 一样,它通过额外的调试信息停止执行

verifyf(Module_libeay32, TEXT("Failed to load DLL %s"), *DLLToLoad);

/*-----------------------------------------------动画播放------------------------------------------------------------*/

//此处摘录于:http://blog.csdn.net/JustinReynard/article/details/44153911

UE4的动画通知和UE3的通知其实在本质上是一样的,但是在UE4 更多的时候使用BP进行了封装,

不像UE3的时候直接在Pawn的代码中直接调用。

UE4允许在每个动画的时间帧上添加我们需要执行动画通知。

 

UE4的动画通知主要分为两类:

 

Notify和Notify State.

 

下面简单的比较比较一下两种通知不一样的地方。

Notify,属于单帧的概念。什么是单帧呢?就是角色动画上的一帧,没有时间段的概念。

比如说在这个动画执行到1/4的地方播放一个声音,我们就可以Notify。

Notify State 它有三个通知的函数:

 

Notify Start: 这个通知序列刚进入时调用

 

NotifyEnd:  这个通知序列结束时调用

NotifyTick :在这个通知执行过程中每Tick都会调用的函数。这个可以理解为不断回调的函数或者更新函数。

BlendSpace和BlendSpaceID的却别:

 

BlendSpaceID 只有一个轴的动画混合空间,这而BlendSpace是一个包含两个轴的动画混合空间


UE4笔记1的评论 (共 条)

分享到微博请遵守国家法律