當我們按下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:
然後在下面找到GameMode,將GameMode Override設成HopeGameMode:
這時候我們會發現下面幾個參數都是灰色的:Default Pawn Class、HUD Class、Player Controller Class、Game State Class。當我們按下Play按鈕時,會發現在右上角的World Outliner中引擎自動生成的instaance包含了這幾個類別:
由於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按右鍵:
我們可以看到有三個選項:
Snap View to Object:將現在的view移動到camera身上。
Snap Object to View:將camera移動到現在看到的。
Pilot ‘MainCameraActor’:讓camera隨著現在看到的view移動,直接按下退出。
這幾個功能可以省下我們不少的時間在camera視角的調整上。
調整好之後,我們可以看到右下角的MainCameraActor正對著我們的Sprite:
接下來的課題便是,我們怎麼樣在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