본문 바로가기
개발 로그/ProjectHive

강참조 중 경로(문자열)로 받아오는거 데이터 에셋으로 받아오게 만들기

by Fel.Forest 2025. 5. 15.

캐릭터 생성에 필요한 에셋을 불러오는 과정 중, 에셋의 경로를 문자열로 받아와서 로드하는 부분이 있는데 이 부분을 최대한 피하고 싶어서 만든 내용입니다.

 

 

PHPlayableCharacter :: PHPlayerableCharacter()
{
        ...
        static ConstructorHelpers::FObjectFinder<UInputMappingContext> InputMappingContextRef(TEXT("/Game/ProjectHive/Input/IMC_Player.IMC_Player"));
        if (InputMappingContextRef.Object != nullptr)
        {
            DefaultMappingContext = InputMappingContextRef.Object;
        }
}

현재는 에셋을 하드코딩된 문자열 경로로 로드하고 있습니다. 초기에는 문제가 없지만, 에셋 수가 많아질수록 경로 변경, 오탈자 등으로 인해 관리가 복잡해지고 휴먼 에러가 발생할 가능성도 커집니다. 이를 방지하기 위해, 경로 정보를 별도의 데이터 에셋으로 분리하고 에디터에서 설정할 수 있는 구조로 변경했습니다.

DataAsset 구조

UCLASS()
class PROJECTHIVE_API UPHCharacterInputActionData : public UPrimaryDataAsset
{
	GENERATED_BODY()

public:
	UPHCharacterInputActionData();

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = InputMapping)
	TObjectPtr <class UInputMappingContext> CharacterInputMapping;

	UPROPERTY(EditAnywhere, Category = ActionBinding)
	TMap<ECharacterActionType, FPHInputBinding> InputBindings;
};

PrimaryDataAsset을 상속받아 만들었으며, enum을 키로 사용합니다

UENUM()
enum class ECharacterActionType : uint8
{
	MoveAction = 1
};

 당장은 이동만 있지만 추후 추가할 예정입니다.

USTRUCT()
struct FPHInputBinding
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere)
	TObjectPtr<class UInputAction> InputAction;

	UPROPERTY(EditAnywhere)
	ETriggerEvent TriggerEvent;
};

InputAction이랑 TriggerEvent를 함께 저장해서 나중에 바인딩할 때 사용할 수 있도록 구성했습니다.

 

캐릭터 입력 바인딩 처리

Editor에서 DataAsset만들어서 설정한 것입니다.

에디터에서 만든 DataAsset을 캐릭터에 할당해 사용할 예정입니다.

class PROJECTHIVE_API APHPlayableCharacter : public APHPartsCharacter, public IPHAttackInterface
{
	// ...
	void BindInputAction(UEnhancedInputComponent* InEnhancedInputComponent);
	TMap<ECharacterActionType, void (APHPlayableCharacter::*)(const FInputActionValue&)> ActionMapping;
};

입력 바인딩을 별도 함수로 분리했습니다.

// Setting Action
ActionMapping.Add(ECharacterActionType::MoveAction, &APHPlayableCharacter::Move);

생성자에서 함수랑 InputAction타입(enum)으로 맞게 TMap에 추가합니다

void APHPlayableCharacter::BindInputAction(UEnhancedInputComponent* InEnhancedInputComponent)
{
	if (CharacterInputActionData == nullptr)
	{
		return;
	}

	for (const auto& pair : CharacterInputActionData->InputBindings)
	{
		auto ActionType = pair.Key;
		auto Action = pair.Value.InputAction;
		if (Action == nullptr)
		{
			continue;
		}
		auto TriggerEvent = pair.Value.TriggerEvent;

		if (const auto* MappingFunc = ActionMapping.Find(ActionType))
		{
			InEnhancedInputComponent->BindAction(Action, TriggerEvent, this, *MappingFunc);
		}
	}
}

이 함수는 SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) 내부에서 호출이 됩니다. PlayerController가 빙의 할때 마다 자동으로 호출해 주는 함수입니다.

 

이렇게 하면 코드에서는 enum 추가와 바인딩 시킬 함수만 만들어 놓으면 에디터에서 쉽게 수정할 수 있습니다.

작동을 잘 하는 것을 볼 수 있습니다.