Animated Ocean System [HELP]

It’s supposed loop through 6 different models on a grid to give it an animated look. It however does not do this. Any ideas on what I’m doing wrong?

Script:

-- Services --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")

-- Ocean Templates Folder --
local oceanFolder = ReplicatedStorage:WaitForChild("OceanTemplates")

-- Starter Part --
local starterPart = Workspace:WaitForChild("StarterPart")

-- Configuration --
local sizeX = 24
local sizeZ = 24
local oceanHeight = starterPart.Position.Y
local loadedPositions = {}
local frameDuration = 0.25

-- Generate Ocean Model --
local function generateOceanModel(x, z)
	local position = Vector3.new(x * sizeX, oceanHeight, z * sizeZ)
	local oceanPart = oceanFolder:WaitForChild("Ocean1_1"):Clone()
	oceanPart:PivotTo(CFrame.new(position))
	oceanPart.Parent = Workspace

	task.spawn(function()
		local frame = 1
		while true do
			local oceanModelName = "Ocean1_" .. frame
			local nextModel = oceanFolder:WaitForChild(oceanModelName)
			if nextModel then
				local newPart = nextModel:Clone()
				newPart:PivotTo(oceanPart.CFrame)
				newPart.Parent = oceanPart.Parent
				oceanPart:Destroy()
				oceanPart = newPart
			end
			task.wait(frameDuration)
			frame = (frame % 6) + 1 -- Loop through Ocean1_1 to Ocean1_6
		end
	end)
end

-- Generate Ocean Grid --
local function generateOceanGrid()
	for z = -100, 100 do
		for x = -100, 100 do
			local key = tostring(x) .. "_" .. tostring(z)
			if not loadedPositions[key] then
				generateOceanModel(x, z)
				loadedPositions[key] = true
			end
		end
	end
end

-- Start Generating Ocean --
generateOceanGrid()

The script is in ServerScriptService

1 Like

This sure seems like it should work. Are you sure the function inside task.spawn is starting? is nextModel ever nil?
Whether it works or not, I’d recommend reworking it so all the models are updated from one thread (not one thread per tile). There is a significant cost associated with additional threads, since each time the Lua context needs saved then restored.

1 Like

I got this script and it loads the first model but it doesn’t disappear or load any of the other ones:

-- Services --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")

-- Ocean Templates Folder --
local oceanFolder = ReplicatedStorage:WaitForChild("OceanTemplates")

-- Starter Part --
local starterPart = Workspace:WaitForChild("StarterPart")

-- Configuration --
local sizeX = 24
local sizeZ = 24
local oceanHeight = starterPart.Position.Y
local frameDuration = 0.25
local loadedPositions = {}

-- List of ocean models --
local oceanModels = {
	"Ocean1_1",
	"Ocean1_2",
	"Ocean1_3",
	"Ocean1_4",
	"Ocean1_5",
	"Ocean1_6"
}

-- Generate Ocean Model --
local function generateOceanModel(x, z)
	local position = Vector3.new(x * sizeX, oceanHeight, z * sizeZ)
	local oceanPart = oceanFolder:WaitForChild(oceanModels[1]):Clone()
	oceanPart:PivotTo(CFrame.new(position))
	oceanPart.Parent = Workspace

	task.spawn(function()
		local frame = 1
		while true do
			local oceanModelName = oceanModels[frame]
			local nextModel = oceanFolder:WaitForChild(oceanModelName)

			if nextModel then
				local newPart = nextModel:Clone()
				newPart:PivotTo(oceanPart.CFrame)
				newPart.Parent = oceanPart.Parent
				oceanPart:Destroy() -- Destroy the old model
				oceanPart = newPart -- Replace with the new part
			end

			task.wait(frameDuration) -- Wait before switching to the next model
			frame = (frame % #oceanModels) + 1 -- Loop through Ocean1_1 to Ocean1_6
		end
	end)
end

-- Generate Ocean Grid --
local function generateOceanGrid()
	for z = -5, 5 do
		for x = -5, 5 do
			local key = tostring(x) .. "_" .. tostring(z)
			if not loadedPositions[key] then
				generateOceanModel(x, z)
				loadedPositions[key] = true
			end
		end
	end
end

-- Start Generating the Ocean --
generateOceanGrid()

I got a working one but now I’m trying to make it so it loads and unloads based on the characters position:

-- Services --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")

-- Ocean Templates Folder --
local oceanFolder = ReplicatedStorage:WaitForChild("OceanTemplates")

-- Starter Part --
local starterPart = Workspace:WaitForChild("StarterPart")

-- Configuration --
local sizeX = 24
local sizeZ = 24
local oceanHeight = starterPart.Position.Y
local frameDuration = 0.25
local loadedPositions = {}

-- List of ocean models --
local oceanModels = {
	"Ocean1_1",
	"Ocean1_2",
	"Ocean1_3",
	"Ocean1_4",
	"Ocean1_5",
	"Ocean1_6"
}

-- Helper function to set transparency for all parts in a model
local function setModelTransparency(model, transparency)
	for _, descendant in ipairs(model:GetDescendants()) do
		if descendant:IsA("BasePart") then
			descendant.Transparency = transparency
		end
	end
end

-- Generate Ocean Model --
local function generateOceanModel(x, z)
	local position = Vector3.new(x * sizeX, oceanHeight, z * sizeZ)

	-- Preload all models at the same position
	local preloadedModels = {}
	for _, modelName in ipairs(oceanModels) do
		local model = oceanFolder:WaitForChild(modelName):Clone()
		model:PivotTo(CFrame.new(position))
		model.Parent = Workspace
		setModelTransparency(model, 1) -- Start as invisible
		table.insert(preloadedModels, model)
	end

	-- Animation loop to switch transparency
	task.spawn(function()
		local frame = 1
		while true do
			-- Set all models to transparent
			for _, model in ipairs(preloadedModels) do
				setModelTransparency(model, 1)
			end

			-- Make the current frame's model visible
			setModelTransparency(preloadedModels[frame], 0)

			-- Increment and loop through the model list correctly
			frame = frame + 1
			if frame > #oceanModels then
				frame = 1 -- Reset to the first model
			end

			-- Wait for the frame duration before switching again
			task.wait(frameDuration)
		end
	end)
end

-- Generate Ocean Grid --
local function generateOceanGrid()
	for z = -10, 10 do  -- Increased the range here for more waves
		for x = -10, 10 do  -- Increased the range here for more waves
			local key = tostring(x) .. "_" .. tostring(z)
			if not loadedPositions[key] then
				generateOceanModel(x, z)
				loadedPositions[key] = true
			end
		end
	end
end

-- Start Generating the Ocean --
generateOceanGrid()

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.