Hey. So I have been trying to make a realistic rain system (which collisions and splash particles). Currently, the framerate drops a bit when using this system (compared to just using particles as rain)
How can improve this?
local RainRadiusX = 80 -- Left, Right
local RainRadiusZ = 70 -- Forward, Back
local MaxRainDistance = 800 -- How far the drops can travel
local RainSpeed = 300
local Rate = 15
local CurrentMaxRainCount = 400 -- Stop the rain from creating more drops than it can destroy.
local RainOffsetZ = 30
local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Whitelist
local Gamesettings = UserSettings().GameSettings
local RS = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Terrain = workspace.Terrain
local RainPartsFolder = Instance.new("Folder")
RainPartsFolder.Name = "RainContent"
RainPartsFolder.Parent = workspace
local RainPartTemplate = Instance.new("Part")
RainPartTemplate.Material = Enum.Material.SmoothPlastic
RainPartTemplate.Color = Color3.fromRGB(255, 255, 255)
RainPartTemplate.Size = Vector3.new(0.1, 5, 0.1)
RainPartTemplate.Transparency = 0.9
RainPartTemplate.CanCollide = false
RainPartTemplate.CanTouch = false
RainPartTemplate.CastShadow = false
RainPartTemplate.Anchored = true
RainPartTemplate.Name = "RainPart"
local SplashPart = Instance.new("Part")
SplashPart.Size = Vector3.new(0.1, 0.1, 0.1)
SplashPart.Transparency = 1
SplashPart.CanCollide = false
RainPartTemplate.CastShadow = false
SplashPart.Anchored = true
SplashPart.CanTouch = false
SplashPart.Name = "RainSplashPart"
SplashPart.Parent = RainPartsFolder
local SplashParticle = script.SplashEffect:Clone()
SplashParticle.Parent = SplashPart
local AbsorbantMaterials = { -- Materials that don't create the rain splash effect
Enum.Material.Grass,
Enum.Material.Fabric,
Enum.Material.Sand,
}
local DeltaTime = 0
local RainDeltaIncrement = RainSpeed
local WhiteListIndex = 0
local Whitelist = {}
local function SetupWhitelist(InstanceToSearch)
for i, child in ipairs(InstanceToSearch:GetChildren()) do
if child:IsA("BasePart") and child.CanCollide and child.Transparency < 1 then
WhiteListIndex = WhiteListIndex + 1
table.insert(Whitelist, WhiteListIndex, child) -- Add the part to the whitelist
else
SetupWhitelist(child) -- Continue searching for baseparts
end
end
end
function CastRain()
Params.FilterDescendantsInstances = Whitelist
if #RainPartsFolder:GetChildren() <= CurrentMaxRainCount then
local RainOrigin = (game.Workspace.CurrentCamera.CFrame * CFrame.new(0, 0, -RainOffsetZ)).Position + Vector3.new(0, math.random(100, 120), 0)
local RandomPosition = RainOrigin + Vector3.new(math.random(-RainRadiusX/2, RainRadiusX/2), 0, math.random(-RainRadiusZ/2, RainRadiusZ/2))
local Direction = Vector3.new(0, -MaxRainDistance, 0)
local RainRay = workspace:Raycast(RandomPosition, Direction, Params)
if RainRay then
local HitPos = RainRay.Position
local Dist = (RainOrigin - HitPos).Magnitude
-- Create the rain drop
local RainPart = RainPartTemplate:Clone()
RainPart.Position = RandomPosition
RainPart.Parent = RainPartsFolder
-- Move the rain drop until it hits the surface
repeat
RS.RenderStepped:Wait()
RainPart.Position = RainPart.Position - Vector3.new(0, RainDeltaIncrement, 0)
until RainPart.Position.Y <= HitPos.Y
-- Create the splash effect
if not table.find(AbsorbantMaterials, RainRay.Instance.Material) and RainRay.Instance.CanCollide then
SplashPart.Position = HitPos
SplashParticle:Emit(1)
end
RainPart:Destroy()
end
end
end
local function CheckQuality()
local Quality = Gamesettings.SavedQualityLevel.Value
if Quality == 10 then
Rate = 15
elseif Quality >= 8 then
Rate = 10
elseif Quality >= 5 then
Rate = 6
else
Rate = 3
end
end
Gamesettings.Changed:Connect(CheckQuality)
RS.RenderStepped:Connect(function(step)
for i = 1, Rate do
CastRain()
RainDeltaIncrement = RainSpeed * step
DeltaTime = step
end
end)
SetupWhitelist(workspace)
CheckQuality()