웨어 이즈 마이 UCharacterMovementComponent??
항상 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() 함수
- 템플릿 함수
- 사용자가 원하는 타입(T)으로 캐스팅 가능.
- CastChecked<T>()는 강제 캐스팅을 수행하며, 실패하면 오류 발생 가능.
- ECastCheckedType::NullAllowed → CharacterMovement가 nullptr이면 nullptr 반환.
- template <class T> FORCEINLINE_DEBUGGABLE T* GetCharacterMovement() const { return CastChecked<T>(CharacterMovement, ECastCheckedType::NullAllowed); }
- 기본 UCharacterMovementComponent* 반환 함수
- 일반적인 UCharacterMovementComponent*를 반환.
- 블루프린트에서는 이 함수가 사용됨.
- 이 함수가 AdvMovementComponent를 인식하지 못하는 이유이기도 함! 🚨
- 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로 변경하면 바로 호출 가능😊