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

当我们按下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中引擎自动生成的instaan​​ce包含了这几个类别:

由于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的目的了。

Author: 90cg