How to Detect the Material of a Terrain Part

Hi, basically, I want to detect the material of a terrain part. I’m making a gun kit and I want to have effects for hitting materials. I’ve achieved this with parts with no problems, however, now that it’s come to terrain, it won’t work. Here’s my code:

local makeHitParticleFX = function(tool, hitPart, hitPos, blood)
	
	if not hitPart:IsA("BasePart") then
		return
	end
	
	local particleFolder = nil

	if not blood then
		particleFolder = tool:WaitForChild("MainModule"):WaitForChild("HitEffects"):WaitForChild(hitPart.Material)
	else
		particleFolder = tool:WaitForChild("MainModule"):WaitForChild("HitEffects"):WaitForChild("Blood")
	end
	
	local attachment = Instance.new("Attachment")
	attachment.Parent = game.Workspace.Terrain
	attachment.WorldPosition = hitPos
	
	local chosenParticle = chooseRandomChild(particleFolder, "ParticleEmitter")
	local particle = chosenParticle:Clone()
	particle.Parent = attachment
	
	if not blood then
		local pColor = particle:FindFirstChild("PartColor")
		
		if pColor then
			if pColor.Value then
				if hitPart:IsA("BasePart") and hitPart.ClassName ~= "Terrain" then
					local hitPartColor = hitPart.Color
					
					particle.Color = ColorSequence.new{
						ColorSequenceKeypoint.new(0, hitPartColor),
						ColorSequenceKeypoint.new(1, hitPartColor),
					};
					
				elseif hitPart:IsA("Terrain") then
					
					local ray = Ray.new(hitPos, Vector3.new(0, 0, 0))
					ray
					local _, _, _, material = workspace:FindPartOnRayWithWhitelist(ray, {workspace.Terrain})
					
					local hitPartColor = game.Workspace.Terrain:GetMaterialColor(material)
					particle.Color = ColorSequence.new{
						ColorSequenceKeypoint.new(0, hitPartColor),
						ColorSequenceKeypoint.new(1, hitPartColor),
					};
				end
			end
			
		else
			particle.Color = ColorSequence.new{
				ColorSequenceKeypoint.new(0, hitPart.Color),
				ColorSequenceKeypoint.new(1, hitPart.Color),
			};
		end
	end
	
	muzzleHandler.Emit(particle, particle:WaitForChild("EmitCount").Value)
	debrisService:AddItem(attachment, (particle.Lifetime.Max - particle.Lifetime.Min))
	
end

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

1 Like

Why not just send the RaycastResult to the function instead of hitpart and hitpos, and get those from RaycastResult.Instance and RaycastResult.Position and then you can also get the material from RaycastResult.Material instead of having to shoot another ray to get it?

2 Likes

I use fastcasting for this. hitPart is the Fastcast instance & hitPos is the bullet’s final position.

1 Like

Im pretty sure fastcast does give you same result as normal casting so you should be getting material with it as well.

1 Like

Hi. Thank you so much, it worked! This is great, honestly this was so frustrating but it had such a simple solution! Thank you very much. The cast result is the same as a raycast result, so it worked perfectly. Thanks.

1 Like

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