[B.C. Ch3 Assignment4] Pawn 클래스 3D 캐릭터 만들기

2026. 6. 10. 18:00·Unreal Engine/Project

미리 구현된 Character 클래스 대신, Pawn에서부터 직접 컴포넌트를 구성하고, 최신 Enhanced Input 시스템을 통해 입력 데이터를 처리하며, 캐릭터가 월드를 자유롭게 누비는 로직을 직접 설계.

 

Pawn 클래스 3D 캐릭터 만들기

 


프로젝트 링크

 

Github (Public): https://github.com/devcol-main/BC_Ch3_Assignment_4

 

GitHub - devcol-main/BC_Ch3_Assignment_4

Contribute to devcol-main/BC_Ch3_Assignment_4 development by creating an account on GitHub.

github.com

 

Google Drive (Share as Commenter) : https://drive.google.com/drive/folders/1_oS7Ye7cIGjDeKh576aLIErvQf6auTvm?usp=sharing

 

BC_Ch3_Assignment_4 - Google Drive

파일을 여기에 드래그 앤 드롭하거나 '신규' 버튼을 사용하세요.

drive.google.com

 

YouTube: https://youtu.be/r0LRk7ACkAY

 


 

이 프로젝트를 위한 준비 단계

1. [Unreal Engine/UE 기초] - Character 클래스 구현 | [언리얼 엔진 C++ (Unreal Engine C++)]

 

Character 클래스 구현 | [언리얼 엔진 C++ (Unreal Engine C++)]

Character 클래스 구현 Pawn과 Character Class 정의 1️⃣ Pawn 클래스란?Pawn은 플레이어 혹은 AI가 “소유( Possess )”할 수 있는 가장 상위 클래스입니다. 즉, 엔진에서 “무언가를 조종한다”라고 할 때

devcol.tistory.com

 

2. [Unreal Engine/UE 기초] - Enhanced Input System 입력 매핑 구현하기 | [언리얼 엔진 C++ (Unreal Engine C++)]

 

Enhanced Input System 입력 매핑 구현하기 | [언리얼 엔진 C++ (Unreal Engine C++)]

Enhanced Input System 입력 매핑 구현하기 PlayerController, IMC, IA PlayerController 이해하기 1️⃣ PlayerController란?PlayerController는 사용자가 키보드, 마우스, 게임패드 등에서 입력을 받으면, 그 입력을 해석하

devcol.tistory.com

 

3. [Unreal Engine/UE 기초] - 캐릭터 동작 구현과 입력 처리 | [언리얼 엔진 C++ (Unreal Engine C++)]

 

캐릭터 동작 구현과 입력 처리 | [언리얼 엔진 C++ (Unreal Engine C++)]

캐릭터 동작 구현과 입력 처리 캐릭터 동작 구현과 입력 처리 관련 이전에 한 것들 GameMode Class 가 관리하고 있는 것: Character Class, Player ControllerCharacter Class 가 월드에 스폰 되도록Player Controller: 사

devcol.tistory.com

 

4. [Unreal Engine/UE 기초] - 캐릭터 애니메이션 적용 | [언리얼 엔진 C++ (Unreal Engine C++)]

 

캐릭터 애니메이션 적용 | [언리얼 엔진 C++ (Unreal Engine C++)]

캐릭터 애니메이션 적용 애니메이션 블루프린트 이해하기 1️⃣ 애니메이션 블루프린트 (Anim Blueprint)란?애니메이션 블루프린트는 언리얼 엔진에서 캐릭터의 골격(스켈레톤) 기반 애니메이션을

devcol.tistory.com

 


 

필수 구현 기능

 

C++ Pawn 클래스 및 컴포넌트 구성

  • [x] Pawn 클래스 생성: Pawn을 상속받는 새로운 C++ 클래스를 생성합니다.
  • [x] 컴포넌트 추가: 아래 컴포넌트들을 Pawn 클래스에 추가합니다.
    • CapsuleComponent (또는 Box/Sphere 중 택 1)
    • SkeletalMeshComponent
    • SpringArmComponent
    • CameraComponent
  • [x] 계층 구조 설정: 충돌 컴포넌트를 RootComponent로 설정하고, 나머지 컴포넌트들을 부착합니다.
  • [x] DefaultPawn 설정: GameMode 클래스에서 DefaultPawnClass를 본인이 만든 Pawn으로 지정합니다.
  • [x] Physics 설정: 루트 충돌체 및 Mesh의 Simulate Physics를 false로 설정합니다. (물리 대신 코드로 직접 제어)

 


 

Enhanced Input 매핑 & 바인딩

  • [x] 입력 액션(IA) 생성: 아래 두 가지 액션을 생성합니다. (타입: Vector2D)
    • IA_Move (WASD 이동용)
    • IA_Look (마우스 회전용)
  • [x] IMC 매핑: 생성한 액션들을 Input Mapping Context에 등록하고 키를 할당합니다.
  • [x] 액션 바인딩: SetupPlayerInputComponent()에서 입력 처리 함수와 액션들을 바인딩합니다.

이동 및 회전 로직 구현

  • [x] 프레임 독립성: DeltaTime을 사용하여 프레임 속도와 관계없이 일정한 속도로 움직이도록 구현합니다.
  • [x] 이동 구현: AddActorLocalOffset() 등을 활용해 WASD 입력에 따라 Pawn이 움직이도록 작성합니다.
    • 이동 방향은 Pawn의 Forward/Right 벡터를 기준으로 결정됩니다.
  • [x] 회전 구현: AddActorLocalRotation() 등을 활용해 마우스 입력에 따라 회전하도록 작성합니다.
    • 마우스 입력값으로 Yaw와 Pitch를 직접 계산하여 구현합니다.
    • ⚠️ 주의: AddControllerYawInput(), AddControllerPitchInput() 등 엔진 기본 제공 함수는 사용하지 않습니다.
  • [x] 제한 사항: 평면 상에서의 이동과 회전만 처리하며, 중력이나 낙하 효과는 고려하지 않습니다.

 


도전 구현 기능

 

6자유도(6 DOF) 비행체 구현

 

  • [x] 6축 액션 구현: 아래 방향에 대한 이동 및 회전을 모두 구현합니다.
    • [x] 이동: 전/후(W, S), 좌/우(A, D), 상/하(Space, Shift)
    • [x] 회전: Yaw(마우스 X), Pitch(마우스 Y), Roll(마우스 휠 또는 별도 키)
  • [x] Local 기반 이동: 단순 월드 좌표 이동이 아닌, Pawn의 현재 회전 상태(로컬 좌표계)를 기준으로 이동 방향이 결정되도록 구현합니다.

 


중력 및 낙하 시스템 구현

 

  • [x] 인공 중력: Tick() 함수에서 매 프레임 중력 가속도를 직접 계산하여 적용합니다. (예: -980 cm/s²)
  • [x] 지면 충돌 감지: LineTrace 또는 SweepTrace를 사용하여 지면과의 충돌을 체크합니다.
  • [x] 상태 초기화: 지면에 착지하는 순간 Z축 낙하 속도를 0으로 초기화합니다.

 


에어 컨트롤(Air Control) 구현

 

  • [x] 이동 속도 제한: 공중에 떠 있는 상태에서는 지상 이동 속도의 30~50% 수준으로 제한합니다.
  • [x] 상태별 로직 분기: 지상 상태와 공중 상태를 구분하여 각각 자연스러운 움직임이 나타나도록 구현합니다.

 


 

캐릭터관련 전체 코드

 

.h

더보기
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "AircraftPawnBaseCharacter.generated.h"


class UCapsuleComponent;
class UStaticMeshComponent;
class USpringArmComponent; 
class UCameraComponent; 
class UInputMappingContext;
class UInputAction;

struct FInputActionValue;

UCLASS()
class BC_CH3_ASSIGNMENT_4_API AAircraftPawnBaseCharacter : public APawn
{
    GENERATED_BODY()

public:
    // Sets default values for this pawn's properties
    AAircraftPawnBaseCharacter();

protected:
    
    
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
    
protected:
    
    //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Character")
    //TObjectPtr<USceneComponent> SceneRoot = nullptr;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Character")    
    TObjectPtr<UCapsuleComponent> CapsuleComp = nullptr;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Character")  
    UStaticMeshComponent* StaticMeshComponent = nullptr;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Character")  
    UStaticMeshComponent* StaticMeshComponent_Ground = nullptr;
    
    
    // Camera
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera")
    USpringArmComponent* SpringArmComp = nullptr;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera")
    UCameraComponent* CameraComp = nullptr;
    

    //
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
    UInputMappingContext* InputMappingContext;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
    UInputAction* MoveAction;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
    UInputAction* LookAction;
    
    //
    //Ground Check
    UPROPERTY(EditAnywhere, Category = "GroundCheck")
    float GroundCheckDistance = 10.0f;
    UPROPERTY(EditAnywhere, Category = "GroundCheck")
    float GroundCheckRadius = 30.0f;
    UPROPERTY(VisibleAnywhere, Category = "GroundCheck")
    bool bIsGrounded = false;
    
    //

    //FVector2D CurrentMoveInput;
    FVector CurrentMoveInput;
    FVector CurrentLookInput;
    
    //
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Environment")
    float Gravity = -980.0f;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Environment")
    float UpMultiplier = 10.0f;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Control")
    float NormalMoveSpeed;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Control")
    float AirMoveSpeed = 0.5f;
    
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Control")
    float LookSpeed;      
    
    void Move(const FInputActionValue& Value);
    void StopMove(const FInputActionValue& Value);
    void Look(const FInputActionValue& Value);
    void StopLook(const FInputActionValue& Value);
    
    UFUNCTION(BlueprintCallable)
    bool CheckGrounded();
private:
    void InitialSetup();
};
 

 

.cpp

더보기
#include "AircraftPawnBaseCharacter.h"

#include "Components/CapsuleComponent.h"
#include "Components/StaticMeshComponent.h"

#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"

#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h" 

#include "DrawDebugHelpers.h"

// Sets default values
AAircraftPawnBaseCharacter::AAircraftPawnBaseCharacter()
{
	InitialSetup();

}

void AAircraftPawnBaseCharacter::InitialSetup()
{
	
	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	
	//
	CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleComp"));	
	SetRootComponent(CapsuleComp);
	
	StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComponent"));
	StaticMeshComponent->SetupAttachment(CapsuleComp);
	//
	SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
	SpringArmComp->SetupAttachment(RootComponent);	
	
	CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
	CameraComp->SetupAttachment(SpringArmComp, USpringArmComponent::SocketName);
	
	//
	StaticMeshComponent_Ground = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComponent_Ground"));
	StaticMeshComponent_Ground->SetupAttachment(RootComponent);
	
	//
	// Physics Setting
	CapsuleComp->SetSimulatePhysics(false);
	StaticMeshComponent->SetSimulatePhysics(false);
	
	// Set Variable
	NormalMoveSpeed = 1000.0f;	
	LookSpeed = 100.0f;
	
	
	StaticMeshComponent_Ground->SetVisibility(true);
}

// Called when the game starts or when spawned
void AAircraftPawnBaseCharacter::BeginPlay()
{
	Super::BeginPlay();
	
	APlayerController* PlayerController = Cast<APlayerController>(GetController());
	if (PlayerController)
	{
		ULocalPlayer* LocalPlayer = PlayerController->GetLocalPlayer();

		if (LocalPlayer)
		{
			// Local Player에서 EnhancedInputLocalPlayerSubsystem을 획득
			// UEnhancedInputLocalPlayerSubsystem: 입력 시스템을 관리 (IMC 추가 혹은 삭제하는 역할)
			UEnhancedInputLocalPlayerSubsystem* Subsystem =
				LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>();

			if (Subsystem && InputMappingContext)
			{
				// Subsystem을 통해 우리가 할당한 IMC를 활성화
				// 우선순위(Priority)는 0이 가장 높은 우선순위
				Subsystem->AddMappingContext(InputMappingContext, 0);
			}
		}
	}
}

// Called every frame
void AAircraftPawnBaseCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	
	const bool bHasLookInput =
		!FMath::IsNearlyZero(CurrentLookInput.X) ||
	!FMath::IsNearlyZero(CurrentLookInput.Y) ||
	!FMath::IsNearlyZero(CurrentLookInput.Z);
	
	const bool bHasMoveInput =
	!FMath::IsNearlyZero(CurrentMoveInput.X) ||
	!FMath::IsNearlyZero(CurrentMoveInput.Y) ||
		!FMath::IsNearlyZero(CurrentMoveInput.Z);
	
	
	bIsGrounded = CheckGrounded();
	
	if (!bIsGrounded)
	{
		if (GEngine)
		{ 
			GEngine->AddOnScreenDebugMessage(
					-1, 0.5f, FColor::Green, 
					TEXT("AIR"));
		}
		
		AddActorWorldOffset(FVector(0.0f, 0.0f, Gravity) * DeltaTime, true);
		
		if (bHasMoveInput)
		{
			const FVector LocalMoveOffset =
				FVector(CurrentMoveInput.X, CurrentMoveInput.Y, 
					CurrentMoveInput.Z * UpMultiplier)
				* NormalMoveSpeed * AirMoveSpeed
				* DeltaTime;

			AddActorLocalOffset(LocalMoveOffset);
		
		}	
	}
	else
	{	
		
		if (GEngine)
		{ 
			GEngine->AddOnScreenDebugMessage(
					-1, 0.5f, FColor::Blue, 
					TEXT("GROUND"));
		}

		AddActorWorldOffset(FVector(0));		
		
		if (bHasMoveInput)
		{
			FVector LocalMoveOffset =
				FVector(CurrentMoveInput.X, CurrentMoveInput.Y, 
					CurrentMoveInput.Z * UpMultiplier)
				* NormalMoveSpeed
				* DeltaTime;
			
			LocalMoveOffset.Z = FMath::Max(LocalMoveOffset.Z, 0.0f);
			
			AddActorLocalOffset(LocalMoveOffset);
		
		}
	}	

	// loock
	if (bHasLookInput)
	{
		
		FRotator SpringArmRot = SpringArmComp->GetRelativeRotation();

		SpringArmRot.Pitch += CurrentLookInput.Y * LookSpeed * DeltaTime;
		SpringArmRot.Yaw += CurrentLookInput.X * LookSpeed * DeltaTime;
		SpringArmRot.Roll += CurrentLookInput.Z * (LookSpeed* 2.0f) * DeltaTime;

		SpringArmRot.Pitch = FMath::Clamp(SpringArmRot.Pitch, -60.0f, 30.0f);
		SpringArmRot.Yaw = FMath::Clamp(SpringArmRot.Yaw, -60.0f, 60.0f);

		//SpringArmComp->SetRelativeRotation(SpringArmRot);
		AddActorLocalRotation(SpringArmRot);
		

	}
}

// Called to bind functionality to input
void AAircraftPawnBaseCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	
	UEnhancedInputComponent* EnhancedInputComponent =
Cast<UEnhancedInputComponent>(PlayerInputComponent);
	
	
	if (EnhancedInputComponent)
	{
		if (MoveAction)
		{
			EnhancedInputComponent->BindAction(
				MoveAction,
				ETriggerEvent::Triggered,
				this,
				&AAircraftPawnBaseCharacter::Move
			);
			
			EnhancedInputComponent->BindAction(
				MoveAction,
				ETriggerEvent::Completed,
				this,
				&AAircraftPawnBaseCharacter::StopMove
			);
		}
		

		if (LookAction)
		{
			EnhancedInputComponent->BindAction(
				LookAction,
				ETriggerEvent::Triggered,
				this,
				&AAircraftPawnBaseCharacter::Look
			);
			
			EnhancedInputComponent->BindAction(
				LookAction,
				ETriggerEvent::Completed,
				this,
				&AAircraftPawnBaseCharacter::StopLook
			);
			
			
		}
	}	

}



void AAircraftPawnBaseCharacter::Move(const FInputActionValue& Value)
{
	if (!Controller) return;
	
	//CurrentMoveInput = Value.Get<FVector2D>();
	CurrentMoveInput = Value.Get<FVector>();
	
}

void AAircraftPawnBaseCharacter::StopMove(const FInputActionValue& Value)
{
	CurrentMoveInput = FVector::ZeroVector;
}

void AAircraftPawnBaseCharacter::StopLook(const FInputActionValue& Value)
{
	CurrentLookInput = FVector::ZeroVector;
}

void AAircraftPawnBaseCharacter::Look(const FInputActionValue& Value)
{
	CurrentLookInput = Value.Get<FVector>();
	
}


bool AAircraftPawnBaseCharacter::CheckGrounded()
{

	FVector StartLocation = GetActorLocation();
	FVector DownVector = -GetActorUpVector(); 
    
	float TraceDistance = 50.f; 
	FVector EndLocation = StartLocation + (DownVector * TraceDistance);

	float CollisionRadius = 40.f;
	FCollisionShape SphereShape = FCollisionShape::MakeSphere(CollisionRadius);

	
	FHitResult HitResult;
	FCollisionQueryParams QueryParams;
	QueryParams.AddIgnoredActor(this);

	bool bHit = GetWorld()->SweepSingleByChannel(
		HitResult,
		StartLocation,
		EndLocation,
		FQuat::Identity,
		ECC_Visibility,
		SphereShape,
		QueryParams
	);

	// [선택 사항] 에디터에서 충돌 영역을 눈으로 확인하고 싶을 때 사용
	DrawDebugSphere(GetWorld(), EndLocation, CollisionRadius, 12, FColor::Orange, false, -1.f);

	StaticMeshComponent_Ground->SetVisibility(bHit);
	
	return bHit;
}

 


 

디버깅

 

[Unreal Engine/Debugging] - [Debugging] Pawn 클래스 3D 캐릭터 만들기| [언리얼 엔진 C++ (Unreal Engine C++)]

 

[Debugging] Pawn 클래스 3D 캐릭터 만들기| [언리얼 엔진 C++ (Unreal Engine C++)]

Debugging Log - [B.C. Ch3 Assignment4] Pawn 클래스 3D 캐릭터 만들기 코드에서 EnhancedInputComponent 는 들어와 지는데, MoveAction 는 false 가 계속 나오는 상황. ```cppvoid APawnBaseCharacter::SetupPlayerInputComponent(UInputCompo

devcol.tistory.com

 


 

추천

 

[Unreal Engine/UE 기초] - Character 클래스 구현 | [언리얼 엔진 C++ (Unreal Engine C++)]

 

Character 클래스 구현 | [언리얼 엔진 C++ (Unreal Engine C++)]

Character 클래스 구현 Pawn과 Character Class 정의 1️⃣ Pawn 클래스란?Pawn은 플레이어 혹은 AI가 “소유( Possess )”할 수 있는 가장 상위 클래스입니다. 즉, 엔진에서 “무언가를 조종한다”라고 할 때

devcol.tistory.com

 

[Unreal Engine/UE 기초] - Enhanced Input System 입력 매핑 구현하기 | [언리얼 엔진 C++ (Unreal Engine C++)]

 

Enhanced Input System 입력 매핑 구현하기 | [언리얼 엔진 C++ (Unreal Engine C++)]

Enhanced Input System 입력 매핑 구현하기 PlayerController, IMC, IA PlayerController 이해하기 1️⃣ PlayerController란?PlayerController는 사용자가 키보드, 마우스, 게임패드 등에서 입력을 받으면, 그 입력을 해석하

devcol.tistory.com

 

[Unreal Engine/UE 기초] - 캐릭터 동작 구현과 입력 처리 | [언리얼 엔진 C++ (Unreal Engine C++)]

 

캐릭터 동작 구현과 입력 처리 | [언리얼 엔진 C++ (Unreal Engine C++)]

캐릭터 동작 구현과 입력 처리 캐릭터 동작 구현과 입력 처리 관련 이전에 한 것들 GameMode Class 가 관리하고 있는 것: Character Class, Player ControllerCharacter Class 가 월드에 스폰 되도록Player Controller: 사

devcol.tistory.com

 

[Unreal Engine/UE 기초] - 캐릭터 애니메이션 적용 | [언리얼 엔진 C++ (Unreal Engine C++)]

 

캐릭터 애니메이션 적용 | [언리얼 엔진 C++ (Unreal Engine C++)]

캐릭터 애니메이션 적용 애니메이션 블루프린트 이해하기 1️⃣ 애니메이션 블루프린트 (Anim Blueprint)란?애니메이션 블루프린트는 언리얼 엔진에서 캐릭터의 골격(스켈레톤) 기반 애니메이션을

devcol.tistory.com

 


[Unreal Engine/Debugging] - [Debugging] Pawn 클래스 3D 캐릭터 만들기| [언리얼 엔진 C++ (Unreal Engine C++)]

 

[Debugging] Pawn 클래스 3D 캐릭터 만들기| [언리얼 엔진 C++ (Unreal Engine C++)]

Debugging Log - [B.C. Ch3 Assignment4] Pawn 클래스 3D 캐릭터 만들기 코드에서 EnhancedInputComponent 는 들어와 지는데, MoveAction 는 false 가 계속 나오는 상황. ```cppvoid APawnBaseCharacter::SetupPlayerInputComponent(UInputCompo

devcol.tistory.com

 

 


[페이지] Unreal Engine | 언리얼 엔진

 

 

저작자표시 동일조건 (새창열림)
'Unreal Engine/Project' 카테고리의 다른 글
  • [B.C. Ch3 Assignment3] 회전, 이동, 랜덤, 생성
DevCol
DevCol
DevCol (Development Collaboration). 함께 개발 & 공부 & IT 정보 나눔장소
  • DevCol
    DevCol (Development Collaboration)
    DevCol
  • 블로그 메뉴

    • Unreal Engine
    • TIL
    • 게임국가기술자격검정 게임프로그래밍전문가 [한국콘텐츠진흥원]
    • 분류 전체보기 (73) N
      • Unreal Engine (31) N
        • Project (2) N
        • Dev Log (0)
        • Debugging (2) N
        • Blueprint (1)
        • UE 기초 (25) N
        • UE 심화 (0)
        • TA (1) N
      • Programming Language (0)
        • C++ (0)
        • C# (0)
      • Unity Engine (0)
      • 자격증 (3)
        • 게임국가기술자격검정 [한국콘텐츠진흥원] (3)
      • Coding Test | 코딩테스트 (0)
        • 프로그래머스 기초 (0)
        • 프로그래머스 입문 (0)
      • TIL (38) N
        • Boot Camp (32) N
      • Git & Github (1)
  • 링크

    • Youtube
    • GitHub
    • itch.io
    • Blog (En)
  • 공지사항

  • 인기 글

  • 태그

    Programming
    언리얼 엔진
    Devlog
    C++
    코드카타
    게임 개발
    c
    UE5
    프로그래밍
    Unreal engine
    til
    UE
    내일배움캠프
    기초
    코드 카타
    게임개발
    Code Kata
    Boot Camp
    cpp
    Game Dev
  • 최근 글

  • GitHub Youtube itch
  • hELLO · Designed By 정상우.v4.10.6
  • DevCol
    [B.C. Ch3 Assignment4] Pawn 클래스 3D 캐릭터 만들기
    상단으로

    티스토리툴바