1. 소스코드 디버깅하기
- 에디터 끄기
- 솔루션파일 열기(없으면 프로젝트파일 -> Generate Visual Studio project files)디버깅할 솔루션 설정하기


중단점 추가 후
솔루션 선택 - 속성

공용속성 - 시작프로젝트구성 - 한 개의 시작 프로젝트 - 해당 프로젝트명 선택 - 확인
- F5 누르면 자동으로 언리얼 에디터 열림.
- 언리얼 프로젝트에서 실행하면 해당 중단점에서 브레이크걸림.

▶️ 디버깅 선택창 길이 늘리기
도구 - 사용자지정 - 명령 - 도구모음 - 표준 - 솔루션구성 선택하고 - 선택사항수정 클릭 - 너비를 300정도로 늘리기
솔루션 플랫폼 - 선택사항 누정 - 너비 120정도로 늘리기

▶️ 솔루션 구성 Debug Editor
Debug : 엔진과 게임 모두 빌드.
DebugGame : 게임만 디버깅하기 위한 용도.
DebugGame Editor : 디버깅용. 에디터로 실행
Development : 최적화 없이 엔진과 게임코드 모두 빌드.
Shipping : 릴리즈용. 디버깅용 정보 제거. 퍼포먼스 최적화
Test : Shipping과 동일하지만, 프로파일링 툴, 스탯, 콘솔코멘트 유지


2. 블루프린트에서 디버깅

1) 블루프린트에서 원하는 함수를 선택 - f9를 누르면 브레이크포인터가 추가됨.

2) 실행하고 해당 함수가 호출되면 위처럼 알려줌
2. [이론] NewObject , Outer와 Inner, 가비지 컬렉터 개념 정리
- NewObject : 언리얼에서 제공하는 UObject 타입을 생성하는 함수
런타임에서 오브젝트를 생성하기 위해 사용. (엔진 초기화 이후)

- Outer : 해당 객체를 소유하고 있는 소유자
- Inner : Outer 에 포함되어 있는 객체

인자로 넣으면 해당 오브젝트가 소유자가 된다.
위 코드에선 this를 넣었으니 this가 mDefaultInput의 소유자가 됨.
⭐⭐ Outer와 Inner의 개념이 중요한 이유 :
- 언리얼은 자체적으로 가비지 컬렉션을 지원함.
* 가비지 컬렉션의 동작원리 :
- 모든 객체들의 관계를 조사한다.
- 루트로부터 시작하여 하나씩 Outer, Inner 관계가 있는지 확인한다.
- 만약에 어떤 객체가 루트로부터 연결이 되어있지 않다면 해당 객체는 가비지 컬렉션의 대상이 된다.
이미지출처 : https://hyo-ue4study.tistory.com/272

가비지컬렉터 동작 알고리즘은 Mark & Sweep
- 마크 : 모든 객체를 돌며 지워질 수 있다고 판단하여 마크를 함.
- 스윕 : 루트서부터 객체를 돌면서 연결이 되어있다면 지워질수 없다고 판단하여 마크를 지움.
- 스윕단계를 거친 후 마크가 남은 애들만 가비지컬랙터가 지워버림
3. [개념] CDO
- T::StaticClass()는 CDO이다.
- CDO : Class Default Object
- 언리얼에서 참조가 일어날 경우 기본적으로 생성되는 객체
- 안에 내부적으로 객체 생성을 확인하게 되면
new 하고 있지 않고, malloc 을 통해서 메모리 할당을 하게 됨
▶️ new와 malloc의 차이점
-> 생성자를 호출하지 않는다.
- 언리얼은 자체적으로 메모리풀을 잡아준다.
- CDO 객체를 통해서 만든 데이터는
가급적 런타임중에는 수정을 하지 않는것을 권한다.
GEngine->AddOnScreenDebugMessage (); 화면에 로그 남기기
4. 런타임 중 키변경
1) 입력액션 IA_KeyChange 생성
- 블프 / input 폴더에 입력-입력액션을 통해 IA_KeyChange 입력액션 생성.
- 트리거 - 눌림 추가 => 눌렸을때 한번만 적용

2) IA_Context 에 IA_KeyChange 추가

3) IA_Move에 액션설명 추가하기

4) DefaultInputSystem에 추가
header
class UInputAction* mKeyChange;
cpp
static ConstructorHelpers::FObjectFinder<UInputAction>
keyAction( L"/Script/EnhancedInput.InputAction'/Game/Blueprint/Input/IA_KeyChange.IA_KeyChange'" );
if ( keyAction.Succeeded() )
mKeyChange = keyAction.Object;
5) playerBase에 연결
header
void KeyChangeAction( const struct FInputActionValue& value );
cpp
SetupPlayerInputComponent() 맨하단
inputCp->BindAction( mDefaultInput->mKeyChange, ETriggerEvent::Triggered, this, &APlayerBase::KeyChangeAction );
6) KeyChangeAction() 구현
UInputMappingContext* context = mDefaultInput->mContext; if ( !IsValid( context ) ) return; // TArray : 언리얼에서 제공하는 배열형 자료구조 // GetMappings() : 매핑된 목록 전부(TArray형태로) 가져옴 const TArray<FEnhancedActionKeyMapping>& mappings = context->GetMappings(); // int32 : 언리얼용 signed int // Num() : TArray에서 갯수 가져오는 함수 int32 cnt = mappings.Num(); for ( int32 i = 0 ; i < cnt ; ++i ) { FEnhancedActionKeyMapping& mappingKey = context->GetMapping( i ); const UInputAction* mappingAction = mappingKey.Action; if ( !IsValid( mappingAction ) ) continue; if ( mappingAction->ActionDescription.EqualTo( FText::FromString( L"InputMove" ) ) ) { // move up if ( mappingKey.Key.GetFName() == EKeys::W ) mappingKey.Key = FKey( EKeys::Up ); else if ( mappingKey.Key.GetFName() == EKeys::Up ) mappingKey.Key = FKey( EKeys::W ); // move down if ( mappingKey.Key.GetFName() == EKeys::S ) mappingKey.Key = FKey( EKeys::Down ); else if ( mappingKey.Key.GetFName() == EKeys::Down ) mappingKey.Key = FKey( EKeys::S ); // move left if ( mappingKey.Key.GetFName() == EKeys::A ) mappingKey.Key = FKey( EKeys::Left ); else if ( mappingKey.Key.GetFName() == EKeys::Left ) mappingKey.Key = FKey( EKeys::A ); // move right if ( mappingKey.Key.GetFName() == EKeys::D ) mappingKey.Key = FKey( EKeys::Right ); else if ( mappingKey.Key.GetFName() == EKeys::Right ) mappingKey.Key = FKey( EKeys::D ); } APlayerController* controller = Cast<APlayerController>( GetController() ); if ( !IsValid( controller ) ) return; UEnhancedInputLocalPlayerSubsystem* subSystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>( controller->GetLocalPlayer() ); if ( !IsValid( subSystem ) ) return; subSystem->RemoveMappingContext( mDefaultInput->mContext ); subSystem->AddMappingContext( mDefaultInput->mContext, 0 ); |
7) 실행하게되면 w,a,s,d로 캐릭터가 움직여지다가
왼쪽 컨트롤키를 누르게되면 화살표키를 이용해야만 캐릭터가 움직이게 된다.
▶️ ULocalPlayer
개별 플레이어의 화면, 입력, 상태를 관리하는 클래스
▶️ 포인터, 참조형 사용시
isValid() 사용하여 널체크 하는 습관을 들이기
'Unreal Engine5 > KDT 2024' 카테고리의 다른 글
[UE5 KDT2024] 7. 트리거 (키눌림) 차이, 언리얼 빌드 시스템 (0) | 2025.02.19 |
---|---|
[UE5 KDT2024] 6. TMap, TSet, TQueue (0) | 2025.02.18 |
[UE5 KDT2024] 4. 플레이어 기본 코드 생성 (0) | 2025.02.16 |
[UE5 KDT2024] 3. EnhancedInput 입력 테스트 (0) | 2025.02.15 |
[UE5 KDT2024] 2. 블루프린트 액터 생성 해보자. (0) | 2025.02.14 |
댓글