[Unreal][C++] ํ”Œ๋ ˆ์ด์–ด ์บ๋ฆญํ„ฐ

2024. 2. 22. 20:29ยท๐Ÿ“ Game/โœ Unreal

Character ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•ด์„œ ํ”Œ๋ ˆ์ด์–ด์˜ ์ž…๋ ฅ์— ๋ฐ˜์‘ํ•˜๋Š” ์บ๋ฆญํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด ๋ณผ ๊ฒƒ์ด๋‹ค.

 

1. Character ํด๋ž˜์Šค

Character ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” C++ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. Character ํด๋ž˜์Šค๋Š” Pawn ํด๋ž˜์Šค์˜ ์ž์‹์œผ๋กœ ์ด์กฑ ๋ณดํ–‰๊ณผ ๊ฐ™์€ ์•„๋ฐ”ํƒ€์— ์‚ฌ์šฉ๋œ๋‹ค.

 

Character ํด๋ž˜์Šค

 

์ด์ œ ์ด ์บ๋ฆญํ„ฐ ํด๋ž˜์Šค์— 3์ธ์นญ ์นด๋ฉ”๋ผ๋ฅผ ๋ถ™์ผ ๊ฒƒ์ด๋‹ค.

 

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
USpringArmComponent* CameraBoom;

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
UCameraComponent* FollowCamera;
ASurvivorCharacter::ASurvivorCharacter()
{
	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(RootComponent);
	CameraBoom->TargetArmLength = 150.0f;
	CameraBoom->bUsePawnControlRotation = true;
	CameraBoom->bDoCollisionTest = false;

	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
	FollowCamera->bUsePawnControlRotation = false;
}
  • CreateDefaultSubobject: ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”์‹œํ‚ค๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์ƒ์„ฑ์ž ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ด๋ฆ„์„ ๋„˜๊ฒจ์ค€๋‹ค.

 

๊ทธ ํ›„ ์ƒ์„ฑํ•œ Character ํด๋ž˜์Šค๋ฅผ ๋ฒ ์ด์Šค๋กœ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค๋ฅผ ์„ค์ •์—์„œ Default Pawn Class๋กœ ์ ์šฉํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ ˆ๋ฒจ ์‹œ์ž‘ ์‹œ ์ƒ์„ฑํ•œ ์บ๋ฆญํ„ฐ๋กœ ํ”Œ๋ ˆ์ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค.

 

Character ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค

 

2. FBX ์ž„ํฌํŠธ

์บ๋ฆญํ„ฐ๋กœ ์‚ฌ์šฉ๋  ๋ฉ”์‹œ๋ฅผ ์ž„ํฌํŠธ ํ•  ๊ฒƒ์ด๋‹ค. ์ฝ˜ํ…์ธ  ๋ธŒ๋ผ์šฐ์ € ๋‚ด ์ž„ํฌํŠธ ๋ฒ„ํŠผ์„ ํ†ตํ•ด FBX๋ฅผ ์ž„ํฌํŠธ ํ•˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž„ํฌํŠธ ์˜ต์…˜ ์ฐฝ์ด ๋œจ๊ฒŒ ๋œ๋‹ค.

 

FBX ์ž„ํฌํŠธ ์˜ต์…˜

  • Mesh-Auto Generate Collision: ์ถฉ๋Œ๊ฐ’์„ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

 

์ž„ํฌํŠธ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด ๋ฉ”์‹œ์™€ ํ•จ๊ป˜ ์—ฌ๋Ÿฌ ํŒŒ์ผ๋“ค์„ ํ•จ๊ป˜ ๊ฐ€์ ธ์˜จ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ํŠน์ • ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ฌ์ง€ ๋ง์ง€๋Š” ์˜ต์…˜์„ ํ†ตํ•ด ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

FBX ์ž„ํฌํŠธ

  • ์Šค์ผˆ๋ ˆํ†ค: ์Šค์ผˆ๋ ˆํƒˆ ๋ฉ”์‹œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ผˆ ๊ตฌ์กฐ์ด๋‹ค.
  • ์Šค์ผˆ๋ ˆํƒˆ ๋ฉ”์‹œ
  • ํ”ผ์ง์Šค ์• ์…‹: ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋Œ€์‘ ์ฝœ๋ฆฌ์ „ ๋ฐ์ดํ„ฐ์ด๋‹ค.
  • ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œํ€€์Šค: ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฐ์ดํ„ฐ์ด๋‹ค.
  • ๋จธํ„ฐ๋ฆฌ์–ผ

 

์ด๋ ‡๊ฒŒ ๊ฐ€์ ธ์˜จ ์• ์…‹๋“ค์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋‹ค ๋ณด๋ฉด ์• ์…‹ ๊ฐ„ ํ˜ผ๋™์ด ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ณ„ ์• ์…‹์— ๋Œ€ํ•œ ๊ณตํ†ต์˜ ๋ช…๋ช… ๊ทœ์น™์„ ์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 

๋ช…๋ช… ๊ทœ์น™

 

์ด์ œ ์บ๋ฆญํ„ฐ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค์—์„œ ์Šค์ผˆ๋ ˆํƒˆ ๋ฉ”์‹œ ์• ์…‹์„ ์ž„ํฌํŠธ ํ•œ ์Šค์ผˆ๋ ˆํƒˆ ๋ฉ”์‹œ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

 

์Šค์ผˆ๋ ˆํƒˆ ๋ฉ”์‹œ ์• ์…‹

 

๋ฉ”์‹œ๋ฅผ ๋ณ€๊ฒฝํ•œ ํ›„ ๋ ˆ๋ฒจ ๋‚ด ์‚ฌ์ด์ฆˆ์™€ ๋งž์ง€ ์•Š๋‹ค๋ฉด, ๋ฉ”์‹œ์˜ ํŠธ๋žœ์Šคํผ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•˜๋‹ค.

 

์Šค์ผˆ๋ ˆํƒˆ ๋ฉ”์‹œ ์ ์šฉ

 

3. ๋จธํ„ฐ๋ฆฌ์–ผ

์ด์ œ ์บ๋ฆญํ„ฐ์—๊ฒŒ ์ƒ‰์„ ์ž…ํ˜€๋ณผ ๊ฒƒ์ด๋‹ค. ๋จผ์ € ๊ด€๋ จ Texture ํŒŒ์ผ์„ ์ž„ํฌํŠธ ํ•œ ํ›„ FBX ์ž„ํฌํŠธ ์‹œ ํ•จ๊ป˜ ์ƒ์„ฑ๋œ ๋จธํ„ฐ๋ฆฌ์–ผ์„ ๋”๋ธ” ํด๋ฆญํ•œ๋‹ค. ์ด์ œ Texture Sample ๋…ธ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ ๊ฐ’์— ๋งž๋Š” ํ…์Šค์ณ๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค. ๋ฒ ์ด์Šค ์ปฌ๋Ÿฌ๋งŒ ์žˆ์–ด๋„ ์ƒ‰์€ ๋งŒ๋“ค์–ด์ง€์ง€๋งŒ, ๋‹ค๋ฅธ ํŠน์ˆ˜ ๊ฐ’์„ ํ†ตํ•ด ๋”์šฑ๋” ๋””ํ…Œ์ผํ•˜๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค.

 

๋จธํ„ฐ๋ฆฌ์–ผ

  • ๋ฒ ์ด์Šค ์ปฌ๋Ÿฌ: ๋จธํ„ฐ๋ฆฌ์–ผ์˜ ์ „๋ฐ˜์ ์ธ ์ƒ‰์ƒ์ด๋‹ค.
  • ์ŠคํŽ˜ํ˜๋Ÿฌ: ๋น„๊ธˆ์† ํ‘œ๋ฉด์˜ ํ˜„์žฌ ์ŠคํŽ˜ํ˜๋Ÿฌ ๊ฐ’์œผ๋กœ ํ•˜์ด๋ผ์ดํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  • ๋…ธ๋ฉ€: ํ‘œ๋ฉด์— ๋ฌผ๋ฆฌ์  ๋””ํ…Œ์ผ์„ ๋”ํ•˜๋Š” ๊ฐ’์ด๋‹ค.
  • ์•ฐ๋น„์–ธํŠธ ์˜คํด๋ฃจ์ „

 

์ด์ œ ์ €์žฅํ•˜๋ฉด ๋จธํ„ฐ๋ฆฌ์–ผ์ด ์ž˜ ์ ์šฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋จธํ„ฐ๋ฆฌ์–ผ ์ ์šฉ

 

4. ์ž…๋ ฅ

์ž…๋ ฅ์€ ํ–ฅ์ƒ๋œ ์ž…๋ ฅ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค. ์ด ์‹œ์Šคํ…œ์€ ๋ณต์žกํ•œ ์ž…๋ ฅ ์ฒ˜๋ฆฌ์™€ ์‹ค์‹œ๊ฐ„ ์ž…๋ ฅ ๋ฆฌ๋งคํ•‘์„ ์ง€์›ํ•œ๋‹ค. ์ž์„ธํ•œ ์„ค์ •์€ ์ด ๊ธ€์„ ์ฐธ๊ณ ํ•˜๋ฉด ๋œ๋‹ค. ํ•ด๋‹น ๊ธ€์€ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ๋ฅผ ํ™œ์šฉํ•˜์˜€์ง€๋งŒ, ์—ฌ๊ธฐ์„  C++๋กœ ๊ตฌํ˜„ํ•ด ๋ณผ ๊ฒƒ์ด๋‹ค.

 

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
UInputMappingContext* DefaultMappingContext;

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
UInputAction* LookAction;

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
UInputAction* WalkAction;
// ์ž…๋ ฅ ๋งคํ•‘ ์ปจํ…์ŠคํŠธ๋ฅผ ๋กœ์ปฌ ํ”Œ๋ ˆ์ด์–ด์˜ ํ–ฅ์ƒ๋œ ์ž…๋ ฅ ๋กœ์ปฌ ํ”Œ๋ ˆ์ด์–ด ์„œ๋ธŒ์‹œ์Šคํ…œ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.
void ASurvivorCharacter::BeginPlay()
{
	Super::BeginPlay();

	if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
	{
		if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
		{
			Subsystem->AddMappingContext(DefaultMappingContext, 0);
		}
	}
}

// ๊ฐ ์ž…๋ ฅ ์•ก์…˜์€ ํ•ด๋‹นํ•˜๋Š” ์• ์…‹ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.
void ASurvivorCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	// Set up action bindings
	if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent)) {

		EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &ASurvivorCharacter::Look);
		EnhancedInputComponent->BindAction(WalkAction, ETriggerEvent::Triggered, this, &ASurvivorCharacter::Walk);
	}
	else
	{
		UE_LOG(LogTemplateCharacter, Error, TEXT("'%s' Failed to find an Enhanced Input component! This template is built to use the Enhanced Input system. If you intend to use the legacy system, then you will need to update this C++ file."), *GetNameSafe(this));
	}
}

void ASurvivorCharacter::Look(const FInputActionValue& Value)
{
	FVector2D LookAxisVector = Value.Get<FVector2D>();

	if (Controller != nullptr)
	{
		AddControllerYawInput(LookAxisVector.X);
		AddControllerPitchInput(LookAxisVector.Y);
	}
}

void ASurvivorCharacter::Walk(const FInputActionValue& Value)
{
	FVector2D MovementVector = Value.Get<FVector2D>();

	if (Controller != nullptr)
	{
		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);
	}
}

 

5. ์• ๋‹ˆ๋ฉ”์ด์…˜

1) FSM(Finite State Machine)

์–ธ๋ฆฌ์–ผ์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € FSM์„ ์•Œ์•„์•ผ ํ•œ๋‹ค. ์œ ํ•œ ์ƒํƒœ ๊ธฐ๊ณ„๋ผ๊ณ ๋„ ๋ถ€๋ฅด๋Š” FSM์€ ์ƒํƒœ(state)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•œ ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค. ์–ธ๋ฆฌ์–ผ์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ์ด FSM์„ ๋”ฐ๋ฅด๊ณ  ์žˆ๋‹ค.

 

๋งŒ์•ฝ ์ ํ”„, ์ด๋‹จ ์ ํ”„, ์—Ž๋“œ๋ฆฌ๊ธฐ ๋“ฑ ์—ฌ๋Ÿฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ด€๋ฆฌํ•ด์•ผ ํ•  ๋•Œ, ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•œ๋‹ค๋ฉด ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ๊ณ„์†ํ•ด์„œ if ๋ฌธ์ด ๋Š˜์–ด๋‚  ๊ฒƒ์ด๋‹ค.

 

if (input == PRESS_B)
{
    if (!bIsJumping)
    {
        bIsJumping = true;
        Jump();
    }
}
else if (input == PRESS_DOWN)
{
    if (!isJumping_)
    {
        Duck();
    }
}
else if (input == RELEASE_DOWN)
{
    Stand();
}

 

FSM์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ ํ”„์™€ ๊ฐ™์€ ํ•˜๋‚˜์˜ ๋™์ž‘์„ ์Šคํ…Œ์ดํŠธ๋กœ ์ •ํ•˜๊ณ  ์ด ์Šคํ…Œ์ดํŠธ๋“ค ์ค‘ ์กฐ๊ฑด์— ๋งž๋Š” ํ•˜๋‚˜๋งŒ ๋™์ž‘ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์‹คํ–‰ํ•  ์Šคํ…Œ์ดํŠธ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ์กฐ๊ฑด์„ ํŠธ๋žœ์ง€์…˜์ด๋ผ ๋ถ€๋ฅธ๋‹ค.

 

FSM

 

2) AnimInstance ํด๋ž˜์Šค

์บ๋ฆญํ„ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์œ„ํ•œ AnimInstance ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” C++ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. AnimInstance ํด๋ž˜์Šค๋Š” ์Šค์ผˆ๋ ˆํƒˆ ๋ฉ”์‹œ๋ฅผ ์†Œ์œ ํ•˜๋Š” ํฐ์˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„ ์• ๋‹˜ ๊ทธ๋ž˜ํ”„๊ฐ€ ์ฐธ์กฐํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

AnimInstance ํด๋ž˜์Šค

 

์ƒ์„ฑํ•œ AnimInstance ํด๋ž˜์Šค์—์„œ ์บ๋ฆญํ„ฐ Movement์˜ ๊ฐ’์— ๋”ฐ๋ผ LandState๊ฐ€ ๋ณ€๊ฒฝ๋˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค. 1์ผ ๋•Œ ์ด๋™ ์ƒํƒœ์ด๋‹ค.

 

UPROPERTY(BlueprintReadWrite)
ASurvivorCharacter* Character;

UPROPERTY(BlueprintReadWrite)
int LandState;
void USurvivorCharacterAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
	Super::NativeUpdateAnimation(DeltaSeconds);

	if (IsValid(Character) == false)
	{
		auto Pawn = TryGetPawnOwner();
		Character = Cast<ASurvivorCharacter>(Pawn);
	}

	if (IsValid(Character))
	{
		LandState = 0;
		if (Character->IsWalking())
		{
			LandState = 1;
		}
	}
}
bool ASurvivorCharacter::IsWalking() const
{
	return GetCharacterMovement()->Velocity.Length() > 0;
}

 

์ด์ œ ์ƒ์„ฑํ•œ AnimInstance ํด๋ž˜์Šค๋ฅผ ๋ฒ ์ด์Šค๋กœ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ด๋•Œ ์บ๋ฆญํ„ฐ์— ๋งž๋Š” ์Šค์ผˆ๋ ˆํ†ค์„ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.

 

AnimInstance ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค

 

์ด์ œ ์• ๋‹˜ ๊ทธ๋ž˜ํ”„์—์„œ LandState์— ๋งž๊ฒŒ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋™์ž‘๋˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค. ์• ๋‹˜ ๊ทธ๋ž˜ํ”„(Anim Graph)๋Š” ์• ๋‹˜ ์ธ์Šคํ„ด์Šค์˜ ๋ณ€์ˆ˜์— ๋”ฐ๋ผ ๋ณ€ํ™”ํ•˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์Šคํ…œ์„ ์„ค๊ณ„ํ•˜๋Š” ๊ณต๊ฐ„์ด๋‹ค. ์• ๋‹˜ ๊ทธ๋ž˜ํ”„์—์„œ ์Šคํ…Œ์ดํŠธ ๋จธ์‹ ์„ ์ถ”๊ฐ€ํ•œ ํ›„ Final Animation Pose ๋…ธ๋“œ์˜ Result ์ž…๋ ฅ ์‹คํ–‰ ํ•€์— ์—ฐ๊ฒฐํ•œ๋‹ค.

 

์Šคํ…Œ์ดํŠธ ๋จธ์‹ 

 

์ƒ์„ฑํ•œ ์Šคํ…Œ์ดํŠธ ๋จธ์‹ ์„ ๋”๋ธ”ํด๋ฆญํ•˜์—ฌ ์—ฐ ํ›„ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์Šคํ…Œ์ดํŠธ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ๊ฐ๊ฐ์˜ ์Šคํ…Œ์ดํŠธ๋Š” Idle, Walk ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์‹คํ–‰๋˜๋„๋ก ์—ฐ๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

 

์Šคํ…Œ์ดํŠธ

 

๋ชจ๋“  ์Šคํ…Œ์ดํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค๋ฉด ์Šคํ…Œ์ดํŠธ ์‚ฌ์ด์˜ ํŠธ๋žœ์ง€์…˜๋„ ์ถ”๊ฐ€ํ•˜์—ฌ LandState๋ฅผ ํ†ตํ•ด ๋ฐ”๋€Œ๋„๋ก ์—ฐ๊ฒฐํ–ˆ๋‹ค.

 

ํŠธ๋žœ์ง€์…˜

 

์„ค์ •์ด ๋‹ค ์™„๋ฃŒ๋˜์—ˆ์œผ๋‹ˆ ์บ๋ฆญํ„ฐ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค์— AnimInstance ๋ธ”๋ฃจํ”„๋ฆฐํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉ

 

์ฐธ๊ณ 

https://wergia.tistory.com/127#footnote_127_2

 

[UE4] ์ œ๋Œ€๋กœ ๋”ฐ๋ผ๊ฐ€๊ธฐ (2) C++ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŠœํ† ๋ฆฌ์–ผ :: ํ”Œ๋ ˆ์ด์–ด ์ž…๋ ฅ ๋ฐ ํฐ

์ œ๋Œ€๋กœ ๋”ฐ๋ผ๊ฐ€๊ธฐ (2) C++ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŠœํ† ๋ฆฌ์–ผ :: ํ”Œ๋ ˆ์ด์–ด ์ž…๋ ฅ ๋ฐ ํฐ ์ž‘์„ฑ๋ฒ„์ „ :: 4.20.3 ์–ธ๋ฆฌ์–ผ ์—”์ง„ ํŠœํ† ๋ฆฌ์–ผ์ธ ํ”Œ๋ ˆ์ด์–ด ์ž…๋ ฅ ๋ฐ ํฐ ๋ฌธ์„œ์—์„œ๋Š” ํฐ(Pawn)[๊ฐ์ฃผ:1] ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•ด์„œ ํ”Œ๋ ˆ์ด์–ด์˜ ์ž…

wergia.tistory.com

https://m.blog.naver.com/scycs6/221238180585

 

์–ธ๋ฆฌ์–ผ์—”์ง„ - FBX ์ž„ํฌํŠธ ์˜ต์…˜

Mesh ํƒญ์˜ Auto Generate Collision์€ ์ถฉ๋Œ๊ฐ’์„ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ฒ ๋‹ค๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ๋งˆ์•ผ์—์„œ ๊ฐ–๊ณ ์˜จ ...

blog.naver.com

https://velog.io/@gb_leem/FSM

 

FSM

Finite State Machine

velog.io

์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)
'๐Ÿ“ Game/โœ Unreal' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Unreal][C++] AI ์บ๋ฆญํ„ฐ
  • [Unreal][C++] ์•„์ดํ…œ ํš๋“, ์ฐฉ์šฉ
  • [Unreal][C++] 1์ธ์นญ ์ŠˆํŒ… ํŠœํ† ๋ฆฌ์–ผ
  • [Unreal][Lyra] ํ–ฅ์ƒ๋œ ์ž…๋ ฅ
Blxxming
Blxxming
CS ์ง€์‹๊ณผ ๊ณต๋ถ€ํ•˜๋‹ค ๋ฐฐ์šด ๊ฒƒ, ๊ฒฝํ—˜ํ•œ ๊ฒƒ ๋“ฑ์„ ๊ธฐ๋กํ•˜๋Š” ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.
  • Blxxming
    ๐Ÿ’ก๋ฒˆ๋œฉ๐Ÿ’ก
    Blxxming
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
  • ๊ณต์ง€์‚ฌํ•ญ

    • Tech Interview
    • ๐Ÿ“š Tech (246)
      • ๐Ÿ“ Computer Science (96)
        • โœ OS (12)
        • โœ Network & Web (10)
        • โœ Database (11)
        • โœ Data Structure (6)
        • โœ Algorithm (40)
        • โœ Design Pattern (9)
        • โœ Cloud Computing (3)
        • โœ (5)
      • ๐Ÿ“ Language (73)
        • โœ Language (6)
        • โœ C & C++ (11)
        • โœ C# (19)
        • โœ JAVA (37)
      • ๐Ÿ“ Game (43)
        • โœ Computer Graphics (2)
        • โœ Unity (14)
        • โœ Unreal (26)
        • โœ (1)
      • ๐Ÿ“ Book (34)
        • โœ Effective (3)
        • โœ Game Server (16)
        • โœ Clean Code (14)
        • โœ (1)
  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.0
Blxxming
[Unreal][C++] ํ”Œ๋ ˆ์ด์–ด ์บ๋ฆญํ„ฐ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”