Can't override PostEditChangeProperty in subclass of USceneComponent

As far as I can tell I’m doing this correctly…

LINE IN QUESTION:


virtual void PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent) override;

ERROR:

USceneComponent does indeed have an overridable PostEditChangeProperty.


#pragma once

#include "Components/SceneComponent.h"
#include "VehicalSocketComponent.generated.h"

UENUM(BlueprintType)
namespace EVehicalSocketType
{
	enum Type
	{
		SQUARE		UMETA(DisplayName = "Square"),
		END			UMETA(DisplayName = "Rounded End Cap"),
		CORNER		UMETA(DisplayName = "Rounded Corner")
	};
}

UENUM(BlueprintType)
namespace EVehicalSocketSize
{
	enum Type
	{
		A_TYPE		UMETA(DisplayName = "A Type (small)"),
		B_TYPE		UMETA(DisplayName = "B Type (large)")
	};
}

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class EDITOR2_API UVehicalSocketComponent : public USceneComponent
{
	GENERATED_BODY()

public:	

	UVehicalSocketComponent();

	// Called when the game starts
	virtual void BeginPlay() override;

	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

	virtual void PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent) override;

	UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Socket Properties")
		TEnumAsByte<EVehicalSocketType::Type> SocketType = EVehicalSocketType::SQUARE;

	UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Socket Properties")
		TEnumAsByte<EVehicalSocketSize::Type> SocketSize = EVehicalSocketSize::A_TYPE;

protected:

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Mesh")
	UStaticMeshComponent * StaticMeshComponent;

};


#include "Editor2.h"
#include "VehicalSocketComponent.h"

// Sets default values for this component's properties
UVehicalSocketComponent::UVehicalSocketComponent()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	bWantsBeginPlay = true;
	PrimaryComponentTick.bCanEverTick = true;

	// Create and attach the static mesh component to our scene component
	StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Static Mesh Component"));
	StaticMeshComponent->AttachTo(this);
	StaticMeshComponent->SetVisibility(true);

}

// Called when the game starts
void UVehicalSocketComponent::BeginPlay()
{
	Super::BeginPlay();	
}

void UVehicalSocketComponent::PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

	static ConstructorHelpers::FObjectFinder<UStaticMesh> A_SquareStaticMeshAsset(TEXT("StaticMesh'/Game/Meshes/VSockets/VSocket_A_Square.VSocket_A_Square'"));
	static ConstructorHelpers::FObjectFinder<UStaticMesh> A_EndStaticMeshAsset(TEXT("StaticMesh'/Game/Meshes/VSockets/VSocket_A_End.VSocket_A_End'"));
	static ConstructorHelpers::FObjectFinder<UStaticMesh> A_CornerStaticMeshAsset(TEXT(""));

	/*switch (SocketType)
	{
	case EVehicalSocketType::CORNER:
		StaticMeshComponent->SetStaticMesh(A_CornerStaticMeshAsset.Object);
		break;
	case EVehicalSocketType::END:
		StaticMeshComponent->SetStaticMesh(A_EndStaticMeshAsset.Object);
		break;
	default:
		StaticMeshComponent->SetStaticMesh(A_SquareStaticMeshAsset.Object);
	}*/

}



// Called every frame
void UVehicalSocketComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}



[FONT=Courier New]PostEditChangeProperty is part of a set of functions that are only used by the editor and shouldn’t be compiled into a game. When it compiles a non-Editor version of your game, it finds your [FONT=Courier New]PostEditChangeProperty function and can’t find the same method in the superclass, because they don’
t exist.

Fix is to wrap both your declaration and implementation of [FONT=Courier New]PostEditChangeProperty in the [FONT=Courier New]WITH_EDITOR macro, like so:




#if WITH_EDITOR
	virtual void PreEditChange(UProperty* PropertyThatWillChange) override;
#endif




#if WITH_EDITOR
void UVehicalSocketComponent::PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

	static ConstructorHelpers::FObjectFinder<UStaticMesh> A_SquareStaticMeshAsset(TEXT("StaticMesh'/Game/Meshes/VSockets/VSocket_A_Square.VSocket_A_Square'"));
	static ConstructorHelpers::FObjectFinder<UStaticMesh> A_EndStaticMeshAsset(TEXT("StaticMesh'/Game/Meshes/VSockets/VSocket_A_End.VSocket_A_End'"));
	static ConstructorHelpers::FObjectFinder<UStaticMesh> A_CornerStaticMeshAsset(TEXT(""));

	/*switch (SocketType)
	{
	case EVehicalSocketType::CORNER:
		StaticMeshComponent->SetStaticMesh(A_CornerStaticMeshAsset.Object);
		break;
	case EVehicalSocketType::END:
		StaticMeshComponent->SetStaticMesh(A_EndStaticMeshAsset.Object);
		break;
	default:
		StaticMeshComponent->SetStaticMesh(A_SquareStaticMeshAsset.Object);
	}*/

}

#endif


4 Likes

Ahhh, that makes sense. Thanks for answering my relatively dumb question. :slight_smile:

Not a dumb question at all. Trips up almost everybody the first time they need to use one of those functions.