UE4_C++_002

玩家輸入與Pawn

這個時組件和碰撞的提前知識預備,最好在之前了解組件相關(guān)東西,重要的概念對于軸映射和操作映射。

首先介紹兩個概念

  1. Actor類——可以放到游戲場景中的游戲?qū)ο蟮幕绢愋汀D闳绻敕胖萌魏螙|西到游戲場景中,必須繼承Actor類
  2. Pawn類——代表或者代表電腦的人工智能的游戲?qū)ο?/strong>,它是可以在屏幕上控制的游戲?qū)ο蟆awn類是從Actor類中繼承的,它可以通過玩家的設(shè)備(鍵盤、鼠標等)控制或者被人工智能腳本控制。如果它是被玩家控制的,我們通常稱之為controller(控制器);如果它是被人工智能腳本控制的,我們通常稱之為AI(Artificial Intelligence,人工智能),如果你經(jīng)常玩游戲,那些NPC(Non-player Characters,非玩家角色)就通常具有AI行為。

自己定義Pawn

  1. 打開UE4的C++項目,添加C++類,命名為MyPawn
  2. 在cpp中設(shè)置玩家控制
// 將該Pawn設(shè)為由最小編號玩家控制
AutoPossessPlayer = EAutoReceiveInput::Player0;
  1. 構(gòu)建幾個組件,在MyPawn.h底部添加
UPROPERTY(EditAnywhere)
USceneComponent* OurVisibleComponent;

《Inside UE4》-GamePlay架構(gòu)系列博客
首先要知道一個對象要在3D世界中的表示,必然要攜帶一個Transform來表示其位置。但是在UE看來,Actor并不只是3D中的表示,一些不在世界中展示的“不可見對象”也可以是Actor,比如AInfo的派生類等,所以Actor也就沒有自帶Transform了。

而SceneComponent則封裝了Transform,當作RootComponent,所以需要位置表示的Actor就可以向Actor中添加ScenetComponent作為其RootComponent.比如,pawn就自動創(chuàng)建了SceneComponent.

還有一點需要注意的是,實際中大部分的Actor是有Transform的,所以我們會經(jīng)常設(shè)置獲取它的坐標,常理來說,我們的需要先獲取下SceneComponent,然后才能操作其Transform等相應(yīng)接口,但是這樣太過繁瑣,因此UE為我們直接提供了基于Actor的接口,如Get/Set ActorLocation,但其實這些接口內(nèi)部也是轉(zhuǎn)發(fā)到RootComponent(SceneComponent)的。

  1. 將下面代碼添加到cpp中構(gòu)造函數(shù)AMyPawn::AMyPawn

這里需要在開頭添加#include "Camera/CameraComponent.h"

// 創(chuàng)建可附加內(nèi)容的虛擬根組件。
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
// 創(chuàng)建相機和可見對象
UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera"));
OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent"));
// 將相機和可見對象附加到根組件。偏移并旋轉(zhuǎn)相機。
OurCamera->SetupAttachment(RootComponent);
OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f));
OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f));
OurVisibleComponent->SetupAttachment(RootComponent);
  1. 現(xiàn)在便擁有響應(yīng)游戲輸入的自定義Pawn,需定義此輸入的內(nèi)容。為此,將在 虛幻編輯器 中配置項目的 輸入設(shè)置。

配置游戲輸入

輸入的映射有兩種——操作

操作映射
適用于"是/否"輸入,例如鼠標或手柄上的按鈕。被按下、松開、雙擊或短時長按時,其將進行報告。跳躍、射擊或與物體互動等離散操作是這類映射的理想對象。

軸映射
是連續(xù)的,可將其視為"程度"輸入,例如手柄上的搖桿,或者鼠標光標的位置。其會逐幀報告自身的值,即使未移動也進行報告。通常使用此方法處理如行走、四處查看和操縱車輛等有量級或方向的對象。

雖然可直接在代碼中定義輸入映射,但常用方法是在 虛幻引擎 編輯器中定義,本教程也將使用此方法。

  1. 在 虛幻引擎編輯器中,在 編輯 下拉菜單下,點擊 項目設(shè)置(Project Settings) 選項。
  2. 在此界面左側(cè)的 引擎(Engine) 部分中選擇 輸入 選項。之后,展開右側(cè)顯示的 綁定 類別,添加 操作映射(Action Mapping) 和兩個軸映射(Axis Mappings)。
    [圖片上傳失敗...(image-76b742-1623143400720)]
  3. 輸入現(xiàn)已配置完成,接下來在關(guān)卡中設(shè)置MyPawn。MyPawn 類將在 內(nèi)容瀏覽器 中顯示,并可被拖入 關(guān)卡編輯器。[圖片上傳失敗...(image-76a21f-1623143400720)]
  4. 設(shè)置MyPawn還需一個步驟。需向其指定 靜態(tài)網(wǎng)格體,以便其可在游戲中顯示。具體操作:選擇剛創(chuàng)建的MyPawn,在 細節(jié)面板 中選擇名為 OurVisibleComponent (Inherited) 的組件,并利用 靜態(tài)網(wǎng)格體 類別中的下拉框向其指定資源。在本教程中,Shape_Cylinder 為現(xiàn)成資源。 [圖片上傳失敗...(image-62bd6a-1623143400720)]
  5. 現(xiàn)在保存關(guān)卡,返回 Visual Studio 編寫代碼,使剛剛放置的MyPawn對定義的輸入做出反應(yīng)。

編寫和綁定游戲操作

  1. Visual Studio 中,打開MyPawn.h并將以下代碼添加到MyPawn類定義的底部:

四個輸入函數(shù)將被綁定到輸入事件。其運行時,將對新輸入變量中存儲的值進行更新,MyPawn將使用此類值決定游戲期間應(yīng)執(zhí)行的操作。

//輸入函數(shù)
    void Move_XAxis(float AxisValue);
    void Move_YAxis(float AxisValue);
    void StartGrowing();
    void StopGrowing();

    //輸入變量
    FVector CurrentVelocity;
    bool bGrowing;
  1. 切換到MyPawn.cpp,并對剛才聲明的四個函數(shù)編碼。

使用 FMath::Clamp 約束輸入中得到的值,將其約束在-1到+1的范圍內(nèi)。雖然本例中不存在此問題,但若有會對軸產(chǎn)生相同影響的多個鍵,則玩家同時按下此類輸入時會將累加這些值。例如,如W鍵和向上方向鍵均映射到MoveX,且縮放均為1.0,同時按下這兩個鍵會得到2.0的AxisValue。如不進行限制,玩家將以兩倍速度移動。

void AMyPawn::Move_XAxis(float AxisValue)
{
    // 以100單位/秒的速度向前或向后移動
    CurrentVelocity.X = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}

void AMyPawn::Move_YAxis(float AxisValue)
{
    // 以100單位/秒的速度向右或向左移動
    CurrentVelocity.Y = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}

void AMyPawn::StartGrowing()
{
    bGrowing = true;
}

void AMyPawn::StopGrowing()
{
    bGrowing = false;
}

可以看到,兩個"Move"函數(shù)將軸值視作浮點,而"Grow"則不同。這是因為其映射到MoveX和MoveY,均為軸映射,因此擁有浮點參數(shù)。操作映射無此參數(shù)。

  1. 現(xiàn)在已定義輸入函數(shù),接下來需進行綁定,以便對相應(yīng)輸入做出反應(yīng)。將以下代碼添加到 AMyPawn::SetupPlayerInputComponent 中:
// 在按下或松開"Grow"鍵時做出響應(yīng)。
InputComponent->BindAction("Grow", IE_Pressed, this, &AMyPawn::StartGrowing);
InputComponent->BindAction("Grow", IE_Released, this, &AMyPawn::StopGrowing);

// 對兩個移動軸"MoveX"和"MoveY"的值逐幀反應(yīng)。
InputComponent->BindAxis("MoveX", this, &AMyPawn::Move_XAxis);
InputComponent->BindAxis("MoveY", this, &AMyPawn::Move_YAxis);
  1. 變量現(xiàn)在將根據(jù)配置的輸入進行更新。接下來只需編寫代碼使其完成部分操作。將以下代碼添加到 AMyPawn::Tick
// 根據(jù)"Grow"操作處理增長和縮減
{
    float CurrentScale = OurVisibleComponent->GetComponentScale().X;
    if (bGrowing)
    {
        // 一秒內(nèi)增長到兩倍大小
        CurrentScale += DeltaTime;
    }
    else
    {
        // 以增長速度縮減一半
        CurrentScale -= (DeltaTime * 0.5f);
    }
    // 確保不會降至初始大小以下,或者增至兩倍大小以上。
    CurrentScale = FMath::Clamp(CurrentScale, 1.0f, 2.0f);
    OurVisibleComponent->SetWorldScale3D(FVector(CurrentScale));
}

// 根據(jù)"MoveX"和"MoveY"軸處理移動
{
    if (!CurrentVelocity.IsZero())
    {
        FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
        SetActorLocation(NewLocation);
    }
}
  1. 編譯代碼后,可返回 虛幻編輯器 并按 運行。應(yīng)可使用WASD鍵控制 Pawn,同時可通過長按 空格 鍵來使其增長,松開空格鍵時看到縮小。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容