[UE] 워프 Top View 만들기
지난 시간에 구현한 워프는 워프 시 일반적인 플레이어의 뷰에서 커서가 가르키는 방향으로 이동하였다. 플레이어의 시점에서 워프를 실행하기 때문에 뒤로 이동하려면 뒤를 돌아야 한다. 이동 가능한 범위가 한 눈에 들어오도록 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;
- if (bTopViewCamera)
- void UCMovementComponent::OnMoveRight(float InAxis)
- if (bTopViewCamera)
direction = FVector::YAxisVector;
- if (bTopViewCamera)
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 |
댓글
이 글 공유하기
다른 글
-
[UE] Around 스킬 구현하기
[UE] Around 스킬 구현하기
2023.07.04 -
[UE] Around 공격 구현하기
[UE] Around 공격 구현하기
2023.07.03 -
[UE] 워프 구현하기
[UE] 워프 구현하기
2023.06.29 -
[UE] 해머 스킬 만들기
[UE] 해머 스킬 만들기
2023.06.27