Trouble Changing Material Variant of a Part Through a Script

  1. What do I want to achieve?

I have a function that creates a new part via Instance.new(). I also created a new MaterialVariant and would like to apply it to my newly created part alongside all other properties

  1. What is the issue?

After numerous iterations, I have received the same error time and time again:
“Unable to assign property MaterialVariant, string expected, got Instance”

Here is the first iteration of my ModuleScript:
Edit: I forgot to add it to the below scripts, but MaterialService was correctly labeled in above the function.

function TerrainGenerator.createCustomPart()
	-- Create a new part
	local newPart = Instance.new("Part")
	-- Elaborate on newPart's properties
	newPart.Size = Vector3.new(25.125, 1, 37.938)
	newPart.Anchored = true
	newPart.BrickColor = BrickColor.new("Brown")
	
	-- Get newPart's BASE material
	newPart.Material = Enum.Material.Ground
	-- Get newPart's Material Variant
	newPart.MaterialVariant = MaterialService:GetMaterialVariant(Enum.Material.Ground, "RealisticDirtPath1")
	-- Parent the object to the workspace
	newPart.Parent = workspace
end

This unfortunately did not work, and so I made a second iteration:

function TerrainGenerator.createCustomPart()
	-- Create a new part
	local newPart = Instance.new("Part")
	-- Elaborate on newPart's properties
	newPart.Size = Vector3.new(25.125, 1, 37.938)
	newPart.Anchored = true
	newPart.BrickColor = BrickColor.new("Brown")
	
	-- Define Variables for BaseMaterial and MaterialVariant
	local baseMaterial = Enum.Material.Ground
	local materialVariantName = "RealisticDirtPath1"
	
	-- Set the base material of newPart
	newPart.Material = baseMaterial
	
	-- Get newPart's MaterialVariant
	local materialVariant = MaterialService:GetMaterialVariant(baseMaterial, materialVariantName)
	if materialVariant then
		newPart.MaterialVariant = materialVariant
	else
		warn("This material variant does not exist")
	end
newPart.Parent = workspace
end
  1. What solutions have I tried thus far?

As listed above, I first tried to rewrite the code, but that did not work. I then looked at the documentation for MaterialService and GetMaterialVariant, which really did not help much. The GetMaterialVariant method only requires two arguments: The base material, and the material variant as a string.

I made sure that my custom Material Variant did exist, and all instances of the name across the ModuleScript were spelled accordingly to the variant in the object explorer.

Lastly, I tried asking the assistant, and after it verifying my script, I was told to ask the devhub forum.

Any help in this matter would be greatly appreciated, thanks in advance.

1 Like

This is pretty simple, just do:

local MaterialService = game:GetService("MaterialService")
local targetMaterial = MaterialService.TargetMaterial

part.MaterialVariant = targetMaterial

What is TargetMaterial in your example? Is that the name of the material variant? And if so, I thought the base material needed to be set first? I was under the impression that MaterialVariant had to be a string.

It is the material variant, which should be stored inside the MaterialService
Screenshot 2023-11-28 at 2.28.08 PM

This still did not work. Here is my new script:

function TerrainGenerator.createCustomPart()
-- Create a new part
	local newPart = Instance.new("Part")
	-- Elaborate on newPart's properties
	newPart.Size = Vector3.new(25.125, 1, 37.938)
	newPart.Anchored = true
	newPart.BrickColor = BrickColor.new("Brown")
newPart.Material = Enum.Material.Ground
	newPart.MaterialVariant = MaterialService.RealisticDirtPath1
newPart.Parent = workspace

I got the same error: Unable to assign property Materialvariant, string expected, got Instance. My custom material is in MaterialService.

You just set MaterialVariant by name, e.g.:

newPart.MaterialVariant = "RealisticDirtPath1"

As long as you set the part.Material to match the MaterialVariant.BaseMaterial, it should work as expected. The Part.MaterialVariant property is not an instance reference, it’s just the name of the material variant (a string).

1 Like

This worked. I am unsure how the first script I used did not work. Perhaps I misused the GetMaterialVariant method. Thanks.

The GetMaterialVariant method returns you the actual MaterialVariant instance that’s somewhere inside MaterialService. You can use that to make sure you are setting the right Part.Material, and to access other properties of the material variant, but you can’t assign the instance reference directly to the Part.MaterialVariant property, since that expects just the name of it.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.