I’m new in Unreal development and I have created a material with a vector parameter for its base colour. I have also a material instance for this material.
I want to use this material in many objects, but all of these objects will have different colours. And these objects will be created at runtime: I have a spawner class to spawn them. For testing purposes I have two spheres with the material instance applied.
AStarActor::AStarActor()
{
// 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;
// Our root component will be a sphere that reacts to physics
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
RootComponent = SphereComponent;
SphereComponent->InitSphereRadius(1.0f);
SphereComponent->SetCollisionProfileName(TEXT("SphereStart"));
// Create and position a mesh component so we can see where our sphere is
SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
SphereVisual->AttachTo(RootComponent);
static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
if (SphereVisualAsset.Succeeded())
{
UStaticMesh* mesh = SphereVisualAsset.Object;
static ConstructorHelpers::FObjectFinder<UMaterial> MatFinder(TEXT("Material'/Game/Geometry/Materials/Star.Star'")); // "MaterialInstanceConstant'/Game/Geometry/Materials/Star_Inst.Star_Inst'"
if (MatFinder.Succeeded())
{
StarMaterial = MatFinder.Object;
}
SphereVisual->SetStaticMesh(mesh);
SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
SphereVisual->SetWorldScale3D(FVector(0.8f));
}
}
I want to use the same material in all of the objects but each of them with different colours. Now, if I change its base colour in one of them, all of them will have the same colour.
Add a param to the main material with the color, and then create a material instance. You’ll need to duplicate the material instance for each color you want, but it will be much more optimized than using a separate material with only the colors changed. I also do this for UV scaling for various meshes. I’ll post some screenshots if you need once I get off of work tonight.
If they are all material instances, you can set their scalar/vector parameters in blueprint with the “set scalar/vector parameter” nodes and change their values to whatever you want when they spawn.
The two yellow balls have a yellow material instance, and in the game I create balls with white-blue material. As you can see, all the Actors in game change their material instance.
In the first screenshot, I show how to 1) Create a UV Scaling parameter and 2) Using a Switch Param to add a color to the texture. This is my main project, and I only needed a normal texture, or a red one. In the second picture, I made up a section that will allow you to specify any color you want.
Once one of these are in your main material, right click the material, and create a material instance. Name this instance MainMatName_Color_Inst. Create as many instances as you need colors for. Change each individual instance to whatever color, and add that instance to the mesh’s material slot.
PS: In the comment node, I say to connect the blue pin to an alpha mask… it’s actually the alpha channel that needs connected to an alpha mask (if you have one)… it’s the bottom pin.
W/o downloading the git (I’m about to call it a night)… did you make sure to have a different material instance on each of the balls? The yellow ball should have your yellow color instance, the white ball should have a white color instance. It sounds like you just made a single instance, and your modifying that single instance. For two colors, you need to make 2 separate instances.
Also, if they are changing colors when you start the game, are you doing anything to the material inside of a level or actor blueprint?
Finally, I have understood the problem. The two objects created with the Editor get their colour from the C++ code in PostInitializeComponents method. It seems that when I start the game, the two spheres run PostInitializeComponents method and then change their colours.