瞧,这是UE4 C++

来源:互联网 发布:淘宝抢购需要刷新吗 编辑:程序博客网 时间:2024/05/16 17:21

http://www.cnblogs.com/NEOCSL/p/4008416.html

在Unreal Wiki上有一系列进入UE4 C++的文章,其中有一个专题非常有用。标题也很有意思。我们开始UE4 C++之路吧

  1.那么怎么入手学习UE4 C++呢?

  以前我们都是从PlayerController,pawn,Camera开始虚幻之路的,方法其实是传承下来的Wiki建议大家从PlayerController或是Blueprint扩展开始。

  ①Hello怎么world呢?

  ClientMessage("Hello world!");

  很简答不是吗

 

  2.搞不清. 和->

  有时候我们能看到代码中有两种指向. 和-> what the hell is this mean?

  ->表示该变量是一个数据指向哪里的指针。FVector* LocationPtr;    指针  

  .表示变量时实际的值。例如 Fvector location;    location.X=5;就是直接访问值

   

       LocationPtr=&Location;    //Location这个变量的地址设置成指针LocationPtr;

    LocationPtr->X返回的就是5啦

   再用上面学到的知识来将其输出

  ClientMessage(FString::SanitizeFloat(LocationPtr->X));  

     瞧是不是很简单:)

 

  总结一下:当你有一个实际的变量就使用.,就像unrealscript和Java等语言中的做法一样。

  当你事用指针的时候,你不确定他是否已经指向了某件东西,你必须得检测一下

  if(!LocationPtr)return;  //那就返回他,因为他没有指向任何东西

  如果向前面设置的那样

  LocationPtr=&location;

  LocationPtr->X;  //这个指针就是这样访问他的变量的

 

  3.::这是什么鬼玩意?

  这告诉我们一个函数或是变量的域名空间的范围

  UUnrealEdEngine::Init

  这告诉我们这是类UUnrealEdEngine的初始化函数

  Super::Init(InEngineLoop)

  因为上面引擎的Init是虚函数,你必须得访问他的父类函数

 

  倘若你写了两个类AMyTree和AMyFlower.两个类都有一个获取位置的函数

  FVector GetLocation() const;

  为什么要引入域名空间::这种超级麻烦的东西?因为C++过于底层。你有权利获取Global域名空间,如果在一个类外你仅仅是声明了一个变量或者函数或者结构

  static const FVector MyGlobalVector=FVector(2,4,16);

  FORCEINLINE void MyVeryGlobalFunction();

   {

      //处理...
  }

  那么这些符合将会进入所有域名空间并且被所有读取认识,这对C++的operators非常有用,例如你定义的+,-,*除等运算符。

  但是对于你定义的那些小类,例如AMyTree和AMyFlower将会引起麻烦,如果你不使用::将会让编译器困惑是哪个GetLocation,所以你使用::来告诉编译器

  FVector AMyFlower::GetLocation()const

  {

    //code...
  }

 

  FVector AMyTree::GetLocation()const

  {

    //code..

  }

  因此如果你不使用域名空间,你讲不得不再你的代码中每一个函数的命名都将是唯一的,如果你没有好的记忆和管理方法,估计这很难做到。

  最后你只需要知道::就是一个简单的标签,告诉你这个函数或是变量属于哪个类的。

 

紧接着上面学到的指针和域名空间我们继续逛Unreal 4 wiki。

  1.怪形 T

  在自己很早学习编程的时候看到过匈牙利表示法,记得是微软的开发者Charles提出来的,尽管看起来很美好但是从来没有遵循过。

  其实那些前缀T就是这回道理。UE4 有自己的定义类,所以我们的标题不叫C++学习。

  TArray

  TSharedRef

  TWeakPtr

  TArray

  之类,带前缀T表示Template class,前缀能让你轻易地区分变量名。

  UE4中的T前缀变量应该让你想起两件东西

  ①一种游戏类型

  ②一种变量类型

  当然UE4中还有T,F,U,A,I等前缀去这里看Epic's Naming Conventions

  

  2.你的痛:指针

  伙计,*和&到底是什么东西?怎么用?着实让我头大:S

  这也是新手学习C++最难得地方了吧,但是一旦你掌握了指针你将会快乐的编写UE4 C++了

  总的来说指针既强大又危险,指针需要你成为一位勤勉的人,与之换来的将赋予你速度和力量。对,就像葵花宝典一样。你得有挥刀的决心XD

  

  ①一个指针必须指向一个数据存储的存储地址

  ②为了获取地址你就得使用&

  FVector Location=FVector(1,2,9000);

  FVector* LocationPtr;

  LocationPtr=&Location;

  ③访问数据前,永远检测你的指针

  Check(LocationPtr);

  或者

  if(!LocationPtr)return;

  你必须这样做,因为你永远不知道什么时候指针中存储的值是有效的

  你可以重定向

  Fvector NewVector=FVector::ZeroVector;

  if(LocationPtr)

  {

    NewVector=*LocationPtr;   //重定向指针
  }

  if(!LocationPtr)return;

  const float XValue=LocationPtr->X;

 

  3.总结:为什么使用指针?

  有很多人喜欢看总结篇,因为貌似总结篇很能讲一些道理,这次我们也不例外:)

  ①指针能让你获取地址,试想一下你当前在编写context,但是要访问一个不是这个context的变量,地址能给你很快的传回

  ②指针还能让你获取大量的数据,从而避免还得创建复制这一类型

  ③指针给你一种活链接,无论你的数值怎么变化,指针都无需更新因为它仅仅是一个指向。就像超级链接一样,你尽管修改自己的网页,URL给我~

  

  Example:我们来获取一个超级超级远的数据

  假设你有一个角色类,他是众多银河,子星系的星球的一部分,我们仅仅是要获取他的盔甲,估计你会这样作:

  GetGalaxy()->GetSolarSystem()->GetPlanet()->GetMainCharacter()->GetCurrentArmor();

  上边的访问是不是看起来都很废?虽然能解决问题

  

  如果只做一次指针指代能好一点?

  FArmorStruct* TheArmor=& GetGalaxy()->GetSolarSystem()->GetPlanet()->GetMainCharacter()->GetCurrentArmor();

  既然做了一次指代你就不需要再写下面的代码了:

GetGalaxy()->GetSolarSystem()->GetPlanet()->GetMainCharacter()->GetCurrentArmor().Durability;GetGalaxy()->GetSolarSystem()->GetPlanet()->GetMainCharacter()->GetCurrentArmor().Color;GetGalaxy()->GetSolarSystem()->GetPlanet()->GetMainCharacter()->GetCurrentArmor().Size;  瞧,为了偷懒我都直接复制过来了。  这样不仅难读,同时又浪费CPU时间  然后你会这样写  if(!TheArmor) return;   //永远检测指针TheArmor->Durability;TheArmor->Color;TheArmor->Size;  上述使用了指针,你或许会问,为什么我不是用FArmorStruct ArmorVar=
GetGalaxy()->GetSolarSystem()->GetPlanet()->GetMainCharacter()->GetCurrentArmor();  而是使用指针?  假设一下,若果有众多数据你将会进行大量的赋值拷贝。我在写iCLoud的时候因为不能将多object直接传送到云端谢了大量代码变量抄写,这可真的非常痛苦。除此之外这些数据就写在一片连续的内存中。  第二点是,你将会失去前面说的链接功能,本地的变量修改了,你的指针完全能抄写回来,因为他是一种链接记着吗
  

 

 

 

 

 

 

 

 

 1.虚幻中的类前缀你会见到U,A,F,以下就是很好的罗列其中的意义

  •  U: UObject继承过来的,例如UTexture
  •    A: AActor继承过来的,例如AGameMode
  •    F: 其他的类和结构,例如FName, FVector
  •    T:模板,例如TArray,TMap,TQueue
  •    I: 接口类,ITransaction
  •    E:枚举, ESelectionMode
  •  B: Boolean, bEnabled

  2.区分大小写!

  用宏定义来包裹C++代码

  UCLASS 来包裹类

  USTRUCT 包裹结构

  UFUNCTION 包裹功能

  UPROPERTY 包裹属性

  这是例子 

复制代码
USTRUCT()  struct FVector2D  {    UPROPERTY()    float X;    UPROPERTY()    float Y;    UFUNCTION()    float GetLength() const;  };
复制代码

  3.虚幻主义者

  UE4代码中使用自己的基础类型,不适用C++中的(char,short,int,long等)

  ①取而代之的是:int32,uint32,uint64,TCHAR,ANSICHAR等  

  数值类型在NumericLimits.h中声明,可以详细阅读查询

  

  ②一般的结构数据类型有

  FBox,FColor,FGuid,FVariant,FVector,TBigInt,TRange  

 

  ③容器

  TArray,TSparseArray-动态数组

  TLinkedList,TDoubleLinkedList

  TMap-键值对哈希表

  TQueue-队列

  TSet-非有序集

  

  ④代理:这一部分中文更加拗口没有翻译的意义,实际使用的时候我会再解释

  Unicast and multicast delegates

  thread-safe variants

 

  ⑤智能指针

  TSharedPtr,TSharedRef-一般传统的C++对象

  TWeakPtr-一般传统的C++对象

  TWeakObjPtr-UObject

  TAutoPtr,TScopedPtr

  TUniquePtr

  原谅我偷懒直接复制,用了才知道怎么回事

  Similar to boost:: & std:: implementations
  Also thread-safe variants

  ⑥String 类型

  FString- 通常的String

  FText- 本地化,在Slate UI中常使用

  FName-在UObject中常使用的,String哈希.FName是大小写敏感的

  

  ⑦String文字

  TEXT()- 创建一个通用的String类型,TEXT("Hello");

  LOCTEXT()-创建一个本地化文字,LOCTEXT("Namespace","Name","Hello");

  NSLOCTEXT()-在一个域名空间内的本地化,NSLOCTEXT("Name","Hello");

  

 


0 0
原创粉丝点击