I am trying to detect the type of smooth terrain under a part. I have tried to find a way to do this with little success. Researching it didn’t provide many solutions.
How would I achieve this?
I am trying to detect the type of smooth terrain under a part. I have tried to find a way to do this with little success. Researching it didn’t provide many solutions.
How would I achieve this?
I thought that’d be the best way. However, it would always return Enum.Material.Air. Perhaps it is due to me being new with regions. what would be the easiest way to make a region perhaps ~1 stud under the part to read the terrain underneath it?
I believe this could be done by doing something like this: (Region3 Under a Part)
local part = ----part
local StudsUnder = 1
local region = Region3.new((part.Position - Vector3.new(0, StudsUnder, 0)) - (part.Size/2), (part.Position - Vector3.new(0, StudsUnder, 0)) + (Part.Size/2)
You could raycast downwards by making the direction negative UpVector, then using FindPartOnRay read the Material it returns:
local part = workspace.Part
local ray = Ray.new(part.Position, -workspace.Part.UpVector * math.huge)
local foundPart, foundPosition, foundMaterial = workspace:FindPartOnRay(ray, Part, true)
since roblox terrain is locked to a 4x4x4 voxel grid, you’d need a region compatible with that size, Region3 on wiki has a function called :ExpandToGrid(), scroll down to the bottom it even has an example of use.
generally creating a vector3 with a position and size has it’s formula: RegionCorner1 = Position + Size/2
and RegionCorner2 = Position - Size/2
, then maybe use :ExpandToGrid() to make it snap to the terrains size, then read the material from there.
@return_end1
You could raycast downwards by making the direction negative UpVector, then using FindPartOnRay read the Material it returns
i think you’d need to enable terrain cells are cubes or something when raycasting, i doubt it would just work on terrain i remember some parameter about it…
Ah good point, I searched it up and found it was the third argument of FindPartOnRay as a boolean.
I’ve updated my code.
I tried that but it only returns plastic as the material. I think that regions might be the only route
Where is the part in relation to the terrain? A downcast should return the material of the current section of Terrain it’s on unless the part is right on the terrain in which you may need to offset the raycast further up. If it isn’t doing that, I suspect it’s either to do with the code or the setup. If neither is the case, then that’s strange behaviour to be looked into.
The part is directly above, on top of the terrain. Either the ray glitches through the terrain, or, as I believe I read somewhere, using .Material on Terrain returns it being plastic.
The material of the Terrain object is technically undefined because it is just a facilitator object for working with terrain. When it comes to terrain, you actually need to work in respect to its voxels or a raycast that finds the material of the item it hit from the third return value.
What I don’t quite understand is why it doesn’t allow you to just downcast. Try casting directly down again at the part’s position and instead of the DownVector (negative UpVector), just a hard-coded amount of studs downward. A negative UpVector expanded by math.huge is expensive and probably not a good idea anyway.
local part = workspace.Part
local ray = Ray.new(part.Position, Vector3.new(0, -10, 0))
local _, _, _, material = workspace:FindPartOnRayWithWhitelist(ray, {workspace.Terrain})
print(material)
This works for me. I put a part right on top of grass and it gave me the Grass material. Put it on some rocky mountains, gave me the Rock material.
@Wingboy0 That argument does nothing. TerrainCellsAreCubes is an artifact of legacy terrain where terrain was done in 4x4 blocks. Turning it on or off will not change how the cast works anymore and it in fact has been removed from the API (it’s visibility has, at the very least).
@return_end1 The material is the fourth return of ray functions, not the third. As for the third argument that Wingboy0 mentioned, that is to ignore water.
Thank you so much man, it actually works! I don’t know if I am just bad at researching things or what, but this is the first thing that actually worked.