Download

Losing values with itinerancy components

I wrote a custom SceneComponent with one camera and one staticmeshcomponent inside.
Through PostEditChangeProperty function I initialize theirs values, like his position or his staticmesh.

This custom SceneComponent (called InmCameraComponent) it’s used by a custom character attached to his mesh.

When editing values in the BlueprintEditor, works fine and set values correctly, but when compile the blueprint, the values remains in detail panel, but lose in the InmCameraComponent like if restars the component with default values (in other words: no values)

I tried to initialize values from InmCamera and Character. And the only solution I found it’s to load values from code directly (with ConstructorHelpers) but I want the design team can change values without need modify the code. I don’t know if this is a unreal bug or if I do something wrong.

I post the code and screenshots to clarify the problem:



InmCharacter.hpp



UCLASS()
class AInmCharacter : public ACharacter
{
GENERATED_BODY()

//...

private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Inmersive Character", meta=(AllowPrivateAccess = "true"))
class UInmCameraComponent* InmCamera;
//...

};

InmCameraComponent.hpp


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

private:
    UPROPERTY(EditAnywhere, Category = "InmCameraComponent")
    class UStaticMesh* HeadMesh;

    UPROPERTY(EditAnywhere, Category = "InmCameraComponent")
    FName HeadMeshSockeName;

    UPROPERTY(EditAnywhere, Category = "InmCameraComponent")
    FName CameraSockeName;

    UPROPERTY(EditAnywhere, Category = "InmCameraComponent")
    FVector NeckOffset;

    UPROPERTY(EditAnywhere, Category = "InmCameraComponent")
    uint8 bHeadMeshVisibleInEditor : 1;

    UPROPERTY(EditAnywhere, Category = "InmCameraComponent")
    float FieldOfView;


private:
    UPROPERTY(meta = (AllowPrivateAccess = "true"))
    class UCameraComponent* Camera;

    UPROPERTY(meta = (AllowPrivateAccess = "true"))
    class UStaticMeshComponent* HeadMeshComponent;

//...

protected:
#if WITH_EDITOR
    virtual void PostEditChangeProperty(struct FPropertyChangedEvent& e) override;
#endif

//..
};


InmCameraComponent.cpp


UInmCameraComponent::UInmCameraComponent(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
    PrimaryComponentTick.bCanEverTick = true;

    FieldOfView = 90.0f;
    bHeadMeshVisibleInEditor = false;

    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    HeadMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("HeadMesh"));

    HeadMeshComponent->SetupAttachment(this);
    HeadMeshComponent->SetHiddenInGame(false);
    HeadMeshComponent->CastShadow = true;
    HeadMeshComponent->bVisibleInReflectionCaptures = true;
    Camera->SetupAttachment(this);
}

#if WITH_EDITOR
void UInmCameraComponent::PostEditChangeProperty(struct FPropertyChangedEvent& e)
{
    FName PropertyName = (e.MemberProperty != NULL) ? e.MemberProperty->GetFName() : NAME_None;

    if (PropertyName == FName("FieldOfView"))
    {
        Camera->SetFieldOfView(FieldOfView);
    }
    else if (PropertyName == FName("HeadMesh"))
    {
        HeadMeshComponent->SetStaticMesh(HeadMesh);
    }
    else if (PropertyName == FName("HeadMeshSockeName"))
    {
        if (ACharacter* OwnCharacter = Cast<ACharacter>(GetOwner()))
        {
            if (USkeletalMeshComponent* Skel = OwnCharacter->GetMesh())
            {
                FAttachmentTransformRules Rules(EAttachmentRule::SnapToTarget, false);
                HeadMeshComponent->AttachToComponent(Skel, Rules, HeadMeshSockeName);
            }
        }
    }
    else if (PropertyName == FName("CameraSockeName"))
    {
        if (ACharacter* OwnCharacter = Cast<ACharacter>(GetOwner()))
        {
            if (USkeletalMeshComponent* Skel = OwnCharacter->GetMesh())
            {
                FAttachmentTransformRules Rules(EAttachmentRule::SnapToTarget, false);
                AttachToComponent(Skel, Rules, CameraSockeName);
            }
        }
    }
    else if (PropertyName == FName("bHeadMeshVisibleInEditor"))
    {
        HeadMeshComponent->SetVisibility(bHeadMeshVisibleInEditor);
        Camera->SetRelativeScale3D
        (
            !bHeadMeshVisibleInEditor
            ? FVector(1, 1, 1)
            : FVector(0.01f, 0.01f, 0.01f)
        );
    }
    else if (PropertyName == FName("NeckOffset"))
    {
        SetRelativeLocation(NeckOffset);
        Camera->SetRelativeLocation(-NeckOffset);
    }

    Super::PostEditChangeProperty(e);
}
#endif


Thanks!