Add Mesh From File

November 30, 2017

UE4 Version: 4.18.3

Github Link: https://github.com/Harrison1/unrealcpp/tree/master/AddMeshFromFile

For this tutorial we are using the standard first person C++ template with starter content. If you don't know how to add a new actor class to your project, please visit the Add C++ Actor Class post.

Let's start by creating a new actor named AddMeshFromFile. We don't have to do anything inside the header file. Below is the default header we generated when we created a new class.

AddMeshFromFile.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "AddMeshFromFile.generated.h"

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

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

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

In order to programmatically add a specific mesh we must include the ConstructorHelpers.h file. Include the file below your actor's named header file

include ConstructorHelpers.h

#include "AddMeshFromFile.h"
// add constructor header
#include "ConstructorHelpers.h"

Next in our actor's init function we will set the default values of the mesh we want to add to the actor. Create a UStaticMeshComponent pointer and set it as your RootComponent.

create UStaticMeshComp and set root

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

	// add Cylinder to root
    UStaticMeshComponent* Cylinder = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
    Cylinder->SetupAttachment(RootComponent);

}

After our initial setup our next step is to add the mesh we want to our actor. We are going to use the ConstructorHelpers method FObjectFinder to locate our mesh. In this example I am calling the variable CylinderAsset and passing in the path to the cylinder shape provided by the starter content. The path we pass in is /Game/StarterContent/Shapes/Shape_Cylinder.Shape_Cylinder.

FObjectFinder method

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

	// add Cylinder to root
    UStaticMeshComponent* Cylinder = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
    Cylinder->SetupAttachment(RootComponent);

    static ConstructorHelpers::FObjectFinder<UStaticMesh> CylinderAsset(TEXT("/Game/StarterContent/Shapes/Shape_Cylinder.Shape_Cylinder"));

}

Next, let's do an error check to ensure we successfully get the mesh. If the statement passes let's SetStaticMesh, SetRelativeLocation, SetWorldScale3D on our Cylinder component.

if asset succeeded

if (CylinderAsset.Succeeded()) {}

SetStaticMesh

if (CylinderAsset.Succeeded()) 
{
    Cylinder->SetStaticMesh(CylinderAsset.Object);
}

SetRelativeLocation

if (CylinderAsset.Succeeded()) 
{
    Cylinder->SetStaticMesh(CylinderAsset.Object);
    Cylinder->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
}

SetWorldScale3D

if (CylinderAsset.Succeeded()) 
{
    Cylinder->SetStaticMesh(CylinderAsset.Object);
    Cylinder->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
    Cylinder->SetWorldScale3D(FVector(1.f));
}

Below is the final .cpp file.

AddMeshFromFile.cpp

#include "AddMeshFromFile.h"
// add constructor header
#include "ConstructorHelpers.h"


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

	// add Cylinder to root
    UStaticMeshComponent* Cylinder = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
    Cylinder->SetupAttachment(RootComponent);

    static ConstructorHelpers::FObjectFinder<UStaticMesh> CylinderAsset(TEXT("/Game/StarterContent/Shapes/Shape_Cylinder.Shape_Cylinder"));

	if (CylinderAsset.Succeeded())
    {
        Cylinder->SetStaticMesh(CylinderAsset.Object);
        Cylinder->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
        Cylinder->SetWorldScale3D(FVector(1.f));
	}

}

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

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

}

Author

Harrison McGuire

Harrison McGuire