PostEditChangeProperty 함수와 PostEditChangeChainProperty 함수는 Unreal Engine의 에디터에서만 실행되는 함수입니다. 이 함수들은 에디터에서 변수 값이 변경될 때 추가적인 처리를 할 수 있게 해줍니다. 이러한 변경 사항은 주로 디테일 패널에서 속성을 수정할 때 발생합니다. 에디터에서만 실행되는 함수 이므로 WITH_EDITOR 매크로를 사용했습니다.
// .h
#if WITH_EDITOR
protected:
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
virtual void PostEditChangeChainProperty(struct FPropertyChangedChainEvent& PropertyChangedEvent) override;
#endif
// .cpp
#if WITH_EDITOR
void UPRAISpawnArea::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
}
void UPRAISpawnArea::PostEditChangeChainProperty(struct FPropertyChangedChainEvent& PropertyChangedEvent)
{
}
#endif
PostEditChangeProperty
PostEditChangeProperty 함수는 디테일 패널에서 단일 속성의 값이 변경될 때 호출되며 변경된 속성에 대해 단일 속성 변경 이벤트를 처리합니다. 함수에 주어진 FPRopertyChangedEvent 구조체의 Property의 Name을 GET_MEMBER_NAME_CHECKED 매크로로 해당 클래스의 변경된 변수의 이름을 비교하여 일치할 경우 구현한 동작을 실행하는 방식입니다. 사용하는 방법은 다음과 같습니다.
// .h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/SceneComponent.h"
#include "PRAISpawnArea.generated.h"
/**
* 범위내에 존재하는 AISpawnPoint를 탐색하는 SceneComponent 클래스입니다.
*/
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class PROJECTREPLICA_API UPRAISpawnArea : public USceneComponent
{
GENERATED_BODY()
public:
UPRAISpawnArea();
#if WITH_EDITOR
protected:
/** 디테일 패널에서 단일 속성의 값이 변경될 때 변경된 속성에 대해 단일 속성 변경 이벤트를 처리합니다. */
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
private:
/** SpawnArea의 Index입니다. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "PRAISpawnArea", meta = (AllowPrivateAccess = "true"))
int32 SpawnAreaIndex;
/** SpawnAreaBox의 범위입니다. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "PRAISpawnArea", meta = (AllowPrivateAccess = "true", DisplayPriority = 0))
FVector SpawnAreaBoxExtent;
};
// .cpp
UPRAISpawnArea::UPRAISpawnArea()
{
SpawnAreaIndex = INDEX_NONE;
SpawnAreaBoxExtent = FVector(100.0f, 100.0f, 100.0f);
}
#if WITH_EDITOR
void UPRAISpawnArea::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
if(PropertyChangedEvent.Property)
{
FName PropertyName = PropertyChangedEvent.GetPropertyName();
PR_LOG_WARNING("PostEditChangeProperty PropertyName: %s", *PropertyName.ToString());
if(PropertyName == GET_MEMBER_NAME_CHECKED(UPRAISpawnArea, SpawnAreaBoxExtent))
{
PR_LOG_WARNING("Find PostEditChangeProperty PropertyName: %s", *PropertyName.ToString());
}
else if(PropertyName == GET_MEMBER_NAME_CHECKED(UPRAISpawnArea, SpawnAreaIndex))
{
PR_LOG_WARNING("Find PostEditChangeProperty PropertyName: %s", *PropertyName.ToString());
}
else
{
PR_LOG_WARNING("PostEditChangeProperty Property False");
}
}
}
#endif
해당 클래스를 월드에 배치하고 디테일 패널에서 기본 값이 FVector(100.0f, 100.0f, 100.0f)인 SpawnAreaBoxExtent와 -1인 SpawnAreaIndex의 값을 변경한 결과는 다음과 같습니다.
PostEditChangeChainProperty
PostEditChangeChainProperty 함수는 디테일 패널에서 구조체의 값이 변경되거나, 여러 속성이 연쇄적으로 변경될 때 호출되며, 여러 속성의 연쇄적 변경을 한 번에 처리할 수 있습니다.
PostEditChangeProperty와 마찬가지로 함수에 주어진 FPropertyChangedChainEvent 구조체를 사용하지만, PostEditChangeChainProperty는 Property가 아닌 PropertyChain 구조체를 사용하였습니다. 해당 구조체를 사용하여 GET_MEMBER_NAME_CHECKED 매크로로 변수의 이름을 비교하여 구현하면 됩니다. 이번에는 PostEditChangeChainProperty를 사용하여 각 함수 값에 출력되는 Name을 출력하기만 했습니다.
// .h
#if WITH_EDITOR
protected:
/** 디테일 패널에서 구조체의 값이 변경되거나, 여러 속성이 연쇄적으로 변경될 때 여러 속성의 연쇄적 변경을 한 번에 처리합니다. */
virtual void PostEditChangeChainProperty(struct FPropertyChangedChainEvent& PropertyChangedEvent) override;
#endif
// .cpp
#if WITH_EDITOR
void UPRAISpawnArea::PostEditChangeChainProperty(struct FPropertyChangedChainEvent& PropertyChangedEvent)
{
Super::PostEditChangeChainProperty(PropertyChangedEvent);
const FName PropertyStrName = PropertyChangedEvent.GetPropertyName();
const FName MemberPropertyName = PropertyChangedEvent.GetMemberPropertyName();
PR_LOG_ERROR("PostEditChangeChainProperty PropertyName: %s", *PropertyStrName.ToString());
PR_LOG_ERROR("PostEditChangeChainProperty MemberPropertyName: %s", *MemberPropertyName.ToString());
const FName HeadName = PropertyChangedEvent.PropertyChain.GetHead()->GetValue()->GetFName();
const FName TailName = PropertyChangedEvent.PropertyChain.GetTail()->GetValue()->GetFName();
PR_LOG_ERROR("PostEditChangeChainProperty Head: %s", *HeadName.ToString());
PR_LOG_ERROR("PostEditChangeChainProperty Tail: %s", *TailName.ToString());
const FName ActivateNodeName = PropertyChangedEvent.PropertyChain.GetActiveNode()->GetValue()->GetFName();
const FName ActivateMemberNodeName = PropertyChangedEvent.PropertyChain.GetActiveMemberNode()->GetValue()->GetFName();
PR_LOG_ERROR("PostEditChangeChainProperty MemberNodeName: %s", *ActivateNodeName.ToString());
PR_LOG_ERROR("PostEditChangeChainProperty MemberNodeName: %s", *ActivateMemberNodeName.ToString());
}
#endif
'Unreal Engine > C++' 카테고리의 다른 글
[Unreal Engine C++] EnhancedInput System으로 게임패드와 키보드 입력 장치 구분하기 (0) | 2024.04.09 |
---|---|
[Unreal Engine C++] EnhancedInputSystem의 입력 값 구하기 (1) | 2024.03.15 |
[Unreal Engine C++] C++에서 인터페이스 변수 사용하기 (0) | 2024.01.12 |
[Unreal Engine C++] Widget Animation Delegate (1) | 2024.01.09 |
[Unreal Engine 4 C++] TimeStop (시공단열/초산 회피) (0) | 2023.08.02 |