When it comes to terrain, it is kinda weird because I know I can’t tween it, but would there be another way in which i could make TERRAIN water rise up? Without creating parts and converting them to terrain of course
For your application are you able to sink the non-terrain environment down into the water instead? It’s the cleanest way I’ve found to flood interior environments.
that’s exactly the issue
-
the main map is in terrain
-
the players would fall, they wouldnt go down in a smooth way ( i guess )
Unfortunately terrain water does not scale properly in the Y direction occupancy only works in X and Z. So you will get 4 stud jumps.
I recommend using flood fill algorithm for this. Here it is:
local mouse = game.Players.LocalPlayer:GetMouse()
local terrain = game.Workspace.Terrain
local function checkDirection(origin, direction)
local ray = Ray.new(origin, direction)
local part, point, normal = game.Workspace:FindPartOnRay(ray, nil, true)
return part
end
local function processDirection(queue, processed, current, direction)
local nextNode = current + direction
if not processed[tostring(nextNode)] then
table.insert(queue, nextNode)
end
end
local function floodFill(voxelPos)
local region = Region3.new(voxelPos - Vector3.new(2,2,2), voxelPos + Vector3.new(2,2,2))
local material, occupancy = terrain:ReadVoxels(region, 4)
if material[1][1][1] ~= Enum.Material.Air then
print("Could not fill from that voxel: Voxel not empty")
return
end
local queue = {}
local processed = {}
local success = true
table.insert(queue, voxelPos)
while #queue > 0 do
local current = table.remove(queue)
region = Region3.new(current - Vector3.new(2,2,2), current + Vector3.new(2,2,2))
material, occupancy = terrain:ReadVoxels(region, 4)
if material[1][1][1] == Enum.Material.Air then
if checkDirection(current, Vector3.new(1000, 0, 0)) and
checkDirection(current, Vector3.new(-1000, 0, 0)) and
checkDirection(current, Vector3.new(0, 0, 1000)) and
checkDirection(current, Vector3.new(0, 0, -1000)) and
checkDirection(current, Vector3.new(0, -1000, 0)) then
processed[tostring(current)] = current
processDirection(queue, processed, current, Vector3.new(4,0,0))
processDirection(queue, processed, current, Vector3.new(-4,0,0))
processDirection(queue, processed, current, Vector3.new(0,0,4))
processDirection(queue, processed, current, Vector3.new(0,0,-4))
processDirection(queue, processed, current, Vector3.new(0,-4,0))
else
processed = {}
success = false
break
end
end
end
if success then
for _, position in pairs(processed) do
region = Region3.new(position - Vector3.new(2,2,2), position + Vector3.new(2,2,2))
material[1][1][1] = Enum.Material.Water
occupancy[1][1][1] = 1
terrain:WriteVoxels(region, 4, material, occupancy)
end
else
print("Could not fill from that voxel: Would create infinite fill")
end
end
local function round(num)
return math.floor(num + .5)
end
mouse.Button1Up:Connect(function()
local hit = mouse.Hit
local x = round(mouse.Hit.p.X)
x = x - x%4 + 2
local y = round(mouse.Hit.p.Y)
y = y - y%4 + 2
local z = round(mouse.Hit.p.Z)
z = z - z%4 + 2
floodFill(Vector3.new(x, y, z))
end)
This is an old basic flood fill implementation. This particular flood fill algorithm needs to have terrain borders in order to work. Or you could modify it so that it only checks voxels in a given range.
Simply cann the flood fill function whilst rising the Y position of the flood fill make sure it is surrounded by terrain or it won’t work.
thanks for the solution, i do think i’ll still use blocks lol
Uhm I know this post is older, but I have an alternative solution which moves sections of terrain, it is very weird looking due to the voxel grid of 4x4x4