지난 시간에 구현한 워프는 워프 시 일반적인 플레이어의 뷰에서 커서가 가르키는 방향으로 이동하였다. 플레이어의 시점에서 워프를 실행하기 때문에 뒤로 이동하려면 뒤를 돌아야 한다. 이동 가능한 범위가 한 눈에 들어오도록 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