Changing Properties Of C++ Based Blueprint on Simulation not working

hi. first of all sorry if my English is not good. :frowning:
i have created a simple c++ actor that find a UStaticMeshComponent on ‘BeginPlay’ and rotate it in tick function.
i put it to world and add a simple box mesh and press simalate . in simulation i change its RotationSpeed and other properties like location, scale. it works well. no problem.
but when i create a new bluprint based on this class and change the properties in simulation it don’t rotate,
it seems “RotationMesh->AddRelativeRotation(…)” Don’t work.
what is the problem? is it a bug or …?

#pragma once

#include "GameFramework/Actor.h"
#include "BaseDefenseItem.generated.h"

UCLASS()
class BATTERYCOLLECTOR_API ABaseDefenseItem : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ABaseDefenseItem();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	UPROPERTY(EditAnywhere)
	float RotateSpeed;
	
	UPROPERTY(Transient)
	UStaticMeshComponent* RotationMesh;
};

//////////////////////////////////////////////////////////////////.CPP
#include "BatteryCollector.h"
#include "BaseDefenseItem.h"


// Sets default values
ABaseDefenseItem::ABaseDefenseItem()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	RotateSpeed = 4;
}

// Called when the game starts or when spawned
void ABaseDefenseItem::BeginPlay()
{
	Super::BeginPlay();

	RotationMesh = (UStaticMeshComponent*)GetComponentByClass(UStaticMeshComponent::StaticClass());
	check(RotationMesh);
}

// Called every frame
void ABaseDefenseItem::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	RotationMesh->AddRelativeRotation(FRotator(0, 0, RotateSpeed));
}

Hey DaneshBAria-

I don’t see where you’re actually adding the static mesh component to the class. Typically this is done using RotationMesh = CreateDefaultSubobject(TEXT("[Text]")); inside of the constructor. Then, in the editor, this component can be set to any static mesh available in the project.

Using the code above, I actually have a crash when I attempt to simulate in the editor. This is likely due to RotationMesh being null when I put an instance of the class in the level. Additionally, you probably don’t want the static mesh component to be marked as Transient. This setting means that the specified component should not be saved which could cause it to unexpectedly be null.

Using EditAnywhere, BlueprintReadWrite, and giving it a category instead (as well as adding the CreateDefaultSubobject line) allowed the code to compile as well as allow me to set a static mesh for the class instance. I found that a blueprint based on the class also spawned/rotated/edited as expected during Simulation with these settings.

Cheers

i don’t want to create component by code. it is added by Add Component in blueprint editor; i just find it in BeginPlay.

I was able to reproduce what you were seeing with the component added to the blueprint and have entered a report (UE-25594) for investigation. If it helps I found that moving the cast to UStatiMeshComponent as well as the following check() (lines 47 and 48 above) to the Tick function just before the call to AddRelativeRotation allows the blueprint version to function exactly the same as the class instance version.

Cheers

I don’t believe this is a bug as such. Components added to blueprints get recreated by the construction script anytime a property on the actor is modified. What’s happening here is that changing a property results in a new version of the mesh component being created during Simulate. However, the cached pointer is still pointing at the old component, so altering the transform has no visible effect. In fact, if this is left to run, the code will crash when the garbage collector deletes the old component and the tick function attempts to access the resulting null property.

It’s possible that the engine code could be modified to replace all property references with the new component after reconstruction, but since this process only occurs in editor and cannot happen in a packaged game, I wouldn’t really say the current behaviour is a bug. In this case, you could just reassign the component reference in an OnConstruction override.

I think though that Epic should consider disabling this component reconstruction behaviour during PIE/Simulate, and have it happen only at design time. To me it doesn’t really make sense to do it in a running world, and it limits the extent to which Simulate mode can be used as a debugging and testing tool.