如何设置一个RTS风格的摄像机

  • 创建一个空工程,如图:

    create_project.png

  • 因为是创建的代码工程,所以创建成功后会直接打开 vs2013,工程打开后,把编译配置改成 DebugGame Editor,这是为了可以在编辑器中调试代码,然后先编译一下工程,如图:

    change_compile_config.png

  • 编译成功后, Ctrl + F5 运行编辑器,然后选择 File->Add Code to Project...,在弹出的对话框中勾选 Show All Classes,然后选择父类为 SpectatorPawn,再点击 Next 按钮,在下一步中选择类名和位置,然后选择 CreateClass 按钮,创建完成后在 VS 中重载工程,这样添加一个新类就完成了,如图:

    add_code.png

    create_spectator_pawn1.png

    create_spectator_pawn2.png

  • UE4 中,摄像机是绑定在角色身上的(FPS引擎),SpectatorPawn 顾名思义就是一个旁观者角色,这个角色就是 RTS 游戏中开了上帝视角的一个角色,因此还需要创建一个摄像机组件,绑定到这个 SpectatorPawn 身上

  • 再次走一遍添加代码的流程,只不过父类换成了 CameraComponent,创建完成后再重载一下 VS 工程,然后关掉编辑器,回到 VS 中编辑代码

  • RTSCameraComponent.h 中重载一个获取摄像机视图的函数,如下代码:

    UCLASS()
    class RTSCAMERA_API URTSCameraComponent : public UCameraComponent
    {
        GENERATED_UCLASS_BODY()
    
        /** 重载获取摄像机视图函数 */
        virtual void GetCameraView(float delta_time, FMinimalViewInfo& view);
    
    private:
        /** 返回拥有这个摄像机组件的游戏物体对象(pawn) */
        APawn* getOwnerPawn();
    
        /** 返回这个摄像机组件的拥有者的PlayerController */
        APlayerController* getPlayerController();
    }
    
  • RTSCameraComponent.cpp 中添加3个函数的实现代码,如下:

    void URTSCameraComponent::getOwnerPawn()
    {
        return Cast<APawn>(GetOwner());
    }
    
    void URTSCameraComponent::getPlayerController()
    {
        APlayerController* controller = nullptr;
        APawn* owner = getOwnerPawn();
    
        if (owner)
        {
            controller = Cast<APlayerController>(owner->GetController());
        }
    }
    
    void URTSCameraComponent::GetCameraView(float delta_time, FMinimalViewInfo& view)
    {
        FRotator fixed_camera_angle;
        fixed_camera_angle.Yaw = -45.f;
        fixed_camera_angle.Pitch = -45.f;
        fixed_camera_angle.Roll = 0.f;
    
        APlayerController* controller = getPlayerController();
        if (controller)
        {
            view.FOV = 30.f;
            view.Location = controller->GetFocalLocation() - fixed_camera_angle.Vector() * 8000;
            view.Rotation = fixed_camera_angle;
        }
    }
    
  • RTSCameraSpectatorPawn.h 中,创建一个自定义的摄像机组件,如下:

    UCLASS()
    class RTSCAMERA_API ARTSCameraSpectatorPawn : public ASpectatorPawn
    {
        GENERATE_UCLASS_BODY()
    
        //摄像机组件
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = CameraActor)
        TSubobjectPtr<class URTSCameraComponent> m_main_camera;
    }
    
  • RTSCameraSpectatorPawn.cpp 中,实现构造函数,如下:

    #include "RTSCameraComponent.h"
    
    ARTSCameraSpectatorPawn::ARTSCameraSpectatorPawn(const class FPostConstructInitializeProperties& PCIP)
        : Super(PCIP)
    {
        CollisionComponent->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
        bAddDefaultMovementBindings = false;
        m_main_camera = PCIP.CreateDefaultSubobject<URTSCameraComponent>(this, TEXT("MainCameraComponent"));
    }
    
  • 然后打开 RTSCameraGameMode.cpp 在构造函数中注册使用新创建的 SpectatorPawn 类,如下:

    #include "Pawn/RTSCameraSpectatorPawn.h"
    ARTSCameraGameMode::ARTSCameraGameMode(const class FPostConstructInitializeProperties& PCIP)
        : Super(PCIP)
    {
        SpectatorClass = ARTSCameraSpectatorPawn::StaticClass();
        DefaultPawnClass = ARTSCameraSpectatorPawn::StaticClass();
    }
    
  • 编译工程,Ctrl + F5 运行编辑器,打开 WorldSettins,将GameMode改成 RTSCameraGameMode,然后点击 Play 按钮,这时视角就变成45度俯视的RTS视角了,如图:

open_world_settings.png

modify_world_settings.png

hit_play.png

  • 运行结果:

run.png