How to do it...

  1. Create a new Actor called OnConstructionActor based on StaticMeshActor:

  1. Update the header file to the following: 
#pragma once

#include "CoreMinimal.h"
#include "Engine/StaticMeshActor.h"
#include "OnConstructionActor.generated.h"

UCLASS()
class CHAPTER_09_API AOnConstructionActor : public AStaticMeshActor
{
GENERATED_BODY()

public:
AOnConstructionActor();

virtual void OnConstruction(const FTransform& Transform) override;

UPROPERTY(EditAnywhere)
bool ShowStaticMesh;

};
  1. Go to the implementation file (OnConstructionActor.cpp) and implement the class constructor:
#include "OnConstructionActor.h"
#include "ConstructorHelpers.h"

AOnConstructionActor::AOnConstructionActor()
{
// 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;

auto MeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(
TEXT("StaticMesh'/Engine/BasicShapes/Cone.Cone'"));

UStaticMeshComponent * SM = GetStaticMeshComponent();

if (SM != nullptr)
{
if (MeshAsset.Object != nullptr)
{
SM->SetStaticMesh(MeshAsset.Object);
SM->SetGenerateOverlapEvents(true);
}
SM->SetMobility(EComponentMobility::Movable);
}

// Default value of property
ShowStaticMesh = true;
}
  1. Implement OnConstruction:
void AOnConstructionActor::OnConstruction(const FTransform& Transform) 
{ 
  GetStaticMeshComponent()->SetVisibility(ShowStaticMesh); 
} 
  1. Compile your code and launch the editor.
  2. Drag an instance of your class into the game world, and verify that toggling the Boolean value for ShowStaticMesh toggles the visibility of the mesh in the editor viewport:

  1. OnConstruction does not currently run for C++ actors that are placed in a level if they are moved.
  2. To test this, place a breakpoint in your OnConstruction function, and then move your actor around the level.
To place a breakpoint, place your cursor on the desired line and hit F9 in Visual Studio.
  1. You'll notice that the function doesn't get called, but if you toggle the ShowStaticMesh Boolean, it does, causing your breakpoint to trigger.
To see why, take a look at the beginning of the AActor::PostEditMove function: 
void AActor::PostEditMove(bool bFinished)
{
if ( ReregisterComponentsWhenModified() && !FLevelUtils::IsMovingLevel())
{
UBlueprint* Blueprint = Cast<UBlueprint>(GetClass()->ClassGeneratedBy);
if (bFinished || bRunConstructionScriptOnDrag || (Blueprint && Blueprint->bRunConstructionScriptOnDrag))
{
FNavigationLockContext NavLock(GetWorld(), ENavigationLockReason::AllowUnregister);
RerunConstructionScripts();
}
}

// ....

The top line here casts UClass for the current object to UBlueprint, and will only run the construction scripts and OnConstruction again if the class is a Blueprint.