当我们按下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的目的了。