SetScalarParameterValue Access Violation

Hi folks,

So my problem is I get an access violation when I want to change a parameter of my material instance when clicking on the mesh. I’ve tried different things for 2hrs now and can’t seem to find what I’m doing wrong. I’m working within a class derived from UStaticMeshComponent.

This is my setup:

Constructor:

	auto materialAsset = ConstructorHelpers::FObjectFinder<UMaterial>(TEXT("Material'/Game/Materials/M_Editor_Node.M_Editor_Node'"));
	if (materialAsset.Object != nullptr)
	{
		UMaterialInterface * mInterface = Cast<UMaterialInterface>(materialAsset.Object);
		if (mInterface != nullptr)
		{
			SetMaterial(0, mInterface);
		}
		else
		{
			Logging::Log("Couldn't cast material to interface");
		}
	}
	else
	{
		Logging::Log("Could not find Asset at path '/Game/Materials/MI_Editor_Node.MI_Editor_Node' in CellEditor_NodeComponent.Constructor");
	}

These components are all created on runtime and need to get some additional values so I got this PostConstructor:

materialDynamic = UMaterialInstanceDynamic::Create(this->GetMaterial(0), this);
/* Some more stuff... */

And finally in my function that registers the click:

if(materialDynamic != nullptr)
					materialDynamic->SetScalarParameterValue(FName("Hover"), 1);

This last part causes the access violation. If it helps this is the log from the crash:

[2018.11.08-15.25.22:075][863]LogWindows: Error: === Critical error: ===
[2018.11.08-15.25.22:075][863]LogWindows: Error: 
[2018.11.08-15.25.22:075][863]LogWindows: Error: Fatal error!
[2018.11.08-15.25.22:075][863]LogWindows: Error: 
[2018.11.08-15.25.22:075][863]LogWindows: Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffff
[2018.11.08-15.25.22:075][863]LogWindows: Error: 
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x000000005ADC8F50 UE4Editor-Core.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x000000005AA589C3 UE4Editor-Core.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x000000005AA58C6E UE4Editor-Core.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x000000005838FA39 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x000000005830772B UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x0000000058399C14 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x0000000058399B1C UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x0000000048C47917 UE4Editor-Lyfe_Game.dll!UCellEditor_NodeComponent::HandleInput() [c:\users\megapoort\desktop\lyfe\lyfe_game\source\lyfe_game\private\celleditor_nodecomponent.cpp:182]
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x0000000057CCD828 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x0000000057D00394 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x00000000589D70BB UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x00000000589DC793 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x000000005A9EB713 UE4Editor-Core.dll!UnknownFunction []
[2018.11.08-15.25.22:075][863]LogWindows: Error: [Callstack] 0x000000005A9EBA50 UE4Editor-Core.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x00000000589FD4E5 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x0000000058A03292 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x000000005825C304 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x0000000058267829 UE4Editor-Engine.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x000000005640D781 UE4Editor-UnrealEd.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x0000000056CA9626 UE4Editor-UnrealEd.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x0000000086945EAC UE4Editor.exe!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x0000000086956BD0 UE4Editor.exe!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x0000000086956C4A UE4Editor.exe!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x0000000086964177 UE4Editor.exe!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x0000000086965B87 UE4Editor.exe!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x00000000AF863034 KERNEL32.DLL!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x00000000AFC21461 ntdll.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: [Callstack] 0x00000000AFC21461 ntdll.dll!UnknownFunction []
[2018.11.08-15.25.22:076][863]LogWindows: Error: 
[2018.11.08-15.25.22:087][863]LogExit: Executing StaticShutdownAfterError
[2018.11.08-15.25.22:089][863]LogWindows: FPlatformMisc::RequestExit(1)
[2018.11.08-15.25.22:089][863]Log file closed, 11/08/18 16:25:22

And the material:

Well the problem seems to originate from celleditor_nodecomponent.cpp, line 182.

Shouldn’t your dynamic material name be “Color_hover”? As in:

 if(materialDynamic != nullptr)
                     materialDynamic->SetScalarParameterValue(FName("Color_hover"), 1);

No. I want to change the scalar parameter “Hover”. If it’s zero the upper color is emitted and if it’s larger then the lower color will be emitted.

maybe it is case-sensitive. try to set parameter name exactly as in material: “Color_Hover”

I don’t to change any of the colors (vector params). I want to set the param Hover from 0 to 1.

Ah, ok. Then try to set it as float:

SetScalarParameterValue(FName("Hover"), 1.0f);

Nope. Did not work.

This is how I setup it in actor containing StaticMeshComponent.

Header:

UPROPERTY(EditDefaultsOnly, meta = (Category = "Mesh"))
	UStaticMeshComponent* StaticMeshComponent;

UPROPERTY()
	UStaticMesh* DefaultMesh;

UPROPERTY()
	UMaterialInterface* DefaultMaterial;

UPROPERTY()
	UMaterialInstanceDynamic* MID;

CPP Constructor:

static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshObj(TEXT("/Meshes/SM_Plane.SM_Plane"));
static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialObj(TEXT("/Materials/M_Base.M_Base"));
DefaultMesh = MeshObj.Object;
DefaultMaterial = MaterialObj.Object;

StaticMeshComponent->SetStaticMesh(DefaultMesh);
StaticMeshComponent->SetMaterial(0, DefaultMaterial);

CPP function that creates dynamic MI:

	MID = StaticMeshComponent->CreateDynamicMaterialInstance(0, DefaultMaterial);
	MID->SetScalarParameterValue(TEXT("Param"), 0.0f);

Okay, the only real difference I can see is that you set the param inside the actor while I do it inside the component. Could this have any effect on my problem?

Okay, I checked line 182 and it’s actually not the line where I set the param but the closing bracket of the entire function.
It works when I delete the line where I set the param, tho.

Maybe you should try to use StaticMeshComponent->CreateDynamicMaterialInstance() instead of UMaterialInstanceDynamic::Create().

And, I’m not sure, but try to use simple if(materialDynamic) instead of if(materialDynamic != nullptr)

When you delete the line, does it work as expected, as in the material changes, or does it just not crash? If it just doesn’t crash you’ve found the offending line of code, and now we can work toward fixing it :slight_smile:

I’ve looked a bit into “EXCEPTION_ACCESS_VIOLATION reading address 0xffffffff”. In Unreal it tends to happen when something is not (yet) set or initialized. So this might be an issue of you not calling Super methods on your overridden methods(for example: in your class derived from UStaticMeshComponent). It could be that you’re trying to change parameters of a material that is not yet initialized, used etc. Maybe you’re overriding the materials in blueprints or something like that, and the material you’re trying to change in C++ does not have the parameter.

Also, since I don’t have the whole code, are you saving a reference to your material to materialDynamic variable? You can access it in a UStaticMesh derived class via GetMaterial

UMaterialInstanceDynamic* Mat_Inst = this->GetMaterial(0);
if(Mat_Inst)
{
    Mat_Inst->SetScalarParameterValue(FName("Hover"), 1.0f);
}

Assuming that this is the only material used on the mesh.

P.S. Make sure your parameter is “Hover” and not "Hover " with a trailing space.

If I delete the line setting the param, it doesn’t crash but then nothing happens, so that’s definitely no solution.

Okay, so something’s not initialized. That’s what I wanted to catch with the if(materialDynamic != nullptr).
I’m loading the material via the FObjectFinder and setting it via this->SetMaterial(); This works since the material actually is on my mesh. So the material has to be initialized.
Maybe when creating a dynamic instance.

materialDynamic is a attribute of my component class.

I tried something different with the constructor. Now it looks like this but I still get the same result:

auto materialAsset = ConstructorHelpers::FObjectFinder<UMaterialInstance>(TEXT("MaterialInstace'/Game/Materials/MI_Editor_Node.MI_Editor_Node'"));
	if (materialAsset.Object != nullptr)
	{
		UMaterialInstance * mInstance = Cast<UMaterialInstance>(materialAsset.Object);
		if (mInstance != nullptr)
		{
			materialDynamic = UMaterialInstanceDynamic::Create(mInstance, this, FName("Material"));
			//materialDynamic = CreateAndSetMaterialInstanceDynamicFromMaterial(0, GetMaterial(0));

			SetMaterial(0, materialDynamic);
		}
		else
		{
			Logging::Log("Couldn't cast material to instance");
		}
	}
	else
	{
		Logging::Log("Could not find Asset at path '/Game/Materials/MI_Editor_Node.MI_Editor_Node' in CellEditor_NodeComponent.Constructor");
	}

Didn’t change anything.
And with StaticMeshComponent->CreateDynamicMaterialInstance() the material isn’t set anymore.

Maybe this helps a bit:
All the handling for hover and so on is in the staticMeshComponent beause I want to handle all the components individually.
The base class is invisible and just handles the logic. It has a attribute baseNode. It is of the class node.
Each node can have [0 - 4] child nodes.
All the code from the question up there is inside the node class.

Would it help to give you all of the code to look at and maybe test?

I have been struggling with the same odd error starting to pop up on me. Two things.

  1. I use:
    WaterMaterial = UMaterialInstanceDynamic::Create(SurfaceMaterial, NULL);
    I read that the use of this vs NULL can cause unexpected results - not sure this is an issue, but I read it so worth a try.

  2. I added a second “Create” statement just above my SetScalarParam statement and the crash went away. Which leads me to a sequencing of functions. I think your code is calling the SetScalarParam too soon, my test of adding a new create above it is not the fix, but it does say that in my case. If the object exists then the line doesn’t crash.

Then you need to track down your sequence issue.