지난 시간에 구현한 워프는 워프 시 일반적인 플레이어의 뷰에서 커서가 가르키는 방향으로 이동하였다. 플레이어의 시점에서 워프를 실행하기 때문에 뒤로 이동하려면 뒤를 돌아야 한다. 이동 가능한 범위가 한 눈에 들어오도록 Top View를 제공해 워프 이동이 좀 더 다양하도록 선택권을 넓혀줄것이다. 마우스 우클릭으로 Top View가 나오도록 SubAction_Warp를 만들것이다.

 

 

목차

     

     


     

     

     
    Plugins
     
      Weapon
     
        Resource
     
          Icon128.png
    weapon_thumbnail_icon.png
     
        Source
     
          Weapon  
          SWeaponCheckBoxes.h .cpp
    SWeaponDetailsView.h .cpp

    SWeaponDoActionData.h .cpp
    SWeaponEquipmentData.h .cpp
    SWeaponHitData.h .cpp

    SWeaponLeftArea.h .cpp
    Weapon.Build.cs
    WeaponAssetEditor.h .cpp
    WeaponAssetFactory.h .cpp
    WeaponCommand.h .cpp 
    WeaponContextMenu.h .cpp
    WeaponModule.h .cpp
    WeaponStyle.h .cpp 
     
       

     

     
    Source
      U2212_06
        Characters
        CAnimInstance.h .cpp
    CEnemy.h .cpp 
    CPlayer.h .cpp
    ICharacter.h .cpp
        Components
        CMontagesComponent.h .cpp 
    CMovementComponent.h .cpp 
    CStateComponent.h .cpp
    CStatusComponent.h .cpp  
    CWeaponComponent.h .cpp 
        Notifies
        CAnimNotifyState_BeginAction.h .cpp 
    CAnimNotify_CameraShake.h .cpp 
    CAnimNotifyState_EndAction.h .cpp
    CAnimNotify_EndState.h .cpp
    CAnimNotifyState.h .cpp
    CAnimNotifyState_CameraAnim.h .cpp
    CAnimNotifyState_Collision.h .cpp 
    CAnimNotifyState_Combo.h .cpp
    CAnimNotifyState_Equip.h .cpp
    CAnimNotifyState_SubAction.h .cpp
        Utilities
        CHelper.h
    CLog.h .cpp
        Weapons
        CAura.h .cpp
    CCamerModifier.h .cpp
    CGhostTrail.h .cpp
    CDoAction_Combo.h .cpp
    CDoAction_Warp.h .cpp
    CSubAction_Fist.h .cpp
    CSubAction_Hammer.h .cpp
    CSubAction_Sword.h .cpp
    CDoAction_Warp.h .cpp 생성

    CAttachment.h .cpp
    CDoAction.h .cpp
    CEquipment.h .cpp
    CSubAction.h .cpp
    CWeaponAsset.h .cpp
    CWeaponStructures.h .cpp
        Global.h
    CGameMode.h .cpp
    U2212_06.Build.cs
        U2212_06.uproject
     

     

     

     

    워프 Top View 만들기

     


     

     

    카메라 이론 설명

     

    W: 직육면체

    VP: Frustum

     

    Vp: 직육면체

     

    종횡비율 Aspect Raio

     

     

    OrthoWidth만 정하고 OrthoHeight는 정하지 않는 이유는?

    Width를 가진 상태로 종횡비로 Height를 정하기 때문이다.  

     

     


     

     

    CMovementComponent  -  Top View 시에 Player를 절대방향으로 움직이도록 수정

     

    평상 시에는 Actor(=플레이어)의 전방 방향을 기준으로 플레이어가 움직인다. 하지만 Warp를 위한 우클릭 시 플레이어가 이동할 때는 Orthographic Top View이기 때문에 플레이어를 절대방향으로 움직일 수 있도록 수정해준다.

     

     

    CMovementComponent .h

    더보기
    #pragma once
    #include "CoreMinimal.h"
    #include "Components/ActorComponent.h"
    #include "CMovementComponent.generated.h"
    
    UENUM()
    enum class ESpeedType : uint8
    {
    	Walk = 0, Run, Sprint, Max,
    };
    
    UCLASS()
    class U2212_06_API UCMovementComponent : public UActorComponent
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(EditAnywhere, Category = "CameraSpeed")
    		float HorizontalLook = 45;
    
    	UPROPERTY(EditAnywhere, Category = "CameraSpeed")
    		float VerticalLook = 45;
    
    private:
    	UPROPERTY(EditAnywhere, Category = "Speed")
    		float Speed[(int32)ESpeedType::Max] = { 200, 400, 600 };
    
    public:
    	FORCEINLINE bool CanMove() { return bCanMove; }
    	FORCEINLINE void Move() { bCanMove = true; }
    	FORCEINLINE void Stop() { bCanMove = false; }
    
    	FORCEINLINE float GetWalkSpeed() { return Speed[(int32)ESpeedType::Walk]; }
    	FORCEINLINE float GetRunSpeed() { return Speed[(int32)ESpeedType::Run]; }
    	FORCEINLINE float GetSprintSpeed() { return Speed[(int32)ESpeedType::Sprint]; }
    
    	FORCEINLINE bool GetFixedCamera() { return bFixedCamera; }
    	FORCEINLINE void EnableFixedCamera() { bFixedCamera = true; }
    	FORCEINLINE void DisableFixedCamera() { bFixedCamera = false; }
    
    	FORCEINLINE void EnableTopViewCamera() { bTopViewCamera = true; }
    	FORCEINLINE void DisableTopViewCamera() { bTopViewCamera = false; }
    
    public:
    	UCMovementComponent();
    
    protected:
    	virtual void BeginPlay() override;
    
    private:
    	void SetSpeed(ESpeedType InType);
    
    public:
    	void OnSprint();
    	void OnRun();
    	void OnWalk();
    
    	void EnableControlRotation();
    	void DisableControlRotation();
    
    public:
    	void OnMoveForward(float InAxis);
    	void OnMoveRight(float InAxis);
    	void OnHorizontalLook(float InAxis);
    	void OnVerticalLook(float InAxis);
    
    private:
    	class ACharacter* OwnerCharacter;
    
    private:
    	bool bCanMove = true; //이동할 수 있는가
    	bool bFixedCamera; //카메라 고정인가
    	bool bTopViewCamera;
    };

    Top View로 사용할 변수 추가

    •  class ACameraActor* CameraActor;

     

    FORCEINLINE 함수 추가

    • FORCEINLINE void EnableTopViewCamera() { bTopViewCamera = true; }
    • FORCEINLINE void DisableTopViewCamera() { bTopViewCamera = false; }

     

     

     

    CMovementComponent .cpp

    더보기
    #include "Components/CMovementComponent.h"
    #include "Global.h"
    #include "GameFramework/Character.h"
    #include "GameFramework/CharacterMovementComponent.h"
    
    UCMovementComponent::UCMovementComponent()
    {
    }
    
    void UCMovementComponent::BeginPlay()
    {
    	Super::BeginPlay();
    
    	OwnerCharacter = Cast<ACharacter>(GetOwner());
    }
    
    void UCMovementComponent::SetSpeed(ESpeedType InType)
    {
    	OwnerCharacter->GetCharacterMovement()->MaxWalkSpeed = Speed[(int32)InType];
    }
    
    void UCMovementComponent::OnSprint()
    {
    	SetSpeed(ESpeedType::Sprint);
    }
    
    void UCMovementComponent::OnRun()
    {
    	SetSpeed(ESpeedType::Run);
    }
    
    void UCMovementComponent::OnWalk()
    {
    	SetSpeed(ESpeedType::Walk);
    }
    
    void UCMovementComponent::EnableControlRotation()
    {
    	OwnerCharacter->bUseControllerRotationYaw = true;
    	OwnerCharacter->GetCharacterMovement()->bOrientRotationToMovement = false;
    }
    
    void UCMovementComponent::DisableControlRotation()
    {
    	OwnerCharacter->bUseControllerRotationYaw = false;
    	OwnerCharacter->GetCharacterMovement()->bOrientRotationToMovement = true;
    }
    
    void UCMovementComponent::OnMoveForward(float InAxis)
    {
    	CheckFalse(bCanMove);
    
    	FRotator rotator = FRotator(0, OwnerCharacter->GetControlRotation().Yaw, 0);
    	FVector direction = FQuat(rotator).GetForwardVector();
    
    	if (bTopViewCamera)
    		direction = FVector::XAxisVector;
    
    	OwnerCharacter->AddMovementInput(direction, InAxis);
    }
    
    void UCMovementComponent::OnMoveRight(float InAxis)
    {
    	CheckFalse(bCanMove);
    
    	FRotator rotator = FRotator(0, OwnerCharacter->GetControlRotation().Yaw, 0);
    	FVector direction = FQuat(rotator).GetRightVector();
    
    	if (bTopViewCamera)
    		direction = FVector::YAxisVector;
    
    	OwnerCharacter->AddMovementInput(direction, InAxis);
    }
    
    void UCMovementComponent::OnHorizontalLook(float InAxis)
    {
    	CheckTrue(bFixedCamera);
    
    	OwnerCharacter->AddControllerYawInput(InAxis * HorizontalLook * GetWorld()->GetDeltaSeconds());
    }
    
    void UCMovementComponent::OnVerticalLook(float InAxis)
    {
    	CheckTrue(bFixedCamera);
    
    	OwnerCharacter->AddControllerPitchInput(InAxis * VerticalLook * GetWorld()->GetDeltaSeconds());
    }

    Top View 시 플레이어의 방향을 플레이어 기준이 아니라 XAxisVector, YAxisVector로 변경시켜 준다.

    • void UCMovementComponent::OnMoveForward(float InAxis)
      • if (bTopViewCamera)
            direction = FVector::XAxisVector;
    • void UCMovementComponent::OnMoveRight(float InAxis)
      • if (bTopViewCamera)
            direction = FVector::YAxisVector;

     


     

     

    CSubAction_Warp 생성

     

    새 C++ 클래스 - CSubAction - CSubAction_Warp 생성

     

     

    CSubAction_Warp.h

    더보기
    #pragma once
    #include "CoreMinimal.h"
    #include "Weapons/CSubAction.h"
    #include "CSubAction_Warp.generated.h"
    
    UCLASS(Blueprintable)
    class U2212_06_API UCSubAction_Warp : public UCSubAction
    {
    	GENERATED_BODY()
    
    private:
        UPROPERTY(EditDefaultsOnly, Category = "Camera")
            TSubclassOf<class ACameraActor> CameraActorClass;
    
        UPROPERTY(EditDefaultsOnly, Category = "Camera")
            FVector CameraRelativeLocation = FVector(0, 0, 1000);//플레이어와 카메라 사이의 상대간격
    
        UPROPERTY(EditDefaultsOnly, Category = "Camera")
            TEnumAsByte<ECameraProjectionMode::Type> ProjectionMode;//Projection모드: perspective, orthographic
    
        UPROPERTY(EditDefaultsOnly, Category = "Camera")
            float OrthoWidth = 2000;
    
        UPROPERTY(EditDefaultsOnly, Category = "Camera")
            float FieldOfView = 90;
    
        UPROPERTY(EditDefaultsOnly, Category = "Camera")
            float BlendIn = 0;//Player카메라에서 Warp카메라로 전환되는 시간
    
        UPROPERTY(EditDefaultsOnly, Category = "Camera")
            float BlendOut = 0;//Warp카메라에서 Player카메라로 전환되는 시간
    
    public:
        UCSubAction_Warp();
    
    public:
        virtual void Pressed() override;
        virtual void Released() override;
    
    public:
        void BeginPlay(class ACharacter* InOwner, class ACAttachment* InAttachment, class UCDoAction* InDoAction) override;
    
    public:
        void Tick_Implementation(float InDeltaTime) override;
    
    private:
        class APlayerController* PlayerController;
        class ACameraActor* CameraActor;
    };

     

     

     

     

    CSubAction_Warp.cpp

    더보기
    #include "Weapons/SubActions/CSubAction_Warp.h"
    #include "Global.h"
    #include "GameFramework/Character.h"
    #include "GameFramework/PlayerController.h"
    #include "Components/CStateComponent.h"
    #include "Components/CMovementComponent.h"
    #include "Camera/CameraActor.h"
    #include "Camera/CameraComponent.h"
    
    UCSubAction_Warp::UCSubAction_Warp()
    {
    	//선택하지 않아도 기본자료형으로 만들 수 있도록 설정. Abstract이 아닌 경우 null 대신 많이 사용하는 형식이다.
    	CameraActorClass = ACameraActor::StaticClass();
    }
    
    void UCSubAction_Warp::BeginPlay(ACharacter* InOwner, ACAttachment* InAttachment, UCDoAction* InDoAction)
    {
    	Super::BeginPlay(InOwner, InAttachment, InDoAction);
    
    	PlayerController = InOwner->GetController<APlayerController>();//PlayController를 가져온다.
    
    	CameraActor = InOwner->GetWorld()->SpawnActor<ACameraActor>(CameraActorClass);//CameraActor를 Spawn 시킨다.
    	CameraActor->SetActorRotation(FRotator(-90.0f, 0.0f, 0.0f));//위에서 아래를 바라보도록 Rotator 설정.
    
    	UCameraComponent* camera = CHelpers::GetComponent<UCameraComponent>(CameraActor);//CameraComponent 생성
    	//변수로 설정한 값들을 camera의 해당 항목에 대입시켜 준다.
    	camera->ProjectionMode = ProjectionMode;
    	camera->OrthoWidth = OrthoWidth;
    	camera->FieldOfView = FieldOfView;
    }
    
    void UCSubAction_Warp::Pressed()
    {
    	CheckNull(PlayerController);
    	CheckTrue(State->IsSubActionMode());
    
    	Super::Pressed();
    
    
    	State->OnSubActionMode();
    	Movement->EnableTopViewCamera();//CMovementComponent의 bTopViewCamera를 true로 만듬. 절대방향으로 움직임.
    	PlayerController->SetViewTargetWithBlend(CameraActor, BlendIn);
    }
    
    void UCSubAction_Warp::Released()
    {
    	CheckNull(PlayerController);
    	CheckFalse(State->IsSubActionMode());
    
    	Super::Released();
    
    
    	State->OffSubActionMode();
    	Movement->DisableTopViewCamera();//CMovementComponent의 bTopViewCamera를 false로 만듬.
    	PlayerController->SetViewTargetWithBlend(Owner, BlendOut);
    }
    
    void UCSubAction_Warp::Tick_Implementation(float InDeltaTime)
    {
    	Super::Tick_Implementation(InDeltaTime);
    
    	CheckNull(PlayerController);
    	CheckNull(CameraActor);
    
    	//카메라의 위치를 Player위치로 실시간 옮겨준다. 
    	CameraActor->SetActorLocation(Owner->GetActorLocation() + CameraRelativeLocation);
    }

     

     

     

     

    BP_CSubAction_Warp 생성

    CSubAction_Warp 기반 블루프린트 클래스생성 -  BP_CSubAction_Warp 생성

    Camera

    • Projection Mode: Orthographic 설정

     


     

     

    DA_Warp

     

    Class Settings

    • SubAction Class: BP_CSubAction_Warp 할당

     

     

     

    실행화면

     

     

     


     

     

     

     

    '⭐ Unreal Engine > UE RPG Skill' 카테고리의 다른 글

    [UE] Around 스킬 구현하기  (0) 2023.07.04
    [UE] Around 공격 구현하기  (0) 2023.07.03
    [UE] 워프 구현하기  (0) 2023.06.29
    [UE] 해머 스킬 만들기  (0) 2023.06.27
    [UE] 일섬 스킬 충돌, 해머 스킬 만들기  (0) 2023.06.26