Unreal Engine

웨어 이즈 마이 UCharacterMovementComponent??

geminanolja 2025. 3. 4. 14:54

 

항상 CharacterMovementComponent랑 씨름하는 경우들이 많았는데... 

왜 내가 새로 생성한 CharacterMovementComponent가 그리고 그안에 있는 함수들이라 변수가 바로 찾아지지 않는걸까?

 

이부분의 수수께끼가 풀렸다

BP에서 항상 끌어오던 

이녀석이~~

	/** Movement component used for movement logic in various movement modes (walking, falling, etc), containing relevant settings and functions to control movement. */
	UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
	TObjectPtr<UCharacterMovementComponent> CharacterMovement;

 

요로케 선언되어있는 것이었다..~~~

그냥 UCharacterMovementComponent만 불러오는 것인거지`~

 


🔍 CharacterMovementComponent 코드 분석

/** Movement component used for movement logic in various movement modes (walking, falling, etc), 
    containing relevant settings and functions to control movement. */
UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
TObjectPtr<UCharacterMovementComponent> CharacterMovement;

✅ 1️⃣ 이 코드가 의미하는 것

키워드 설명

UPROPERTY(...) 언리얼 엔진에서 블루프린트 및 C++에서 접근 가능하도록 설정
Category=Character 블루프린트에서 "Character" 카테고리로 표시
VisibleAnywhere 언리얼 에디터에서 볼 수 있지만 수정은 불가능
BlueprintReadOnly 블루프린트에서 읽을 수 있지만, 변경은 불가능
meta=(AllowPrivateAccess = "true") C++에서 private 변수처럼 관리하지만 블루프린트에서 읽을 수 있음
TObjectPtr<UCharacterMovementComponent> UCharacterMovementComponent 스마트 포인터*
CharacterMovement 이동 관련 기능을 담당하는 변수

✅  CharacterMovement를 기본적으로 어떤 클래스가 사용하나?

CharacterMovement는 **UCharacterMovementComponent**를 기본으로 사용합니다.
즉, **ACharacter 클래스의 기본 이동 컴포넌트는 UCharacterMovementComponent**입니다.

📌 기본적으로 CharacterMovement는 UCharacterMovementComponent를 가리킴

UCharacterMovementComponent* ACharacter::GetCharacterMovement() const
{
    return CharacterMovement;
}

 

 

✅  GetCharacterMovement() 코드 분석

/** Returns CharacterMovement subobject **/
template <class T>
FORCEINLINE_DEBUGGABLE T* GetCharacterMovement() const
{
    return CastChecked<T>(CharacterMovement, ECastCheckedType::NullAllowed);
}

FORCEINLINE UCharacterMovementComponent* GetCharacterMovement() const 
{ 
    return CharacterMovement; 
}

📌 분석: 두 개의 GetCharacterMovement() 함수

  1. 템플릿 함수
    • 사용자가 원하는 타입(T)으로 캐스팅 가능.
    • CastChecked<T>()는 강제 캐스팅을 수행하며, 실패하면 오류 발생 가능.
    • ECastCheckedType::NullAllowed → CharacterMovement가 nullptr이면 nullptr 반환.
  2. template <class T> FORCEINLINE_DEBUGGABLE T* GetCharacterMovement() const { return CastChecked<T>(CharacterMovement, ECastCheckedType::NullAllowed); }
  3. 기본 UCharacterMovementComponent* 반환 함수
    • 일반적인 UCharacterMovementComponent*를 반환.
    • 블루프린트에서는 이 함수가 사용됨.
    • 이 함수가 AdvMovementComponent를 인식하지 못하는 이유이기도 함! 🚨
  4. FORCEINLINE UCharacterMovementComponent* GetCharacterMovement() const { return CharacterMovement; }

✅  GetCharacterMovement()를 사용하여 AdvMovementComponent 반환하기

✅ 3️⃣ CharacterMovement를 AdvMovementComponent로 변경하는 방법

🚀 해결 방법 1: ACharacter에서 CharacterMovement를 직접 변경

기본적으로 CharacterMovement가 UCharacterMovementComponent*를 사용하므로,
C++ 코드에서 직접 AdvMovementComponent를 할당하면 캐스팅 없이 사용 가능!

📌 변경 코드 (ACharacter 생성자에서 AdvMovementComponent로 변경)

#include "AdvMovementComponent.h"

AMyCharacter::AMyCharacter()
{
    // 기존 CharacterMovement를 커스텀 이동 컴포넌트로 변경
    CharacterMovement = CreateDefaultSubobject<UAdvMovementComponent>(TEXT("AdvMovement"));
}

이제 CharacterMovement가 UAdvMovementComponent* 타입이므로 캐스팅 없이 바로 사용 가능!


🚀 해결 방법 2: GetCharacterMovement()를 오버라이딩하여 AdvMovementComponent* 반환

기본적으로 GetCharacterMovement()는 UCharacterMovementComponent*를 반환하므로,
이를 오버라이딩하여 자식 클래스(AdvMovementComponent*)를 반환하도록 변경할 수 있습니다.

📌 GetCharacterMovement()를 오버라이딩하여 AdvMovementComponent* 반환

UAdvMovementComponent* AMyCharacter::GetAdvCharacterMovement() const
{
    return Cast<UAdvMovementComponent>(CharacterMovement);
}

 

🚀 해결 방법 3: GetAdvCharacterMovement() 함수 추가 (C++ & 블루프린트)

📌 새로운 GetAdvCharacterMovement() 함수를 만들어 캐스팅 없이 사용 가능하게 변경

UFUNCTION(BlueprintCallable, Category = "Movement")
UAdvMovementComponent* GetAdvCharacterMovement() const
{
    return Cast<UAdvMovementComponent>(CharacterMovement);
}

 이제 블루프린트에서 GetAdvCharacterMovement()를 사용하면 FindWall()이 자동으로 보임!


✅ 4️⃣ 결론

CharacterMovement는 기본적으로 어떤 클래스를 사용하나? UCharacterMovementComponent*를 기본으로 사용
왜 FindWall()이 바로 안 보이고 캐스팅이 필요할까? CharacterMovement가 AdvMovementComponent*가 아니라 UCharacterMovementComponent*로 선언되어 있기 때문
캐스팅 없이 FindWall()을 사용하려면? ① CharacterMovement를 AdvMovementComponent*로 변경 ② GetCharacterMovement()를 오버라이딩하여 올바른 타입 반환

🚀 이제 CharacterMovement가 기본적으로 UCharacterMovementComponent를 가리킨다는 걸 알았고,
이를 AdvMovementComponent로 변경하면 바로 호출 가능
😊