Why is my C++ actor instances not updating in the level viewport after recompiling modified code?

Hi,

I am new to Unreal Engine and currently learning with version 4.27.2. I’m learning unreal c++. Since yesterday, I have been trying to solve an unexpected issue.

I created an Actor class and added two UStaticMeshComponent to it. I made one of the component the root and attached the second one as a child to the root.

I then assigned static meshes to each of the component. After that, I offset the transform (location and rotation) of the child component and then compiled the code. The compilation was successful and I placed instances of the C++ actor in the level viewport. After that, I modified the offset transform in the code and recompiled. After successful compilation, the actor class in the “content browser” showed that the transform of the child component has been updated. However, the instances I already placed in the viewport did not update. I had to use the “Replace selected actor with” option before I was able to update the instances.

When I exposed the C++ code to blueprint and then modified the offset of the child component in the blueprint editor, the blueprint instances I already placed in the level updated automatically. That was not the case with the C++ version.

Please, what am I doing wrong in C++ or does C++ Actor instances don’t update automatically when you modify and recompile the code?

Below is the code:
HEADER FILE
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include “CoreMinimal.h”
#include “GameFramework/Actor.h”
#include “MyActor.generated.h”

UCLASS()
class ROLLINGABALL_API AMyActor : public AActor
{
GENERATED_BODY()

public:
// Sets default values for this actor’s properties
AMyActor();

protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;

UPROPERTY(EditAnywhere, Category = "Components")
	UStaticMeshComponent* ConeStaticMeshComponent;

UPROPERTY(EditAnywhere, Category = "Components")
	UStaticMeshComponent* CubeStaticMeshComponent;

public:
// Called every frame
virtual void Tick(float DeltaTime) override;

};

CPP CODE
// Fill out your copyright notice in the Description page of Project Settings.

#include “MyActor.h”
#include “UObject/ConstructorHelpers.h”

// Sets default values
AMyActor::AMyActor()
{
// 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;

// Initialize ConeStaticMeshComponent and set it as the default root component
ConeStaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("RootStaticMeshComponent"));
SetRootComponent(ConeStaticMeshComponent);

// Initialize CubeStaticMeshComponent and then attach it to the root component set earlier
CubeStaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Child1StaticMeshComponent"));
CubeStaticMeshComponent->SetupAttachment(ConeStaticMeshComponent);

// Find a static mesh in the project folder and then assign it to ConeStaticMeshComponent
static ConstructorHelpers::FObjectFinder<UStaticMesh>MeshAsset(TEXT("StaticMesh'/Game/StarterContent/Shapes/Shape_Cone.Shape_Cone'"));
if (MeshAsset.Succeeded())
{
	ConeStaticMeshComponent->SetStaticMesh(MeshAsset.Object);
}

// Find a static mesh in the project folder and then assign it to CubeStaticMeshComponent
static ConstructorHelpers::FObjectFinder<UStaticMesh>ChildMeshAsset(TEXT("StaticMesh'/Game/StarterContent/Shapes/Shape_Cube.Shape_Cube'"));
if (ChildMeshAsset.Succeeded())
{
	CubeStaticMeshComponent->SetStaticMesh(ChildMeshAsset.Object);
}

// Offset the rotation, location, and scale of CubeStaticMeshComponent from the root component.
FTransform OffsetTransform = FTransform(FRotator(0.0f, 80.0f, 30.0f), FVector(500.0f, 0.0f, 0.0f), FVector(1.0f, 1.0f, 1.0f));
CubeStaticMeshComponent->SetRelativeTransform(OffsetTransform);

}

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

}

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

}

Hi Oro Seun,

I’m guessing you’re using “Live Coding” - try closing your project, build from your compiler and run from there - that may help…

1 Like

Thank you for your help. I followed your advice and it resolved the issue.

I also read more about the “Live Coding” you suspected might be causing the issue. I found that I was actually not using “Live Coding” but was using “Hot Reload.”

However, while reading the article on “Live Coding”, I read that “When changing default values for variables, values set in the constructor implemented in the .cpp file will not update in existing instances of objects. However, if you change them in your .h file, you will see the change take place.”

That section of the article explained the issue I was facing. As you will see in the code I shared, I initialized and modified the code in the constructor function AMyActor::AMyActor() {….}

That seemed to be the reason why the instances already placed in the viewport were not updating when I modified the transform value in the C++ code.

By following your advice, i.e Pressing “Ctrl + F5” in Visual Studio instead of the “Ctrl + Shift + B” I was previously pressing, the actor instances were updated. Pressing Ctrl + F5 recompiled the code and then open another Unreal Engine window with the updated instances.

However, there is a catch. That solution only works if I have not manually edit the transform of the child components in the “Details panel of the viewport.” Once I modify them in the details panel, pressing “Ctrl + F5” in Visual Studio will still not update the transform edited in the C++ code. I guess Unreal Engine is respecting the manual changes I made to the instances already in the viewport.

Thanks again for your help. It helped resolve the issue and made me understand what was happening.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.