Static Mesh Actor

Hi,

I am new to game development and Unreal Engine 4. I am using version 4.7

I have for example 8 chairs and 8 tables. I have converted everything into fbx files using Autodesk. After importing in Unreal Editor, I followed the basic tutorial.

As I am a beginner, I have seen with basic C++ programming and followed this Programming Quick Start | Unreal Engine Documentation link and I created a basic Actor class. After building it, I placed 8 Actor class into the viewport and changed that to StaticMesh to Chair1-8.

The problem is, I do not want to change that each Actor class to StaticMesh as Chair. It should automatically recognize the class as StaticMesh for all the 8 Chairs.

Can somebody please help me to find the solution for this issue.

Any code or tutorial might help.

Thanks in advance!

I’m not 100% what you want to achieve. Just to make sure I understand what you want to do. You are trying to create an Actor class that features a Static Mesh Component, each mesh of that actor should be set to a different chair? Or do you want to create a new children of the StaticMeshActor class?

Yes exactly. I need to create a StaticMeshComponent as Chair 1-8 i.e as you said, each mesh of that actor should be set to different chair. And this process should be automated for all the actors (eg: for all 8 chairs or for all 8 tables).

I think if tou wanted to do that sequentially or make sure that every chair is different it would need more work. But the idea is just make an array of staticmesh and assign that in your staticmeshcomponent, you can do that in the construction script in the blueprint or on your construction method in your class, or in yhe postInitializeComponents function or others (please read ue4 doc of actor initialization step). I think i have seen some implementation of this in youtube. Just search crowd system test ue4 in youtube. I think in some videos the author to this mechanics to change the mesh

The esiest way on doing it would be creating a Parent class that holds a list of static meshe. Create an enum blueprint type and add an entry for each of your chairs and add a variable of that enum type to your BP class. Now in the PostInitializeComponents method you check if there is a mesh in your list for the given enum type and if yes change the mesh of the StaticMeshComponent.

The next part would be creating a BP class that inherits from your C++ class, in the defaults section of that class just fill the array with the meshes you would like to use (1-8 chair meshes). Now each time you change the enum the mesh will change. To go a step further you can create another class that inherit from your BP class setting the enum value by default to a given one, this way you can then just drop a specific type of chair.

I recommend creating such a relationship between C++ and BP so that you hold any real content reference in BP space, this will help you when you package your game and you cook your content. References should only be set in BP for simplicity, flexibility and to only load the required resources at any moment.

If you have different chair base BP classes that can hold different meshes just create a list that contains each enum to later see if it is there, this is like a list of linkes which maps an enum value to an index of the available meshes list.

Cheers,
Moss

EDIT: I’m resolving the issue for now, if you need any further assistance please reopen it ^^ Hope you where able to achieve your goals

Did one of the answers work?

As you said, I have created a Parent class as Actor and listed out the components as Chair1-8. Then I created an Enum Blueprint and added all the Chair entries and called that type as a variable in Actor class Blueprint. Then I created a c++ Actor class and created a method PostInitializeComponents. But as I am new to write C++ in Unreal 4, I am facing some problems to complete the code. I am just trying it…

You do not need to add 8 components, just one. You only need an array which contains the meshes. Then in PostInitializeComponents you just set the correct mesh to the used by the static mesh component.

I have a doubt that if I add only one component, which chair should I choose as static mesh in component properties?
And I changed as an array to the variable which I called as an Enum type in Actor class.

You shouldn’t select any in the properties tab, you should set the static mesh of the component in your construction script or PostInittializeComponents if you are planing to so so in C++.

The idea is to set the mesh based on a value, in your case an enum, you use the enum to indicate which mesh you have to set.

I am getting an error in PostInitializeComponent method in .cpp file. Can you please check whether my code is correct?

My .h file looks like this,

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

#pragma once

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

UENUM(BlueprintType)
enum class EChairEnumActors : uint8
{
	EChair1 UMETA(DisplayName = "Chair1"),
	EChair2 UMETA(DisplayName = "Chair2"),
	EChair3 UMETA(DisplayName = "Chair3"),
	EChair4 UMETA(DisplayName = "Chair4"),
	EChair5 UMETA(DisplayName = "Chair5"),
	EChair6 UMETA(DisplayName = "Chair6"),
	EChair7 UMETA(DisplayName = "Chair7"),
	EChair8 UMETA(DisplayName = "Chair8"),
};


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

	virtual void PostInitializeComponents() OVERRIDE;

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

	TSubobjectPtr<UStaticMeshComponent> Chairs;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Enum)
	EChairEnumActors ActorsType;

};

.cpp file

#include "BPCPP2.h"
#include "MyActor.h"
    
AMyActor::AMyActor()    {  PrimaryActorTick.bCanEverTick = true; }
void AMyActor::PostInitializeComponents()    {
  Super::PostInitializeComponents();
  static ConstructorHelpers::FObjectFinder<UStaticMesh> ChairMesh1(TEXT("StaticMesh'C:BPCPP2/Content/Chairs_Chair1.uasset'"));
  static ConstructorHelpers::FObjectFinder<UStaticMesh> ChairMesh2(TEXT("StaticMesh'C:BPCPP2/Content/Chairs_Chair2.uasset'"));
  static ConstructorHelpers::FObjectFinder<UStaticMesh> ChairMesh3(TEXT("StaticMesh'C:BPCPP2/Content/Chairs_Chair3.uasset'"));
  static ConstructorHelpers::FObjectFinder<UStaticMesh> ChairMesh4(TEXT("StaticMesh'C:BPCPP2/Content/Chairs_Chair4.uasset'"));
  static ConstructorHelpers::FObjectFinder<UStaticMesh> ChairMesh5(TEXT("StaticMesh'C:BPCPP2/Content/Chairs_Chair5.uasset'"));
  static ConstructorHelpers::FObjectFinder<UStaticMesh> ChairMesh6(TEXT("StaticMesh'C:BPCPP2/Content/Chairs_Chair6.uasset'"));
  static ConstructorHelpers::FObjectFinder<UStaticMesh> ChairMesh7(TEXT("StaticMesh'C:BPCPP2/Content/Chairs_Chair9.uasset'"));
  static ConstructorHelpers::FObjectFinder<UStaticMesh> ChairMesh8(TEXT("StaticMesh'C:BPCPP2/Content/Chairs_Chair10.uasset'"));
  if (ActorsType != NULL)  {
    	Chairs = EChairEnumActors::EChair1->SetStaticMesh(ChairMesh1.Object);
    	Chairs = EChairEnumActors::EChair2->SetStaticMesh(ChairMesh2.Object);
    	Chairs = EChairEnumActors::EChair3->SetStaticMesh(ChairMesh3.Object);
    	Chairs = EChairEnumActors::EChair4->SetStaticMesh(ChairMesh4.Object);
    	Chairs = EChairEnumActors::EChair5->SetStaticMesh(ChairMesh5.Object);
    	Chairs = EChairEnumActors::EChair6->SetStaticMesh(ChairMesh6.Object);
    	Chairs = EChairEnumActors::EChair7->SetStaticMesh(ChairMesh7.Object);
    	Chairs = EChairEnumActors::EChair8->SetStaticMesh(ChairMesh8.Object);
  }
}
void AMyActor::BeginPlay()    { Super::BeginPlay(); }
void AMyActor::Tick( float DeltaTime )    { Super::Tick( DeltaTime ); }

Could you post the error?

Sorry for the late response. You are having some basic C++ errors in there, EChairEnumActors is an enum value so you can not use it as a pointer. The compiler gives you hints on that issue.

What I suggest would be writing your mesh assignment like:

switch(ActorsType)
{
	case EChairEnumActors::EChair1:
		this->GetMeshComponent()->SetStaticMesh(ChairMesh1.Object);
		break;
	case EChairEnumActors::EChair2:
		this->GetMeshComponent()->SetStaticMesh(ChairMesh2.Object);
		break;
	case EChairEnumActors::EChair3:
		this->GetMeshComponent()->SetStaticMesh(ChairMesh3.Object);
		break;
	case EChairEnumActors::EChair4:
		this->GetMeshComponent()->SetStaticMesh(ChairMesh4.Object);
		break;
	case EChairEnumActors::EChair5:
		this->GetMeshComponent()->SetStaticMesh(ChairMesh5.Object);
		break;
	default:
		// TODO: Add the rest of the cases and a log if the default case is called
		break;
}

I strongly recommend you learning C++ for such cases.

Cheers,
Moss