善始者实繁,能克终者盖寡。
盖为本书的阅读笔记。ps.有读过这本书的朋友指点一下我就再好不过了
Chapter01:UE_LOG信息打印,为基础篇,要点有三
1、logging with UE_LOG
UE_LOG(LogTemp,Warning,TEXT("Some warning message");
与C语言的printf函数类似,可以使用格式化,
UE_LOG(LogTemp,Warning,TEXT("Text, %d,%f,%s"),intVar,floatVar,*fstringVar);
但字符串指针需要加*
2、通过Fstring::Printf()创建新的FString
FString name="Tim";
int32 mana=450;
Fstring string=FString::Printf(TEXT("Name=%s" mana="%d"),*name,mana);
3、通过FString::Format创建新的FString
TArray<FStringFormatArg> args;
args.Add(FStringFormatArg(name));
args.Add(FStringFormatArg(mana));//name和mana的声明如上条
FString string=FString::Format(TEXT("NAME={0} MANA={1}"},args);
Chapter02:创建与蓝图交互的C++类,实操篇,要点有四,
至于UStrcut章节和UEnum与原生C++的strcut和enum类似。原书实例构建并不适用。
生词:
qualifers:资格,修饰语
There are a number of qualifers that we can add to each UPROPERTY,
recipe:秘诀,菜谱
To use this recipe,
instantiate:实例化
But how do you instantiate them?
particular:特别的; 详细的; 独有的; 挑剔的;
derived from a particular C++ class
Category:类型,部门,种类,类别,类目; [逻,哲] 范畴; 体重等级;
01)、Make a UCLASS 继承自UObject
UE4中,用户可以使用原生的C++语言,只要适当的调用new和delete来创建和销毁用户自定义的物体当然也可以自定义一个C++物体,通过使用UCLASS声明这个物体。UCLASS使用了UE4的智能指针和内存管理,可以被Blueprint访问。
创建基于Object的一个C++类,特点,不能够在场景中放置:
this chapter's example will not be placeble in the level,但是可以在蓝图中使用
UCLASS()
class SCRIPTINGSTARTER_API UUserProfile : public UObject
{
GENERATED_BODY()
};
其中通过传入UCLASS()中的关键字定义与蓝图交互的行为:
Blueprintble,可以基于该类创建一个Blueprint Class
BlueprintType:使用该关键字使得可以在其他Blueprint类中作为变量
02)、在蓝图中访问类成员,通过UPROPERTY来设置
C++类成员必须声明为一个具有UPROPERTY属性的成员才能够使得蓝图访问,UPROPERTY会自动的生成一个get和set方法,不能够被声明成private,如果没有被声明成public和protected程序会报错。
UCLASS(Blueprintable)
class SCRIPTINGSTARTER_API UUserProfile : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Stats)
float Armor;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Stats)
float HpMax;
};
针对该类创建生成的BluePrint Class的属性窗口会出现Armor和HpMax两个变量
UPROPERTY传递的宏:
EditAnywhere:意味着UPROPERTY()下的变量既可以在Blueprint类中修改也可以在关卡中被实例化的对象身上修改
EditDefaultsOnly:只在蓝图中修改,不在实例上修改
EditInstanceOnly:只在实例上修改,不在蓝图本身修改
BlueprintReadOnly|BluePrintReadWrite决定了该变量是否在蓝图中只读
BlueprintsDefalutsOnly使得数据成员不能再蓝图运行时修改
Category:为该变量添加条目
03)、USTRUCT创建结构体,UENUM创建枚举,通过在类中使用UPROPERTY来暴露给蓝图使用
USTRUCT(Blueprintable)
struct FMystruct
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Info)
FString Name;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Info)
int32 Number;
};
UENUM(Blueprintable)
enum Status {
Stopped UMETA(DsiplayName="Stopped"),
Moving UMETA(DisplayName="Moving"),
Attacking UMETA(DisplayName="Attacking"),
};
UCLASS(Blueprintable)
class CODEBASIC_API UUserprofile : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Stats)
float Armor;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Stats)
float HpMax;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Info)
FMystruct Mystruct;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Status)
TEnumAsByte<Status> status;
};
和UCLASS一样,传入Blueprintable关键字可以使得蓝图访问
04)、UFUNCTION使得C++创建的函数能够被蓝图调用。
所有的C++函数都可以被创建为UFUNCTION函数
.h文件
UCLASS(Blueprintable)
class CODEBASIC_API ATestUfunction : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Propeties)
FString Name;
UFUNCTION(BlueprintCallable, Category = Propeties)
FString ToString();
};
.cpp文件
FString ATestUfunction::ToString() {
return FString::Printf(TEXT("An instance of UProfile:%s"), *Name);
}
通过传入BlueprintCallable使得基于该C++类的蓝图类可以使用ToString方法
原书中:FString::Printf("An instance of UProfile:%s", *Name);编译不通过,
使用TEXT构建字符串,如Chapter01节所述
Chapter03:内存管理和智能指针这一章节对初学者难度有点大,不方便上手
先行知识,
C语言中动态内存分配是通过malloc和free,C++中给对象分配内存则是用new。
C++也提供了一种智能指针方便用户的内存管理操作
UE4中是基于UObject的,该类提供了内存的智能分配与管理操作,采用一种称为
引用计数的系统<reference counting system>。
书中本节中也提到了UE4为常规C++类提供了TSharedPtr 和TWeakPtr用于方便内存管理
当然,我也得承认自己是初学者。先放一放第三章的内容。等到用到时再做一遍梳理。
Chapter04:Actor和Component
生词:
demonstrate:论证;证明,证实;显示,展示;演示,说明
The next two recipes demonstrate how to use either composition or inheritance to customize Actors.
preprocessor:预处理程序
This preprocessor statement
subclass:子类
you'll need to have an Actor subclass ready to instantiate
其实在看到这一章时就感觉到这本书另一个作者的存在了,不过这书的确是合作写的。另外吐槽句VS对unity的代码提示特别棒,但对Unreal。。。
1)、Actor类(一个可以在世界中放置或生成的对象)
1)、构造函数
AMyFirstActor();
PrimaryActorTick.bCanEverTick = true;
用于设置Tick是否每帧调用
2)、BeginPlay()
用于游戏运行时的初始化
virtual void BeginPlay() override;
在C#中继承重写时需要加override的,但C++中override可以不加
3)、Tick()
virtual void Tick(float DeltaTime) override;
每帧调用的函数
上述三个函数都可以保留或者不要,以简化程序的结构
2)、创建GameMode类动态加载Actor
本书这里讲解的不好,没有铺垫知识,是不是得吐槽下作者呢。不过也可能是由于早期版本导致的。
GetWorld()->SpawnActor<AMyFirstActor>(AMyFirstActor::StaticClass(), &SpawnLocation);
原书代码并不能执行。
篇一只能至此收尾。后记:测试了一下,早期版本的UE4的代码提示的确比UE18版本后的要好。后面的UE4版本改为试一试版本(4.14)