最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

TomLooman_ActionRoguelike_第二章項(xiàng)目與版本

2023-08-09 18:21 作者:別叫我小紅  | 我要投稿

該專欄用于保存對(duì)TomLooman的ActionRoguelike項(xiàng)目的學(xué)習(xí)筆記,學(xué)習(xí)過(guò)程中的思考與記錄不一定準(zhǔn)確。


教程參考:https://github.com/tomlooman/ActionRoguelike

基于UE5.0的項(xiàng)目實(shí)現(xiàn):https://github.com/CarolBaggins2023/TomLooman_ActionRoguelike_Tutorial



2023_07_24

C++基礎(chǔ)類,添加組件(第三人稱攝像機(jī)),綁定運(yùn)動(dòng)輸入,角色設(shè)置

?

建立角色的C++類,繼承自Character,

Scharacter.h文件如下,

"CoreMinimal.h"頭文件包含一套來(lái)自UE的核心編程環(huán)境的普遍存在類型(包含F(xiàn)String,F(xiàn)Name,TArray等),通常被多數(shù)引擎的頭文件包含。

?

因?yàn)镾Character類繼承自Character類,基于Character類生成源代碼,所以包含"GameFramework/Character.h"頭文件。

?

"SCharacter.generated.h"是所有C++類都會(huì)包含的頭文件(SCharacter為該類的類名),UE將生成所有反射數(shù)據(jù)并放入該文件中。您必須將該文件作為聲明類型的標(biāo)頭文件中的最后一個(gè)包含語(yǔ)句,將其包含進(jìn)去,他必須在最下方,切記!

?

Uclass()是類說(shuō)明符,類聲明的語(yǔ)法如下

UCLASS([specifier, specifier, ...], [meta(key=value, key=value, ...)])

class ClassName : public ParentName

{

??? GENERATED_BODY()

}

Specifier為類說(shuō)明符,meta為類元數(shù)據(jù),兩者合稱為描述符,被傳入CLASS宏。這里的類說(shuō)明符和類元數(shù)據(jù)為空。

?

class ACTIONROGUELIKE_API ASCharacter中class后類名前的ACTIONROGUELIKE_API是一個(gè)宏,ACTIONROGUELIKE指代模塊名。在虛幻引擎的代碼中,MYGAME_API被用來(lái)標(biāo)記一些類以及函數(shù),從而將這些類和函數(shù)從模塊或者是插件中公布出去,即被MYGAME_API標(biāo)記的類和函數(shù)可以允許被其他模塊或者插件訪問(wèn),也就是控制代碼的可見(jiàn)性和模塊間的連接。模塊的含義參考:https://docs.unrealengine.com/5.2/zh-CN/module-properties-in-unreal-engine/

?

因?yàn)槲覀儎?chuàng)建的SCharacter類繼承自Character類,所以屬于游戲性類,游戲性類的前綴如下,

我們SCharacter的實(shí)例可以直接生成到世界場(chǎng)景中,所以我們代碼中的類名不是SCharacter,而是ASCharacter。

?

GENERATED_BODY()UE4 將這個(gè)標(biāo)記替換為該類型生成的所有必要的樣板代碼。引擎在背后為我們做了很多工作,生成了很多代碼。

?

結(jié)合SCharacter.cpp文件

?

ASCharacter::ASCharacter()類的構(gòu)造函數(shù)。

?

PrimaryActorTick.bCanEverTick = true;如果為true,則這個(gè)Character在每一幀都調(diào)用一次Tick函數(shù)。設(shè)置為false后可提升性能,默認(rèn)為false。

?

virtual void BeginPlay() override;游戲開(kāi)始或Character出生時(shí)被調(diào)用。

Super::BeginPlay();先調(diào)用ACharacter父類的BeginPlay,其它類成員函數(shù)類似。

?

Tick(float DeltaTime)DeltaTime為兩次Tick之間的時(shí)間間隔

?

virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;調(diào)用該函數(shù),完成該函數(shù)內(nèi)一系列語(yǔ)句,將player的某個(gè)input映射到某個(gè)函數(shù)(控制角色的某種行為)。

而且這里的UInputComponent就是上面說(shuō)的兩種游戲類種的另一類,因?yàn)椴荒苤苯硬贾玫绞澜鐖?chǎng)景中,所以不是AInputComponent,而是UInputComponent。

?

創(chuàng)建C++的藍(lán)圖子類。C++和藍(lán)圖應(yīng)該混合使用,因?yàn)橐恍┎僮鞅热缣砑觤esh,在藍(lán)圖中更方便。

?

“終于,到了第4個(gè)紀(jì)元,UE窺得一絲隔壁平行宇宙Unity的天機(jī)。下定決心,讓Actor們輕裝上陣,只提供一些通用的基本生存能力,而把眾多的“技能”抽象成了一個(gè)個(gè)“Component”并提供組裝的接口,讓Actor隨用隨組裝,把自己武裝成一個(gè)個(gè)專業(yè)能手。”

?

CapsuleComponent常用來(lái)處理碰撞和移動(dòng)。

ArrowComponent用于指示方向。

這里的mesh(網(wǎng)格)是SkeletonMeshComponent,虛幻引擎中角色的基礎(chǔ)資產(chǎn)是 骨骼網(wǎng)格體 資產(chǎn),這種資產(chǎn)包含角色的一個(gè)可視化網(wǎng)格體(即角色的幾何模型渲染結(jié)果),以及角色的一個(gè)包含骨骼數(shù)據(jù)(用于為角色制作動(dòng)畫)的骨架。

?

CharacterMovementComponent?能夠使人身不使用剛體物理即可行走、跑動(dòng)、飛行、墜落和游泳。 其為角色特定,無(wú)法被任何其他類實(shí)現(xiàn)。?

?

每個(gè)Actor都有一個(gè)RootComponent。一般有一個(gè)SceneComponent作為RootComponent,定義Actor在世界中的transform(變換,包括位置location,旋轉(zhuǎn)rotation,縮放scale),其它所有組件都需要attach到RootComponent上。

?

在SCharacter中添加兩個(gè)組件

UPROPERTY([specifier, specifier, ...], [meta(key=value, key=value, ...)])??? Type VariableName;

UPROPERTY是屬性說(shuō)明符,在聲明屬性時(shí),屬性說(shuō)明符?可被添加到聲明,以控制屬性與引擎和編輯器諸多方面的相處方式。這里的VisibleAnywhere指此屬性在所有屬性窗口中都可見(jiàn),設(shè)置后我們可以在編輯器的藍(lán)圖中看到Camera和SpringArm的各種屬性,如下


否則紅框的部分是不可見(jiàn)的。

UPROPERTY是實(shí)現(xiàn)UE中的“反射”的一種方式。

?

虛幻引擎反射系統(tǒng)?使用宏為提供引擎和編輯器各種功能,封裝你的類。也就是

反射就是在運(yùn)行狀態(tài)中

1.對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;

2.對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)屬性和方法;

即可以動(dòng)態(tài)的獲取信息以及調(diào)用對(duì)象的方法稱之為反射機(jī)制。

?

因?yàn)閁SpringArmComponent和UCameraComponent繼承自UObject,不能直接在世界中生成,所以類名的前綴是U。

攝像機(jī)(Camera) 代表了玩家的視角,比如玩家如何查看世界。

彈簧臂(SpringArm)組件努力與其對(duì)象(在這里是我們的Character)之間保持一個(gè)固定距離(TargetArmLength,不存在碰撞時(shí)的彈簧臂自然長(zhǎng)度)如果發(fā)生碰撞,就會(huì)使子對(duì)象收回,如果沒(méi)有碰撞,則發(fā)生回彈。

如果把SpringArm作為Camera的父項(xiàng),就可以創(chuàng)建一個(gè)第三人稱視角,且能保持Camera與SpringArm的對(duì)象(我們的Character)之間沒(méi)有遮擋物。(這里需要調(diào)用attach函數(shù),下面會(huì)做)


SpringArm始終保持遮擋物(白色方塊)不會(huì)擋住Camera拍攝Character的畫面。

?

在SCharacter.cpp中實(shí)例化SpringArm和Camera,

SpringArmComp = CreateDefaultSubobject<USpringArmComponent>("SpringArmComp");

CameraComp = CreateDefaultSubobject<UCameraComponent>("CameraComp");

形式如下,

CreateDefaultSubobject<類名>(在UE編輯器中顯示的名字)

1.CreateDefaultSubobject必須寫在Actor的無(wú)參構(gòu)造函數(shù) 中,否則crash;
2.CreateDefaultSubobject中的編輯器中顯示的名字參數(shù)在同一個(gè)Actor中不能重復(fù),否則crash;

?

SpringArmComp->SetupAttachment(RootComponent);

CameraComp->SetupAttachment(SpringArmComp);

將SpringArm附加到角色,將Camera附加到SpringArm。A“附加”到B,指A成為B的子組件。子組件的位置、旋轉(zhuǎn)和縮放是相對(duì)于其父組件或Actor。Attach的函數(shù)原型如下,

void SetupAttachment(USceneComponent* InParent, FName InSocketName = NAME_None);

如果不進(jìn)行attach,則會(huì)是如下的層級(jí)關(guān)系,SpringArm不會(huì)隨Character移動(dòng),Camera不會(huì)隨SpringArm移動(dòng)。


?

在SCharacter.h中聲明

void MoveForward(float val);
void MoveRight(float val);

在SCharacter.cpp中實(shí)現(xiàn)

void ASCharacter::MoveForward(float val) {
???
FRotator ControlRot = GetControlRotation();
???
ControlRot.Pitch = 0.0f;
???
ControlRot.Roll = 0.0f;
???
???
AddMovementInput(ControlRot.Vector(), val);
}
void ASCharacter::MoveRight(float val) {
???
FRotator ControlRot = GetControlRotation();
???
ControlRot.Pitch = 0.0f;
???
ControlRot.Roll = 0.0f;

???
FVector RightVector = FRotationMatrix(ControlRot).GetScaledAxis(EAxis::Y);
???
???
AddMovementInput(RightVector, val);
}

并在SetupPlayerInputComponent中調(diào)用

PlayerInputComponent->BindAxis("MoveForward", this, &ASCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &ASCharacter::MoveRight);
PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);

?

BindAxis的函數(shù)接口為template<class UserClass>
FInputAxisBinding& BindAxis( const FName AxisName, UserClass* Object, typename FInputAxisHandlerSignature::TMethodPtr< UserClass > Func )

第一個(gè)參數(shù)是在Project Setting里設(shè)置的(Axis)軸映射名如下(將外部輸入與該輸入下要觸發(fā)的事件綁定),第二個(gè)參數(shù)是調(diào)用此函數(shù)的對(duì)象?(涉及UE的委托機(jī)制),第三個(gè)參數(shù)是一個(gè)函數(shù)指針(將觸發(fā)的事件與成員函數(shù)綁定)。


?

BindAxis后,外部輸入會(huì)觸發(fā)類的成員函數(shù),所以要聲明、實(shí)現(xiàn)該成員函數(shù),并在函數(shù)內(nèi)進(jìn)行響應(yīng)。

在MoveForward的實(shí)現(xiàn)中,AddMovementInput的函數(shù)接口為

UFUNCTION(BlueprintCallable, Category="Pawn|Input", meta=(Keywords="AddInput"))
virtual void AddMovementInput(FVector WorldDirection, float ScaleValue = 1.0f, bool bForce = false);

該函數(shù)在所給的WorldDirection上增加一個(gè)外部輸入的變化量ScaleValue(ScaleValue<0則反向移動(dòng))

?

FRotator(旋轉(zhuǎn)類)是三個(gè)歐拉角Pitch、Roll、Yaw的封裝,所以Frotator類的ControlRot中有它們?nèi)齻€(gè)成員變量。在MoveForward和MoveRight中我們只需要用外部輸入控制Character的Yaw,所以把Pitch和Roll設(shè)為0(在UE中要顯式地用0.0f)。

GetControlRotation()返回Pawn的控制器的旋轉(zhuǎn)向量(相對(duì)世界坐標(biāo))。

ControlRot.Vector()將FRotator類型的變量轉(zhuǎn)換為Vector類型的變量。

FVector是三維向量結(jié)構(gòu)體。

?

將Fvector轉(zhuǎn)為FrotationMatrix(FRotationMatrix(ControlRot)),并獲取Y軸方向的方向向量(.GetScaledAxis(EAxis::Y)),從而得到指向當(dāng)前Controller朝向的右方的方向向量。

否則,由于Pawn自身朝向的朝右向量,一旦右轉(zhuǎn)就會(huì)一直在變化,導(dǎo)致會(huì)原地打轉(zhuǎn)。(參考:https://blog.csdn.net/surkea/article/details/127104682)

?

我們不把事件"Turn"和"LookUp"綁定到自定義的函數(shù)上,而是綁定到Pawn類自帶的APawn::AddControllerYawInput和APawn::AddControllerPitchInput上。這兩個(gè)函數(shù)將輸入值增加到控制器的Rotation上(Pawn相比Actor,增加了一個(gè)Controller,這里的Pawn就是我們的Character,Character是Pawn的子類)。

?

為了獲得正確的Camera與Pawn移動(dòng)表現(xiàn),我們還要在構(gòu)造函數(shù)ASCharacter::ASCharacter()中設(shè)置,

SpringArmComp->bUsePawnControlRotation = true;(SpringArm的Rotation跟隨它所attach的Pawn的Controller(我們的鼠標(biāo))的Rotation。若為false,則因?yàn)镾pringArm實(shí)際上控制著Camera(它是Camera的父組件),所以此時(shí)Camera固定朝著一個(gè)方向,不會(huì)隨著鼠標(biāo)的轉(zhuǎn)動(dòng)而轉(zhuǎn)動(dòng))——>控制Camera朝向

GetCharacterMovement()->bOrientRotationToMovement = true;(Character朝向加速方向(Character中有個(gè)Arrow組件表示方向)。若為false,則Character在不調(diào)用Turn時(shí)始終面朝一個(gè)方向。該選項(xiàng)與下一項(xiàng)沖突,為下一項(xiàng)為true,則該項(xiàng)無(wú)效。)

this->bUseControllerRotationYaw = false;(類似SpringArmComp->bUsePawnControlRotation,Character用Controller的Rotation控制朝向。)

第一句設(shè)置Camera朝向,二三句控制Character朝向(所以兩者沖突)。

GetCharacterMovement()->bOrientRotationToMovement = true; this->bUseControllerRotationYaw = false; ——>黑魂、老滾5,可看到角色正面(Controller控制Character朝X軸反方向移動(dòng)時(shí),Character面朝玩家)

GetCharacterMovement()->bOrientRotationToMovement = false; this->bUseControllerRotationYaw = true; ——>光明記憶、一些大逃殺,只能看到角色背面(因?yàn)榻巧冀K朝向Controller的X軸方向)

另外,因?yàn)閎OrientRotationToMovement和bUseControllerRotationYaw都是bool類型的變量,所以它們的名字都是b開(kāi)頭的。


給Character的mesh組件的skeletal mesh一個(gè)具體的東西,否則我們看不到角色。

這里還要把導(dǎo)入的角色與碰撞體適配,并且角色朝向與ArrowComponent方向一致。


加入角色動(dòng)畫,否則角色默認(rèn)擺大字。角色動(dòng)畫會(huì)根據(jù)角色的狀態(tài)、速度等因素渲染一個(gè)姿勢(shì),不同姿勢(shì)組成的時(shí)間序列形成了我們看到的動(dòng)畫效果。

TomLooman_ActionRoguelike_第二章項(xiàng)目與版本的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
喀喇| 宝应县| 新龙县| 浮山县| 红河县| 卢氏县| 湖南省| 会同县| 子洲县| 广平县| 沙坪坝区| 玉屏| 泰顺县| 广饶县| 阜康市| 林周县| 香港| 涿州市| 武汉市| 清原| 清镇市| 临漳县| 民和| 闸北区| 普定县| 军事| 长春市| 怀仁县| 南岸区| 渝中区| 山丹县| 蓬溪县| 穆棱市| 通许县| 太和县| 威远县| 海门市| 昭苏县| 大新县| 南开区| 顺义区|