Fluid Animation!
Video:
Functions;
SetAmplitude(Number)
SetAmplitude, determines the “WaveHeight”. Updates real-time.
MaximumColor3fromRGB(Table)
MaximumColor3fromRGB, determines the maximum Color3.fromRGB colour the water can shift to. Updates real-time.
SetMinimumColor3fromRGB(Table)
SetMinimumColor3fromRGB, determines the minimum Color3.fromRGB colour the water can shift to. Updates real-time.
SetParent(Instance)
SetParent, sets the parent of the parts. Does not Update real-time.
SetPartSize(Vector3)
SetPartSize, sets the size of the parts (PartSize.Y works best when it is set the the Amplitude value). Does not Update real-time.
SetSize(Vector3)
SetSize, sets the size of the “Plane” (expect lag with number values larger than 50). Does not Update real-time.
SetSpeed(Number)
SetSpeed, determines the “WaveSpeed” (works best with number values lower than .1). Updates real-time.
CreatePlane()
CreatePlane, this creates a “Plane” where the Fluid Animation will take place. Only needs to be called once, does not update real-time.
Start()
Start, starts the Fluid Animation. Updates real-time.
Pause()
Pause, pauses the Fluid Animation. Updates real-time.
Resume()
Resume, resumes the Fluid Animation. Updates real-time.
Stop()
Stop, stops the Fluid Animation. Updates real-time.
Reset()
Reset, reverses Fluid Animation Table back to its original state. Updates real-time.
Code;
Script:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ModuleScript = ReplicatedStorage.ModuleScript
local FluidAnimation = require(ModuleScript.FluidAnimation)
local Terrain = workspace.Terrain
local Folder = Instance.new("Folder")
Folder.Name = "Fluid Animation"
Folder.Parent = Terrain
local FluidAnimationnew = FluidAnimation.new()
FluidAnimationnew:SetAmplitude(6.25)
FluidAnimation:SetMaximumColor3fromRGB({
Red = 0,
Green = 0,
Blue = 255
})
FluidAnimation:SetMinimumColor3fromRGB({
Red = 0,
Green = 204,
Blue = 153
})
FluidAnimationnew:SetParent(Folder)
FluidAnimationnew:SetPartSize(Vector3.new(6.25, 6.25, 6.25))
FluidAnimationnew:SetSize(Vector3.new(50, 0, 50))
FluidAnimationnew:SetSpeed(.005)
FluidAnimationnew:CreatePlane()
FluidAnimationnew:Start()
ModuleScript:
local HttpService = game:GetService("HttpService")
local RunService = game:GetService("RunService")
local ModuleTable = {}
ModuleTable.__index = ModuleTable
ModuleTable.new = function()
local FluidAnimation = {}
FluidAnimation.Amplitude = 0
FluidAnimation.MaximumColor3fromRGB = nil
FluidAnimation.MinimumColor3fromRGB = nil
FluidAnimation.Motion = 0
FluidAnimation.OffsetXTable = nil
FluidAnimation.OffsetZTable = nil
FluidAnimation.Parent = nil
FluidAnimation.PartOffsetX = 0
FluidAnimation.PartOffsetZ = 0
FluidAnimation.PartSize = nil
FluidAnimation.PartTable = nil
FluidAnimation.Paused = false
FluidAnimation.Size = nil
FluidAnimation.Speed = 0
FluidAnimation.Started = false
FluidAnimation.Stopped = false
setmetatable(FluidAnimation, ModuleTable)
return FluidAnimation
end
ModuleTable.SetAmplitude = function(FluidAnimation, Amplitude)
FluidAnimation.Amplitude = Amplitude
return
end
ModuleTable.SetMaximumColor3fromRGB = function(FluidAnimation, MaximumColor3fromRGB)
FluidAnimation.MaximumColor3fromRGB = MaximumColor3fromRGB
return
end
ModuleTable.SetMinimumColor3fromRGB = function(FluidAnimation, MinimumColor3fromRGB)
FluidAnimation.MinimumColor3fromRGB = MinimumColor3fromRGB
return
end
ModuleTable.SetMotion = function(FluidAnimation, Motion)
FluidAnimation.Motion += Motion
return
end
ModuleTable.SetOffsetXTable = function(FluidAnimation, OffsetXTable)
FluidAnimation.OffsetXTable = OffsetXTable
return
end
ModuleTable.SetOffsetZTable = function(FluidAnimation, OffsetZTable)
FluidAnimation.OffsetZTable = OffsetZTable
return
end
ModuleTable.SetParent = function(FluidAnimation, Parent)
FluidAnimation.Parent = Parent
return
end
ModuleTable.SetPartOffsetX = function(FluidAnimation, PartOffsetX)
FluidAnimation.PartOffsetX = PartOffsetX
return
end
ModuleTable.SetPartOffsetZ = function(FluidAnimation, PartOffsetZ)
FluidAnimation.PartOffsetZ = PartOffsetZ
return
end
ModuleTable.SetPartSize = function(FluidAnimation, PartSize)
FluidAnimation.PartSize = PartSize
return
end
ModuleTable.SetPartTable = function(FluidAnimation, PartTable)
FluidAnimation.PartTable = PartTable
return
end
ModuleTable.SetPaused = function(FluidAnimation, Paused)
FluidAnimation.Paused = Paused
return
end
ModuleTable.SetSize = function(FluidAnimation, Size)
FluidAnimation.Size = Size
return
end
ModuleTable.SetSpeed = function(FluidAnimation, Speed)
FluidAnimation.Speed = Speed
return
end
ModuleTable.SetStarted = function(FluidAnimation, Started)
FluidAnimation.Started = Started
return
end
ModuleTable.SetStopped = function(FluidAnimation, Stopped)
FluidAnimation.Stopped = Stopped
return
end
ModuleTable.CreatePlane = function(FluidAnimation)
local Parent = FluidAnimation.Parent
local PartSize = FluidAnimation.PartSize
local PartTable = {}
local Size = FluidAnimation.Size
for Number = -Size.X / 2, Size.X / 2 do
for Number2 = -Size.Z / 2, Size.Z / 2 do
local Part = Instance.new("Part")
Part.Name = HttpService:GenerateGUID(true)
Part.CFrame = CFrame.new(Number * PartSize.X, 0, Number2 * PartSize.Z)
Part.Anchored = true
Part.Size = PartSize
Part.Parent = Parent
PartTable[Number .. "." .. Number2] = Part
end
end
FluidAnimation:SetPartTable(PartTable)
return
end
local Color3fromRGBLerp = function(Number, Minimum, Maximum)
local Color3fromRGBTable = {}
table.insert(Color3fromRGBTable, Maximum.Red + (Minimum.Red - Maximum.Red) * Number)
table.insert(Color3fromRGBTable, Maximum.Green + (Minimum.Green - Maximum.Green) * Number)
table.insert(Color3fromRGBTable, Maximum.Blue + (Minimum.Blue - Maximum.Blue) * Number)
return Color3.fromRGB(Color3fromRGBTable[1], Color3fromRGBTable[2], Color3fromRGBTable[3])
end
local BoundNumber = function(Number, Minimum, Maximum)
return (-Maximum + Number) / (-Maximum / Minimum)
end
ModuleTable.Start = function(FluidAnimation)
local PartSize = FluidAnimation.PartSize
local PartTable = FluidAnimation.PartTable
local Size = FluidAnimation.Size
local Started = FluidAnimation.Started
local Stopped = FluidAnimation.Stopped
if Started then
return
else
FluidAnimation:SetStarted(true)
end
if Stopped then
FluidAnimation:SetStopped(false)
end
RunService:BindToRenderStep("FluidAnimation", Enum.RenderPriority.First.Value, function()
local Amplitude = FluidAnimation.Amplitude
local MaximumColor3fromRGB = FluidAnimation.MaximumColor3fromRGB
local MinimumColor3fromRGB = FluidAnimation.MinimumColor3fromRGB
local Paused = FluidAnimation.Paused
local Speed = FluidAnimation.Speed
if Paused then
return
else
FluidAnimation:SetMotion(Speed)
FluidAnimation:SetOffsetXTable({
OffsetX = FluidAnimation.Motion,
OffsetX2 = -FluidAnimation.Motion,
OffsetX3 = 0,
OffsetX4 = 0,
OffsetX5 = 0
})
for Number = -Size.X / 2, Size.X / 2 do
FluidAnimation:SetOffsetZTable({
OffsetZ = 0,
OffsetZ2 = 0,
OffsetZ3 = 0,
OffsetZ4 = FluidAnimation.Motion,
OffsetZ5 = -FluidAnimation.Motion
})
for Number2 = -Size.Z / 2, Size.Z / 2 do
local Part = PartTable[Number .. "." .. Number2]
if Part ~= nil then
local MathNoise = Amplitude * math.noise(FluidAnimation.OffsetXTable.OffsetX, FluidAnimation.OffsetZTable.OffsetZ)
local MathNoise2 = Amplitude * math.noise(FluidAnimation.OffsetXTable.OffsetX2, FluidAnimation.OffsetZTable.OffsetZ2)
local MathNoise3 = Amplitude * math.noise(FluidAnimation.OffsetXTable.OffsetX3, FluidAnimation.OffsetZTable.OffsetZ3)
local MathNoise4 = Amplitude * math.noise(FluidAnimation.OffsetXTable.OffsetX4, FluidAnimation.OffsetZTable.OffsetZ4)
local MathNoise5 = Amplitude * math.noise(FluidAnimation.OffsetXTable.OffsetX5, FluidAnimation.OffsetZTable.OffsetZ5)
local Height = MathNoise + MathNoise2 + MathNoise3 + MathNoise4 + MathNoise5
Part.Color = Color3fromRGBLerp(BoundNumber(Part.CFrame.Position.Y / PartSize.Y / Amplitude, -5, 5), MinimumColor3fromRGB, MaximumColor3fromRGB)
Part.CFrame = CFrame.new((FluidAnimation.PartOffsetX + Number) * PartSize.X, Amplitude + Height + PartSize.Y, (FluidAnimation.PartOffsetX + Number2) * PartSize.Z)
end
FluidAnimation:SetOffsetZTable({
OffsetZ = FluidAnimation.OffsetZTable.OffsetZ + .01,
OffsetZ2 = FluidAnimation.OffsetZTable.OffsetZ2 + .025,
OffsetZ3 = FluidAnimation.OffsetZTable.OffsetZ3 + .050,
OffsetZ4 = FluidAnimation.OffsetZTable.OffsetZ4 + .075,
OffsetZ5 = FluidAnimation.OffsetZTable.OffsetZ5 + .1
})
end
FluidAnimation:SetOffsetXTable({
OffsetX = FluidAnimation.OffsetXTable.OffsetX + .01,
OffsetX2 = FluidAnimation.OffsetXTable.OffsetX2 + .025,
OffsetX3 = FluidAnimation.OffsetXTable.OffsetX3 + .050,
OffsetX4 = FluidAnimation.OffsetXTable.OffsetX4 + .075,
OffsetX5 = FluidAnimation.OffsetXTable.OffsetX5 + .1
})
end
end
end)
end
ModuleTable.Pause = function(FluidAnimation)
local Paused = FluidAnimation.Paused
if Paused then
return
else
FluidAnimation:SetPaused(true)
end
end
ModuleTable.Resume = function(FluidAnimation)
local Paused = FluidAnimation.Paused
if Paused then
FluidAnimation:SetPaused(false)
else
return
end
end
ModuleTable.Stop = function(FluidAnimation)
local Started = FluidAnimation.Started
local Stopped = FluidAnimation.Stopped
if Started then
FluidAnimation:SetStarted(false)
else
return
end
if Stopped then
return
else
FluidAnimation:SetStopped(true)
end
RunService:UnbindFromRenderStep("FluidAnimation")
FluidAnimation:SetMaximumColor3fromRGB(nil)
FluidAnimation:SetMinimumColor3fromRGB(nil)
FluidAnimation:SetMotion(0)
FluidAnimation:SetOffsetXTable(nil)
FluidAnimation:SetOffsetZTable(nil)
return
end
ModuleTable.Reset = function(FluidAnimation)
FluidAnimation:SetAmplitude(0)
FluidAnimation:SetMaximumColor3fromRGB(nil)
FluidAnimation:SetMinimumColor3fromRGB(nil)
FluidAnimation:SetMotion(0)
FluidAnimation:SetOffsetXTable(nil)
FluidAnimation:SetOffsetZTable(nil)
FluidAnimation:SetParent(nil)
FluidAnimation:SetPartOffsetX(0)
FluidAnimation:SetPartOffsetZ(0)
FluidAnimation:SetPartSize(nil)
FluidAnimation:SetPartTable(nil)
FluidAnimation:SetPaused(false)
FluidAnimation:SetSize(nil)
FluidAnimation:SetSpeed(0)
FluidAnimation:SetStarted(false)
FluidAnimation:SetStopped(false)
return
end
return ModuleTable
Place File
Fluid Animation.rbxl (25.0 KB)
Updates;
Color3.fromRGB Shifting
With some help from @CoderHusk I have been able to interpret and Color3.fromRGB instead of a Color3.new. Interpolation is based on the part height. Very Smooth.
Improved Lag:
By creating a whole new script and transforming it into a “ModuleScript”, I have exponentially decreased the lag. Although Size.X and Size.Z values over 50 still, regrettably, cause lag.
Remade and Re-modeled:
I have entirely re-modeled “Water Simulation” into “Fluid Animation”, making it easier-to-use and more customizable.