C++

2026-6-1 코드카타

왕건 2026. 6. 1. 10:02

오늘 학습한 내용

오늘 코드카타에서는 Unreal Engine에서 Pawn을 구현할 때 필요한 기본 구성 요소와 입력 처리 흐름을 복습했다. 특히 PlayerController가 Pawn을 조종하는 과정, Pawn을 구성하는 주요 Component들의 역할, 그리고 입력 함수를 어디에서 바인드해야 하는지를 정리할 수 있었다.

1. PlayerController와 Pawn의 관계

PlayerController가 Pawn을 소유해서 조종하게 되는 과정을 Possess라고 한다.

Unreal Engine에서 Pawn은 조종 가능한 대상이고, PlayerController는 실제 입력을 받아 Pawn에게 전달하는 역할을 한다. 즉, Pawn 자체가 플레이어 입력을 직접 소유한다기보다는 PlayerController가 Pawn을 Possess함으로써 조작이 가능해진다.

이번 문제를 통해 Controller와 Pawn의 관계를 다시 정리할 수 있었다.

2. 인간형 Pawn의 기본 루트 컴포넌트

인간형 Pawn을 구현할 때 루트 컴포넌트로 주로 사용되는 것은 CapsuleComponent이다.

CapsuleComponent는 캐릭터나 Pawn의 충돌 범위를 표현하는 데 적합하다. 사람 형태의 캐릭터는 위아래로 긴 형태이기 때문에 단순한 박스보다 캡슐 형태의 충돌체가 자연스럽다.

즉, CapsuleComponent는 단순히 보이는 외형이 아니라 충돌 처리의 기준이 되는 컴포넌트라고 이해했다.

3. SpringArmComponent의 역할

SpringArmComponent는 3인칭 카메라 구도를 설정할 때 사용된다.

카메라를 Pawn에 바로 붙이면 움직임이나 회전에 따라 화면이 너무 급격하게 변할 수 있다. SpringArmComponent를 사용하면 Pawn과 CameraComponent 사이에 일정한 거리를 둘 수 있고, 3인칭 시점에서 자연스러운 카메라 위치를 만들 수 있다.

따라서 SpringArmComponent는 카메라 자체라기보다는 카메라를 적절한 거리와 위치에 배치하기 위한 보조 컴포넌트라고 볼 수 있다.

4. FloatingPawnMovementComponent의 역할

FloatingPawnMovementComponent는 Pawn의 이동 처리를 담당한다.

Pawn은 기본적으로 Character처럼 복잡한 이동 기능을 자동으로 제공하지 않는다. 그래서 Pawn을 움직이려면 MovementComponent가 필요하다. FloatingPawnMovementComponent를 사용하면 Pawn이 입력값에 따라 이동할 수 있다.

즉, Pawn에 입력을 바인딩하는 것만으로는 실제 이동이 완성되지 않고, 이동을 처리할 MovementComponent가 함께 필요하다는 점을 알게 되었다.

5. 입력 바인딩 함수

Pawn에서 입력 처리 함수를 바인드하기 가장 적절한 함수는 SetupPlayerInputComponent()이다.

BeginPlay()는 게임 시작 시 초기화에 사용되고, Tick()은 매 프레임 반복 실행에 사용된다. 반면 입력 액션이나 축 입력을 연결하는 작업은 SetupPlayerInputComponent()에서 처리하는 것이 적절하다.

입력 처리 코드를 아무 함수에나 작성하는 것이 아니라, Unreal Engine이 제공하는 입력 바인딩 흐름에 맞춰 작성해야 한다는 점이 중요했다.

오늘 알게 된 점

오늘 문제를 풀면서 Pawn을 구성할 때 각 컴포넌트가 서로 다른 책임을 가진다는 것을 알게 되었다.

  • PlayerController는 Pawn을 Possess하여 조종한다.
  • CapsuleComponent는 충돌 기준이 되는 루트 컴포넌트로 사용된다.
  • SpringArmComponent는 3인칭 카메라 구도를 잡는 데 사용된다.
  • FloatingPawnMovementComponent는 Pawn의 이동을 처리한다.
  • SetupPlayerInputComponent()는 입력 함수를 바인딩하는 곳이다.

처음에는 각 컴포넌트를 단순히 외워야 하는 개념처럼 느꼈지만, 정리해보니 Pawn을 만들기 위한 역할 분담 구조로 이해할 수 있었다.

회고

오늘 코드카타를 통해 Unreal Engine에서 Pawn을 직접 구현할 때 필요한 기본 흐름을 복습했다. 단순히 정답을 맞히는 것보다, 왜 해당 컴포넌트가 필요한지 이해하는 것이 더 중요하다고 느꼈다.

다음에는 직접 Pawn 클래스를 만들어서 CapsuleComponent, SpringArmComponent, CameraComponent, FloatingPawnMovementComponent를 붙여보고, SetupPlayerInputComponent()에서 이동 입력까지 연결해보면서 개념을 코드로 확인해봐야겠다.

코딩테스트 연습

 

 

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

string solution(string X, string Y) {
    string answer = "";
    
    for(int i = 0; i < X.length(); i++)
    {
        for(int j = 0; j < Y.length(); j++)
        {
            if(X[i] == Y[j])
            {
                answer += X[i];
                Y.erase(j, 1);
                break;
            }
            else
            {
                continue;
            }
        }
    }
    sort(answer.begin(), answer.end(), greater<char>());
    if(answer == "")
    {
        answer = "-1";
        return answer;
    }
    else if(answer[0] == '0')
    {
        answer = "0";
        return answer;
    }
    else
    {
    
    return answer;
    }
}

 

이렇게 작성을 하였지만 X,Y조건이 3 부터 3,000,000이였기 때문에 실행시간 초과로 통과를 못하였다.

좀더 줄여보기위해

문자열을 직접 비교하면서 지우는 대신, 숫자 개수를 세는 방식으로 변경했다.

숫자는 0부터 9까지만 존재하므로 크기가 10인 배열을 만들고, 각 숫자가 몇 번 등장하는지 저장했다.


여기서
c - '0'은 문자로 된 숫자를 실제 숫자 인덱스로 바꾸기 위해 사용한다.

예를 들어 문자 '5'는 배열의 5번 위치에 저장되어야 하므로 countX[5]를 증가시킨다.

#include <string>
#include <algorithm>

using namespace std;

string solution(string X, string Y) {
    int countX[10] = {};
    int countY[10] = {};

    for (char c : X) {
        countX[c - '0']++;
    }

    for (char c : Y) {
        countY[c - '0']++;
    }

    string answer = "";

    for (int i = 9; i >= 0; i--) {
        int commonCount = min(countX[i], countY[i]);

        for (int j = 0; j < commonCount; j++) {
            answer += to_string(i);
        }
    }

    if (answer == "") {
        return "-1";
    }

    if (answer[0] == '0') {
        return "0";
    }

    return answer;
}

 

'C++' 카테고리의 다른 글

2026-6-2 코드카타  (0) 2026.06.02
STL  (0) 2026.03.24
기본 생성자와 오버로딩  (0) 2026.03.12
생성자와 소멸자  (0) 2026.03.12
C++로 전직 시스템과 전투 시스템 구현해보기  (0) 2026.03.10