UE4

UE4/C++ プレイヤーキャラクターを作る:カメラの作成(4/)

アームカメラコンポーネントの作成

USpringArmComponentを継承してアームカメラコンポーネントを作成します。

ファイル構成は以下ようになります。
utyにアームカメラコンポーネント(ArmCamera.h)を配置していす。
IvPadInput.hはKey入力用のクラスです。
vatico

ArmCamera.h

/**
 * @file ArmCamera.h
 * @brief アーム付きカメラ
 * @author     inuvatico
 * @date        2020/11/01
 * @version     1.0
 * @copyright   2018 inuvatico
 * Released under the MIT license.
 *   see https://opensource.org/licenses/MIT
 * @par (new/Add/Change : 2020/10/17)
 *
*/
#pragma once

#include "GameFramework/Actor.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "ArmCamera.generated.h"

UCLASS()
class UArmCamera : public  USpringArmComponent
{

    GENERATED_BODY()

public:
    UArmCamera() {

    }

    virtual void BeginPlay() override {
        Super::BeginPlay();
    };

private:

    AActor *TrgActor; //!< 追尾対象
    UCameraComponent* CameraComponent; //!< カメラ 

    #define  _CAMERA_ARM_NAME  "UArmCamera_Arm" //オブジェクトの名前
    #define _CAMERA_NAME  "UArmCamera_Camera"   //オブジェクトの名前

public:
    UCameraComponent* GetCamera() { return CameraComponent; }
    AActor *GetTrgActor() { return TrgActor; }

    ///カメラの移動
    FRotator AddRotation(float x, float y) {
        FRotator Rot = { 0,0,0 };

        float yaw = x  * 1.0f;// 左右
        float pitch; // 上下
        {
            pitch = y * 1.0f;
            FRotator rot = GetRelativeRotation();
            if (rot.Pitch + pitch > 50) {
                pitch = 50 - rot.Pitch;
            }
            if (rot.Pitch + pitch < -80) {
                pitch = -80 - rot.Pitch;
            }
        }
        AddRelativeRotation(FRotator(pitch, yaw, 0.f));

        return Rot;
    }

    ///カメラ向きの設定
    void SetRotation(FRotator Rot) {SetRelativeRotation(Rot);}
public:
    static UArmCamera *Create(AActor * Actor) {

        static const float arm_length = 350;    // アームの長さ(対象とカメラの距離)
        static const float def_pitch = -70.0f;  // 見下ろす角度


        AActor * TrgActor = Actor;
        UArmCamera* CameraArm = nullptr; //!< カメラのアーム部分
        UCameraComponent* CameraComponent = nullptr; //!< プレイヤー用カメラ 

        //カメラを作成:カメラとカメラアーム
        {
            // アームの作成
            {
                CameraArm = NewObject< UArmCamera >(TrgActor, _CAMERA_ARM_NAME);
                if (!CameraArm) {
                    return nullptr;
                }

                CameraArm->RegisterComponent();
                FAttachmentTransformRules AttachmentRules(EAttachmentRule::KeepRelative, false);
                CameraArm->AttachToComponent(TrgActor->GetRootComponent(), { EAttachmentRule::KeepRelative, false }); //ルートにアームを接続

                CameraArm->TargetArmLength = arm_length; // キャラクタまでのデフォルト距離
                CameraArm->SetRelativeRotation(FRotator(def_pitch, 0.f, 0.f)); // 見下ろす角度
                CameraArm->SetUsingAbsoluteRotation(true); //false だと常にキャラの背中なる

                //追随のレート(遅延レート) 
                CameraArm->bEnableCameraLag = true;
                CameraArm->CameraLagSpeed = 10.0f;// 0.125f;
            }

            // カメラの作成&カメラをアームに接続
            {
                CameraComponent = NewObject< UCameraComponent >(TrgActor, _CAMERA_NAME);
                if (!CameraComponent) {
                    return nullptr;
                }

                CameraComponent->RegisterComponent();
                FAttachmentTransformRules AttachmentRules(EAttachmentRule::KeepRelative, false);
                CameraComponent->AttachToComponent(CameraArm, AttachmentRules); //アームにカメラを接続

                CameraComponent->bUsePawnControlRotation = false; //キャラの回転に影響されない?
                CameraComponent->SetRelativeRotation(FRotator(0.f, 0.f, 0.f)); // アームの回転に追従
                CameraComponent->SetRelativeLocation(FVector(0.f, 0.f, 0.f)); // カメラ位置の修正
            }
        }

        // メンバーを設定する
        {
            CameraArm->TrgActor = Actor;
            CameraArm->CameraComponent = CameraComponent;
        }

        return CameraArm;
    }
};

Createを呼び出してインスタンス作成します。
  static UArmCamera *Create(AActor * Actor);

カメラをプレイヤーコントローラに接続

プレイヤーコントローラ(ACppPlayerController)を修正していきます。

headerの変更

CppPlayerController.hにclass UArmCameraのポインタを追加します。

/**
 * @file CppPlayerController.h
 * @brief プレイヤーコントローラー
 * @author     inuvatico
 * @date        2020/10/17
 * @version     1.0
 * @copyright   2020 inuvatico
 * Released under the MIT license.
 *   see https://opensource.org/licenses/MIT
 * @par (new/Add/Change : 2020/10/17)
 *
*/

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "CppPlayerController.generated.h"


//クラスの前方宣言
class UArmCamera;
 //========================================================================
 /// プレイヤーコントローラー
 //========================================================================
UCLASS()
class ACppPlayerController : public APlayerController
{
    GENERATED_BODY()

protected:
    virtual void BeginPlay() override;

public:
    ACppPlayerController();
    virtual void Tick(float DeltaTime) override;

protected:
    UArmCamera *ArmCamera = nullptr; //!< アームカメラのポインタ
};

cppの変更

UArmCameraを実装します。
CppPlayerController.cppのBeginPlay()でUArmCamera::Createを呼び出します。

 * @copyright   2020 inuvatico
 * Released under the MIT license.
 *   see https://opensource.org/licenses/MIT
 * @par (new/Add/Change : 2020/10/17)
 *
*/

#include "CppPlayerController.h"
#include "../../../uty/ArmCamera.h"

//----------------------------------------------------------------
/// コンストラクタ
//----------------------------------------------------------------
ACppPlayerController::ACppPlayerController() {

    PrimaryActorTick.bCanEverTick = true; //Tickが呼ばれるようにする
}

//----------------------------------------------------------------
/// BeginPlay()
//----------------------------------------------------------------
void ACppPlayerController::BeginPlay() {

    Super::BeginPlay();

    AActor *TrgActor = (AActor *)GetCharacter();//プレイヤーキャラクタを取得
    if (!TrgActor) return;

    // カメラをセットアップする
    ArmCamera = UArmCamera::Create((AActor *)TrgActor);
}

//----------------------------------------------------------------
///Tick 毎フレーム呼び出される
//----------------------------------------------------------------
void ACppPlayerController::Tick(float DeltaTime) {
    if (GEngine)
        GEngine->AddOnScreenDebugMessage(-1, 1.0f / 60.f, FColor::Orange, FString::Printf(TEXT("Tick")));
}

実行

プレイボタン押します。
vatico

表示が変わればOKです。
vatico










digitalize
  始めました。