I want to get the CellMaterial of a smooth terrain region, but using Terrain::ReadVoxels is only returning “Enum.Material.Slate” no matter which CellMaterial the region is. I also thought Enum.Material was for BaseParts except for Terrain, which has me scratching my head.
Is this intended? I don’t see any other way to get CellMaterial from smooth terrain, so if someone could point me in the right direction that’d be great. Thanks.
Alright, I managed to find Terrain::GetCell but it appears deprecated without a successor, and it’s also - from what I can tell using it - rather unreliable.
Does anyone know if there’s either a better way or a better way coming soon?
I tried Terrain:ReadVoxels() and it printed correct materials. How exactly are you getting the material? Do you have a 4x4x4 stud gridaligned region that you give to the ReadVoxels function or do you do it differently?
I copy/pasted the code from here but was reading a 2x2x2 region (specifically, directly in front of my characters head). Was trying to detect Enum.CellMaterial.Water but the ‘materials’ table only contained Enum.Material.Slate. I was scratching my head because no parts contain that material in my game
The original code is deleted, but it was along the lines of
local cast = (head.CFrame * CFrame.new(0, 0, (-head.Size.Z / 2) - 0.15)).p;
local ray = workspace:Raycast(head.Position, cast);
local offset = Vector3.new(1.5, 1.5 1.5);
local ray_pos = ray.Position;
local region = Region3.new(ray_pos - offset, ray_pos + offset):ExpandToGrid(4);
-- then readvoxels w/ region
I imagine if I messed up anywhere it’d be creating the region because the raycast works, but it doesn’t explain why I wasn’t getting an Enum.CellMaterial value back. How is Enum.Material useful when reading smooth terrain?
I made a function that you can use to create a gridAligned, 4x4x4 stud region. The region can then be given to :ReadVoxels(). I think you could do something like this.
local function round(n, divBy)
local mod = n % divBy
if mod < divBy/2 then
return n-mod
else return n+(divBy-mod)
end
end
local function getCellCenter(pos)
local xm, ym, zm = pos.X < 0 and -1 or 1, pos.Y < 0 and -1 or 1, pos.Z < 0 and -1 or 1
local vectorToRound = Vector3.new(math.abs(pos.X), math.abs(pos.Y), math.abs(pos.Z))-Vector3.new(2, 2, 2)
local positiveCenter = Vector3.new(round(vectorToRound.X, 4), round(vectorToRound.Y, 4), round(vectorToRound.Z, 4))+Vector3.new(2, 2, 2)
local actualCenter = positiveCenter*Vector3.new(xm, ym, zm)
return actualCenter
end
local function make4x4x4GridRegion(pos)
local cellCenter = getCellCenter(pos)
return Region3.new(cellCenter-Vector3.new(2, 2, 2), cellCenter+Vector3.new(2, 2, 2))
end
local cast = -- try giving this the same value you gave it before, it might work
local region = make4x4x4GridRegion(cast)
-- use ReadVoxels with the region