UE4 c++ 简要入门

1. c++ 与蓝图

  • C++实现Gameplay的构建模块,蓝图用这些模块实现有意思的Gameplay
  • 创建流程
    • 通过UE4内的类向导生成,避免自己直接去VS里创建
    • 指定适合的父类
  • UProperty(): 暴露变量给编辑器
    • EditAnywhere & VisibleAnywhere
      • EditAnywhere: 编辑器属性窗口可见,不可编辑
      • VisibleAnywhere: 编辑器属性窗口可见,可编辑
    • BlueprintReadOnly & BlueprintReadWrite
      • BlueprintReadOnly: 蓝图可读,不可修改
      • BlueprintReadWrite:蓝图可读,可修改
    • 其他的一些宏,定义在ObjectMacro.h的namespace UP中
  • UFUNCTION(): 公开方法给蓝图
    • BlueprintCallable:蓝图可调用
    • BlueprintImplementableEvent: 蓝图实现,c++调用(thunk)
    • BlueprintNativeEvent:类似上,不给c++可提供默认方法,用[func_name]_implementation实现
  • Reload机制,可不关闭虚幻编辑器,编译VS代码
  • 根据C++类,构建蓝图类,实现Gameplay
  • Gameplay的常用类
    • UObject, AActor, UActorComponent, UStruct
    • UObject:提供虚幻基础功能,一般不直接继承。如:
      • 反射属性和方法
      • 序列化,垃圾回收,按名称查找UObject
      • 联网,等等
    • AActor:派生自UObject
      • 基本对象,可添加UActorComponent
      • BeginPlay()
      • Tick()
      • EndPlay():对象销毁时调用
    • UStruct
      • 添加USTRUCT()标记
      • 传统数据类型,自己需要管理生命周期
  • 反射机制
    • Reflection is the ability of a program to examine itself at runtime
    • 可选,需要自己设置对应标签
      • UCLASS: 类必须派生自UObject,为该类生成反射数据
      • USTRUCT:为结构体生成反射数据
      • GNERATED_BODY: 替换为该类的样板代码
      • UPROPERTY, UFUNCTION:上面已经介绍过了
  • Actor迭代器
// 查找所有当前UObject实例
for (TObjectIterator<UObject> It; It; ++It)
{
    UObject* CurrentObject = *It;
    UE_LOG(LogTemp, Log, TEXT("Found UObject named:%s"), *CurrentObject->GetName());
}
APlayerController* MyPC = GetMyPlayerControllerFromSomewhere();
UWorld* World = MyPC->GetWorld();

// 正如对象迭代器一样,您可以提供一个具体类来仅获得
// 属于该类或派生自该类的对象
for (TActorIterator<AEnemy> It(World); It; ++It)
{
    // ...
}

2. 内存管理与垃圾回收

垃圾回收

  • UE4使用反射机制进行垃圾回收
  • 引用计数的垃圾回收
  • Actor通常不会垃圾回收,必须手动调destroy(),然后在下次垃圾回收周期时回收
  • 类中的属性必须标记为UPROPERTY,才会被正常引用计数

3. 常用数据类型

类命名前缀

  • 派生自Actor,prefix A, such as AController
  • 派生自Object, prefix U, such as UComponent
  • Enums, prefix E, such as EFortificationType
  • Interface,prefix I, such as IAbilitySystemInterface
  • Template, prefix T, such as TArray
  • SWidget(Slate UI), prefix S, such as SButton
  • other: prefix F, such as FVector

常用的

  • 整型和浮点数
    • int8/uint8 :8位有符号/无符号整数
    • int16/uint16 :16位有符号/无符号整数
    • int32/uint32 :32位有符号/无符号整数
    • int64/uint64 :64位有符号/无符号整数
    • 浮点数也支持标准 浮点float(32位) 和 双精度double(64位)类型
    • TNumericLimits<t>: 查找该类型的最大值和最小值
  • 字符串
    • FString
      • 可变字符串,类似std::string
      • 使用TEXT()宏创建
      •    	FString MyStr = TEXT("Hello, Unreal 4!")
        
    • FTEXT
      • 类似FString,但多用于本地化
      • 使用NSLOCTEXT()宏,定义名称控件,键和值
      •   FText MyText = NSLOCTEXT("Game UI", "Health Warning Message", "Low Health!")
        
    • FName
      • 存储反复出现的字符串,节省内存和时间
    • TCHAR
      • 单独字符
  • 容器
    • TArray, 类似std::vector
      •   TArray<AActor*> ActorArray = GetActorArrayFromSomewhere();
          // get length of the array
          int32 ArraySize = ActorArray.Num();
          // get particular actor by index
          int32 index = 0;
          AActor* FirstActor = ActorArray[index];
          //Append new actor
          AActor* NewActor = GetNewActor();
          ActorArray.Add(NewActor);
          //Append new UNIQUE Actor
          ActorArray.AddUnique(NewActor);
          //remove actor
          ActorArray.Remove(NewActor);
          //remove by index
          ActorArray,RemoveAt(index);
          //more efficient removeAt, but DO NOT gurantee swap order
          ActorArray.RemoveAtSwap(index);
          //empty array
          ActorArray.Empty();		
        
      • TArray 会自动对其元素进行垃圾回收,只要标记了反射
      •   UCLASS()
          class UMyClass : UObject
          {
              GENERATED_BODY();
          
              // ...
          
              UPROPERTY()
              TArray<AActor*> GarbageCollectedArray;
          };
        
    • TMap,类似std::map
      • map.Contains(k), map[k], map.Add(k, v)
      • map.Remove(k), map.Empty()
    • TSet,类似std::set
      • set.Add(x), set.Contains(x), set.Num(), set.Remove(x)
      • set.Empty()
      • set…Array()
    • Iterator
      • example: Set Iterator
      void RemvoeDeadEnemies(TSet<AEnemy*>& EnemySet){
      	// from start of set, iterate to the end
      	for (auto EnemyIterator = EnemySet.CreateIterator(); EnemyIterator; ++EnemyIterator){
      	AEnemy* Enemy = *EnemyIterator;
      	if (Enemy.Health == 0){
      		EnemyIterator.RemoveCurrent();
      	}
      }
      
      • 常用操作
        • –EnemyIterator
        • EnemyIterator += Offset, EnemyIterator -= Offset
        • int32 index = EnemyIterator.GetIndex()
        • EnemyIterator.ReSet() //复位到第一个元素
    • For each,简化版Iterator,全部元素循环一次
      • TArray, TSet, TMap
      //TArray
      TArray<AActor*> ActorArray = GetArrayFromSomewhere();
      for (AActor* ActorArray :ActorArray){
      	...
      } 
      //TSet
      TSet<AActor*> ActorSet = GetSetFromSomewhere();
      for (AActor* Actor :ActorSet){
      ...
      }
      //TMap
      TMap<FName, AActor*> NameToActorMap = GetMapFromSomewhere();
      for (auto& KVP : NameToActorMap){
      	FName Name = KVP.Key;
      	AActor* Actor = KVP.Value;
      	...
      }
      
    • Class 和 Hash函数
      • 能用作Map和Set的Class必须自定义Hash函数
      • 存object用GetTypeHash(const FMyClass& MyClass)
      • 存pointer用GetTypeHash(const FMyClass* MyClass)
      class FMyClass
      {
          uint32 ExampleProperty1;
          uint32 ExampleProperty2;
      
      // 散列函数
          friend uint32 GetTypeHash(const FMyClass& MyClass)
          {
          	// HashCombine是将两个散列值合并的效用函数
              uint32 HashCode = HashCombine(MyClass.ExampleProperty1, MyClass.ExampleProperty2);
              return HashCode;
          }
      
          // 为了演示目的,两个相同的对象
          // 应该始终返回相同的散列代码。
          bool operator==(const FMyClass& LHS, const FMyClass& RHS)
          {
              return LHS.ExampleProperty1 == RHS.ExampleProperty1
                  && LHS.ExampleProperty2 == RHS.ExampleProperty2;
          }
      };
      
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值