[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
댓글을 사용할 수 없습니다.