Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How do detect Terrain Material Type instead of Brick Material on Mud?

Hello, the following code prints "Enum.Material.Plastic" when my mouse is moving over the Mud Terrain Enum Material. I would like to detect only the Mud.

mouse.Move:Connect(function()
	if mouse.Target ~= nil then
		if mouse.Target:IsA("Terrain") then
			print(mouse.Target.Material)
		end
	end
end)

Edit: The following code yields no output because the the game thinks that the Mud is plastic. So checking if it is mud with this method won't work.

mouse.Move:Connect(function()
	if mouse.Target ~= nil then
		if mouse.Target:IsA("Terrain") then
			if mouse.Target.Material == Enum.Material.Mud then
				print(mouse.Target.Material)
			end
		end
	end
end)

1 comment

0

try using voxels

1 answer

ReadVoxels


To see what material a terrain object is at a specific point, you would have to use the ReadVoxels function of terrain objects.

You may be asking, "what is voxels?", well, a voxel is basically a point in 3d space, often arranged in a grid.In Roblox, each cell in the voxel grid measures 4x4x4 studs.

To create the terrain effect, points in the voxel grid are assigned a material. This material is then filled in around the voxel to create the terrain. With Smooth Terrain each voxel contains an occupancy value along with its material value. This occupancy value defines how full the voxel is with the given material. This value can be anywhere between 0 (almost completely empty) to 1 (very full, sometimes overflowing). When Roblox generates terrain based on these values, the shape of the terrain is organically generated to create smooth curves to accommodate varying occupancy values.

The ReadVoxels function takes a region in the form of a region3 and a resolution ranging from 1-4, and returns the raw voxel data for the region specified. This data is returned as 2 3d arrays, the first containing the material values, the second containing the occupancy.

Ex of 3d array :

local 3dArr = {
	{
		{"oof"}
	}
}

print(3rdArr[1][1][1])

Both arrays also have a Vector3 property called Size that can be used to determine the size of the arrays in each of their dimensions.

ExpandToGrid can be used to ensure that the correct region is used.

With all that said, here is an example of how you can use this:

local mouse = game.Players.LocalPlayer:GetMouse()
local rs = game:GetService("RunService")
local vector = Vector.new(1,1,1)
local resolution = 4

rs.RenderStepped:Connect(function()
	local Mpos = mouse.Hit.Position
	local MRegion = Region3.new(MPos - vector,MPos + Vector)
	MRegion = MRegion:ExpandToGrid(4)
	local material = workspace.Terrain:ReadVoxels(region,resolution)
	local size = material.Size
	for x = 1, size.X do
		for y = 1, size.Y do
			for z = 1, size.Z do
				local mat = material[x][y][z]
				if mat == Enum.Material.Mud then
					print("it's mud")
				end
			end
		end
	end
end)

Note that I did not use the array for occupancy for this example, as that has no apparent use for the purpose you are trying to achieve. But remember, ReadVoxel returns both the materials and occupancies arrays.

Reference link:

smooth terrain wiki page

Hopefully this helped you with your problem!

This discussion is preserved as it was. New answers, comments, and votes are closed.