So, after some deeper research and tries to understand what’s wrong, I understood what I did wrong and what you was telling me:
So, in some cases, droplet can be too close to wall with my old check so it will detect only blocking wall, ignoring lower one. (Previous check checked base velocity and velocity + gravity. So it was worst method I had ever tbh, bc limit of this was 2 walls)
So, I rescripted detection method a bit:
local Droplet = Droplets[i]
local StartVelocity = Droplet.Velocity
SurfaceParams.FilterDescendantsInstances = Droplets
local Normals = {}
local function TestVelocity(Start, Velocity)
local VelocityGrav = Velocity - Vector3.new(0, Gravity * CurDelay, 0)
local Offset = VelocityGrav.Unit / 20
local RayStart = -Offset + Start
local RayDirection = VelocityGrav + Offset
local Result = workspace:Raycast(RayStart, RayDirection, SurfaceParams)
local RaycastDistanceTarget = (VelocityGrav.Magnitude + Offset.Magnitude) * CurDelay + 0.05
local ResultSucceed = Result and Result.Distance <= RaycastDistanceTarget and 2 or Result and 1 or 0
local Distance = math.huge
if ResultSucceed == 2 then
if #Normals > 100 then
error("TOO MANY NORMALS")
else
local found = false
for i = 1, #Normals, 1 do
if Normals[i]:FuzzyEq(Result.Normal, 0.001) then
found = true
break
end
end
if not found then
table.insert(Normals, Result.Normal)
local Normal = Normals[1]
for i = 2, #Normals, 1 do
Normal += Normals[i]
end
Distance = Result.Distance
Normal = Normal.Unit
local NextVelocity = Velocity - Velocity:Dot(Normal) * Normal
local PreDistance = TestVelocity(Start, NextVelocity)
Distance = PreDistance ~= math.huge and PreDistance or Distance
end
end
end
return Distance
end
local Distance = TestVelocity(Droplet.Position, StartVelocity)
local Velocity = StartVelocity - Vector3.new(0, Gravity * CurDelay, 0)
local PossibleMovement = Velocity * CurDelay
local Normal = Normals[1]
if #Normals > 0 then
for i = 2, #Normals, 1 do
Normal += Normals[i]
end
Normal = Normal.Unit
local NewVelocity = (Velocity - Velocity:Dot(Normal) * Normal)-- * Friction
local DistanceProportion = math.min(Distance / NewVelocity.Magnitude, 1) * 0.99
Velocity = (Velocity * (0.99 - DistanceProportion) + NewVelocity * (0.01 + DistanceProportion)) * Friction
PossibleMovement = Velocity * CurDelay
Velocity = NewVelocity * Friction
end
And also I found small bug which goes in action when you detect surface. So, there’s previous and reflection velocities. If surface detected, 100% power will go to reflect velocity. On big speeds this can result in hitting mid-air. And I tried to fix this one too. But failed - again due to clipping problems.