기본 콘텐츠로 건너뛰기

250401 상속, TMap, UPROPERTY, 델리게이트, Enhanced Input

virtual 

부모 클래스에서 사용한다.

자식 클래스가 재정의 할 수 있다라는 뜻.

override

자식 클래스에서 사용한다.

부모 클래스에서 정의한 virtual(가상함수)를 사용하겠다.



virtual 자료형 함수이름() = 0;

순수 가상함수.

반드시 자식 클래스에서 정의해줘야 함. 안하면 에러.


Property 선언
블루프린트, 에디터에서 사용하기 위해 선언하는 것.


블루프린트의 Class Settings - Parent Class에 해당 클래스가 맞는지 확인


Class Defaults로 가서 Detail에서 변수를 확인가능


UPROPERTY 프로퍼티 지정자
EditAnywhere : 에디터상 어디서나 편집가능.
EditDefaultsOnly : 블루프린트 안에서만 가능, 디테일 창, 플레이에서 불가능
EditFixedSize : 배열의 사이즈를 변경 못하게 함.
*EditInline : 프로퍼티에 참조된 오브젝트의 프로퍼티를 편집할 수 있도록 합니다.
EditInstanceOnly : 게임 플레이 상황에만 편집 가능. (클래스가 인스턴스화 되었을 때)

VisibleAnywhere : 에디터상 어디서나 표시. 편집은 불가
VisibleDefaultsOnly : 블루 프린트 안에서만 가능.
VisibleInstanceOnly : 게임 플레이 상황에만 표시

SimpleDisplay : 디테일 패널에 바로 표시.
BlueprintReadOnly : 블루 프린트에서 수정 불가.
BlueprintReadWrite : 블루 프린트에서 수정 가능.
Category ="TopName|SubName|SubSubName" 카테고리를 만들 수 있음. '|' 이용.

프로퍼티 메타 데이터 지정자
meta = 
AllowPrivateAccess="true" : Private형식이어도 블루 프린트에서 접근 가능하게 함.
ClampMin = n, ClampMax = m : 해당 값을 n과 m사이 값으로 고정함.
Displayname : c++내의 변수 명과 다르게 블루 프린트 상의 이름을 정함.
Tooltip : 해당 프로퍼티에 대한 설명을 쓸 수 있음.



TMap
TMap <key(자료형), 값(자료형)> TMap이름;

if 문을 사용하는 것은 존재하지 않는 TMap을 사용하는 에러를 방지하기 위함이다.
블루프린트에서 TMap을 사용할 경우, 미리 초기화 해주지 않으면, 에러가 발생한다.
따라서, TMap.Num()을 이용해서, 초기화를 해줘야 한다.


BeginPlay()에서 실행되므로 플레이 화면에서만 확인가능

생성자에서 쓰는 경우는 게임이 실행되기 전에 변경할 필요가 있는 경우.
BeginPlay()에서 쓰는 경우는 위의 생성자 이후에 사용하는 경우.


DELEGATE




Player Character 만들기

PlayerCharacter.h
Spring Arm과 Camera를 이용해 카메라를 설정할 생각이므로 변수를 만든다.


PlayerCharacter.cpp

Chracter는 기본적으로 Mesh, Capsule Component, Arrow Component를 갖고 있으므로, 메쉬를 따로 추가할 필요가 없다. 이것을 사용하기 위해서 메쉬를 찾아다 사용한다.

// 콘텐츠 브라우저에서 메쉬를 찾는다.
ConstructorHelpers::FObjectFinder<USkeletalMesh>PlayerMesh(TEXT("경로"));
경로 이름은 마우스 우클릭, CopyReference

GetMesh()->SetSkeletalMesh를 이용해서 찾은 메쉬를 넣어준다.
GetMesh()->SetWorldLocationAndRotation을 통해 위치와 회전을 통해 정면방향으로 한다.

CreateDefaultSubobject<컴포넌트형식>TEXT("컴포넌트이름")
컴포넌트 형식의 오브젝트를 컴포넌트 이름으로 생성한다.

SetupAttachment(붙일 위치)
컴포넌트가 붙일 위치를 정한다. RootComponent는 가장 상위 바로 밑


C++에서 정한 값은 블루프린트에서 바꿀 수 있다.
단, 블루프린트에서 바뀐 값이 C++에 저장되는 게 아니므로 주의하자.

Enhanced Input

Editor - Input - Enhanced Input




Editor - Plugin - Enhanced Input
프로젝트이름.build.cs의 PublicDependencyModuleNames.AddRange({"EnhancedInput"});

Generate Visual Studio Project file

헤더파일에 #include "InputActionValue.h"


InputMappingContext
MoveAction
LookAction
mouseSpeed

CPP 파일
Enhanced Input을 사용하기 위해 Include
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubSystems.h"
#include "InputMappingContext.h"

Input, Input Mapping Context
static ConstructorHelpers::FObjectFinder<UInputMappingContext> InputContext(TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_PlayerDefault.IMC_PlayerDefault'"));
if (InputContext.Object != nullptr)
{
DefaultContext = InputContext.Object;
}
static ConstructorHelpers::FObjectFinder<UInputAction> InputMove(TEXT("/Script/EnhancedInput.InputAction'/Game/Input/IA_Move.IA_Move'"));
if (InputMove.Object != nullptr)
{
MoveAction = InputMove.Object;
}
static ConstructorHelpers::FObjectFinder<UInputAction> InputLook(TEXT("/Script/EnhancedInput.InputAction'/Game/Input/IA_Look.IA_Look'"));
if (InputLook.Object != nullptr)
{
LookAction = InputLook.Object;
}

캐릭터에 EnhancedInput
if (APlayerController* PlayerController = Cast<APlayerController>(GetController()))
{
if (UEnhancedInputLocalPlayerSubsystem* SubSystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
SubSystem->AddMappingContext(DefaultContext, 0);
}

}


UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &APlayerCharacter::Move);
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &APlayerCharacter::Look);

이동
const FVector2D MovementVector = value.Get<FVector2D>();
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);

const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);

화면 회전 
FVector2D LookAxisVector = value.Get<FVector2D>();

AddControllerYawInput(LookAxisVector.X * GetWorld()->DeltaTimeSeconds * mouseSpeed);
AddControllerPitchInput(LookAxisVector.Y * GetWorld()->DeltaTimeSeconds * -mouseSpeed);

카메라의 상하 이동 가능하게
SpringArm->bUsePawnControlRotation = true;

Visual Studio 단축키
Ctrl + / 전체 주석
Ctrl + K, O Header <-> cpp이동

Visual studio 연동 문제 생길 때
Engine이랑 Games Source위치에 존재하는 잘못 생성된 cpp, h파일 삭제.
탐색기 Source파일에 확인
프로젝트 파일 위치의 파일 4개 삭제, Generated visual studio
Visual Studio 열어서, 솔루션 정리

오류 발생 해결 순서
1. 오류 발생 Output 확인
2. 오류 위치 주석 처리
3. 오류 관련 로그 UE_LOG / GEngine->AddOnScreenDebugMessage()

🪽참고

UProperty 선언
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/unreal-engine-uproperties?application_version=5.3

메타 데이터
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/metadata-specifiers-in-unreal-engine

TMap
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/tmap?application_version=4.27

DELEGATE
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/delegates-and-lambda-functions-in-unreal-engine

이 블로그의 인기 게시물

250523 PCG 2

PCG Building Volume Sampler를 사용할 경우 Voxel Size를 맞추어주자. 2m길이를 Transform Points로 Offset을 이동시켜 Difference를 통해 메쉬를 생성한다. 사용시에 Pivot의 위치가 중앙이 아니면 제대로 표현되지 않을 것이다. PCG Landscape Landscape 생성후 PCG Volume 생성. Get Landscape Data - Surface Sampler 안보인다면 Generate Surface Sampler 일반 그리드 패턴으로 서피스 데이터에 포인트를 샘플링합니다. 이 노드에는 다음과 같은 옵션이 있습니다. 포인트 규모(Point Extents) : 서피스의 기본 그리드 셀 크기를 정의합니다. 여유(Looseness) : 변형 가능한 셀 크기를 정의합니다. 실제로 셀 크기는 포인트 규모 * (1 + 여유)입니다. 제곱미터당 포인트(Points Per Square Meter) : 유지되는 셀의 비율을 계산합니다. 이 프로퍼티는 그리드가 클 때 과잉을 제한합니다. Looseness : 기본 1. 0일경우 Extent의 길이 만큼, 1일경우 2배가 됨.  Attribute Filter를 생성하고, Material에 해당하는 Layer를 찾아서 이름을 넣어준다. Type을 Float로 하고 Float Value를 설정하면, 해당 머티리얼이 색칠된 정도 0~1에서 Operator에 의해 >(초과) 0.6초과 일 경우만 생성되게 할 수 있다. 값을 1로 하고 Equal을 이용해서 1인 경우만 생성되게 하는 것도 가능하다. plugin Water body lake를 넣으면, 이또한 Spline이라는 것을 알 수 있다. 따라서 Get Spline Data-Spline Sampler를 통해 사용할 수 있다. GetActorData와 Difference를 통해서 Lake내부를 제거해주기 PCG Mesh Mesh Sampler를 쓰기위해 Get Actor Property를 이용하면, 해당 액터가 ...

250604 저장불러오기

SaveGame 블루프린트 생성 Game Instance 생성, Init 오버라이드 AC_Inventory Save Load

250609 온라인

 Online Subsystem외에도 어느 서버를 사용할 것인지에 따라 플러그인을 추가해주어야 한다. 공통으로 OnlineSubsystem으로 시작한다. 헤더파일 CPP파일 cmd에서 Ipconfig를 통해 Ipv4를 넣어주면 된다. DefaultEngine.ini 수정 https://dev.epicgames.com/documentation/ko-kr/unreal-engine/online-subsystem-steam-interface-in-unreal-engine#%EC%99%84%EC%84%B1%EC%84%B8%ED%8C%85 [/Script/Engine.GameEngine] +NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemSteam.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver") [OnlineSubsystem] DefaultPlatformService=Steam [OnlineSubsystemSteam] bEnabled=true SteamDevAppId=480 bInitServerOnclient=true [/Script/OnlineSubsystemSteam.SteamNetDriver] NetConnectionClassName="OnlineSubsystemSteam.SteamNetConnection" 전용 서버 없이 클라이언트가 서버를 만들 수 있게 함. 호스팅 Binaries와 Saved파일을 한번 제거해주고, Generate해주기 헤더파일 헤더파일 CPP 파일 CreateSessionComplete, FindSessionsComplete, JoinSessionComplete 생성자 CreateGameSession 세션을 생성하고 존재하면 제거한다. OnCreateSessionComplete ServerTrav...