Download

Struggling to adjust a material parameter via c++

So in my Character header file i have these lines:



        float testfloat;

	void UpdateTeamColors(UMaterialInstanceDynamic* UseMID);

	UPROPERTY(Transient)
	TArray<UMaterialInstanceDynamic*> MeshMIDs;

	void TeamColorVerify();


in the Character cpp file i have this:



//in constructor
testfloat = 0.f;

//and these functions

void ASmashyCharacter::UpdateTeamColors(UMaterialInstanceDynamic* UseMID)
{
	if (UseMID)
	{
		ASmashyPlayerState* MyPlayerState = Cast<ASmashyPlayerState>(PlayerState);
		if (MyPlayerState)
		{
			float MaterialParam = (float)MyPlayerState->GetTeamNum();
			UseMID->SetScalarParameterValue(TEXT("TeamColorIndex"), MaterialParam);
		}
	}
}

void ASmashyCharacter::UpdateTeamColorsAllMIDs()
{
	for (int32 i = 0; i < MeshMIDs.Num(); ++i)
	{
		UpdateTeamColors(MeshMIDs*);
	}
}

void ASmashyCharacter::TeamColorVerify()
{
	ASmashyPlayerState* MyPlayerState = Cast<ASmashyPlayerState>(PlayerState);
	for (int32 i = 0; i < MeshMIDs.Num(); ++i)
	{
		UpdateTeamColors(MeshMIDs*);
	
	testfloat += 1.f;
	UMaterialInstanceDynamic* MI = UMaterialInstanceDynamic::Create(Mesh->GetMaterial(0), this);
	MI->SetScalarParameterValue(TEXT("TeamColorIndex"), testfloat);

	//float MaterialParam = (float)MyPlayerState->GetTeamNum();
	//MeshMIDs*->SetScalarParameterValue(TEXT("TeamColorIndex"), testfloat);
	}
}



Here’s the problem. if i create a breakpoint at the start of UpdateTeamColorsAllMIDs(), it breaks, so the function is being run. it also breaks if i place a point at the start of the for loop.

If i place a break point inside the for loop (UpdateTeamColors(MeshMIDs*);), this break point is never triggered.

So then i set up the final function just to see if i could debug this somewhat. TeamColorVerify() is triggered by a button press (e). placing breakpoints within the function confirms that it’s being triggered fine. EXCEPT for within the for loop, the same line fails to trigger the break point as in the previous function.

Also, annoyingly… TeamColorVerify() doesn’t seem to adjust the TeamColorIndex parameter within the material that’s applied to the character mesh.

This means i have two problems. The first is that for some reason the function within the for loop is never triggered (super frustrating). And also the parameter isn’t changed either. This is still the case if i uncomment the bottom two lines in TeamColorVerify().

Any ideas?

After creating your MID, you have to overwrite the original material with it:



UMaterialInstanceDynamic* MI = UMaterialInstanceDynamic::Create(Mesh->GetMaterial(0), this);
Mesh->SetMaterial(0, MI)
MI->SetScalarParameterValue(TEXT("TeamColorIndex"), testfloat);


Alternatively, UPrimitiveComponent::CreateAndSetMaterialInstanceDynamic will handle both creating and replacing the material for you.

okay mark me down as a *****… forgot to actually fill the MeshMID’s array with data -_-



Fatal error: [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.5\Engine\Source\Runtime\CoreUObject\Private\Templates\Casts.cpp] [Line: 11] 
Cast of GameUserSettings /Engine/Transient.GameUserSettings_0 to SmashyGameUserSettings failed


this is destroying me, i’ve been trying to fix this for two hours but i have no idea how to fix it.

A CastChecked is failing, most likely because the instance is null. You should only use CastChecked if something is guaranteed to not be null.

Yeah i’ve changed that to Cast, but it’s still breaking. I’ve posted more info here:
https://answers.unrealengine.com/questions/139644/gameusersettings-failing-to-cast-1.html

Ah, my bad, it’s not null, but rather of the wrong type. The path /Engine/Transient.GameUserSettings_0 sounds like a GameUserSettings instance, not a SmashyGameUserSettings instance. Have you updated the GameUserSettingsClassName config in your project settings / DefaultEngine?

i had, two days ago… but i made a typo and didn’t find it until last night. =/