C++ Game Project for Unreal Engine 4.8 part2:2D Camera

posted in: UnrealEngine | 0

當我們按下play按鈕的時候會發現,其實玩家還是在3D world中進行操控,當玩家按下旋轉或移動時,camera會進行對應的動作。那麼我們該怎麼固定Camera的視角呢?

為了解決這個問題,我們所需思考的,便是想辦法將一個我們固定好的camera設給玩家所使用的view port,並禁止其改變這個camera的位置。實際上我們該怎麼辦到這件事?由於在UE中對於不同關卡的管理是用『map』的概念來進行操作,因此我們必須想辦法在map中找到我們的PlayerController,並將這個被我們固定住的camera設給他。

map,其實就是一個擺設好關卡內容的場景再加上GameMode中所描述的game rule所組合而成。由於我們剛剛建立了一個MainMap取代了預設的template map,因此可以預見的是現在這個map的game mode會是空的。雖然在引擎中大部份的參數如果沒有設定的話,通常都會有引擎的預設值,但這裡我們希望將GameMode設回HopeGameMode這個類別。要在哪裡才能找到這個設定呢?首先先在右上角找到目前的map按右鍵,選取WorldSettings:

clip_image001

然後在下面找到GameMode,將GameMode Override設成HopeGameMode:

clip_image002

這時候我們會發現下面幾個參數都是灰色的:Default Pawn Class、HUD Class、Player Controller Class、Game State Class。當我們按下Play按鈕時,會發現在右上角的World Outliner中引擎自動生成的instaance包含了這幾個類別:

clip_image003

由於PlayerController負責用來接收Human Player的輸入並轉發給對應的Actor,因此為了達到固定視角的目的,因此我們必須使用我們自己的PlayerController,並設定這個CameraActor不該接受Human Player操控。只是由於我們的GameMode是C++ Class,因此要更改上面那四個預設的類別也只能在C++中操作。當然,若是使用BluePrint,我們就會發現在editor中就可以直接選擇了。

這裡我們討論的是C++,因此首先我們要做的,便是先建立一個C++ PlayerController,並在HopeGameMode的建構子中指定。在這裡,我們將其命名為GamePlayerController。

 

AHopeGameMode::AHopeGameMode(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{   PlayerControllerClass = AGamePlayerController::StaticClass();
}

 

有了PlayerController,接下來我們要在editor中建立一個CameraActor,並調整到正確的位置上。在這裡提供一個技巧,可以很快速的就將Camera的位置調好。首先,在右上角的World Outliner中對剛剛建好的CemeraActor按右鍵:

clip_image001[4]

我們可以看到有三個選項:

Snap View to Object:將現在的view移動到camera身上。

Snap Object to View:將camera移動到現在看到的。

Pilot ‘MainCameraActor’:讓camera隨著現在看到的view移動,直接按下退出。

這幾個功能可以省下我們不少的時間在camera視角的調整上。

調整好之後,我們可以看到右下角的MainCameraActor正對著我們的Sprite:

clip_image002[4]

接下來的課題便是,我們怎麼樣在Code裡面找到這個CameraActor?先來看看我們GamePlayerController的宣告:

 

UCLASS()
class HOPE_API AGamePlayerController : public APlayerController
{
    GENERATED_BODY()
public:
    virtual void BeginPlay() override;
private:
    ACameraActor* FixedViewTarget;
};


接下來在BeginPlay的實作如下:

 

void AGamePlayerController::BeginPlay(){
    Super::BeginPlay();  for (TActorIterator<ACameraActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
    {
        auto objectName = ActorItr->GetName();
        if (FString("MainCameraActor") == objectName){
            FixedViewTarget = *ActorItr;
            break;
        }
    }

    SetViewTarget(this->FixedViewTarget);
}

這段程式會將所有ACameraActor找出來,當我們找到MainCameraActor之後,我們就把這個camera設成當前的ViewTarget。這樣就完成了我們固定camera的目的了。

Leave a Reply

Your email address will not be published. Required fields are marked *