Terrain Water going up

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

2 Likes

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.

2 Likes

that’s exactly the issue

  1. the main map is in terrain

  2. 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.

1 Like

thanks for the solution, i do think i’ll still use blocks lol

1 Like

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

1 Like