I have been working on some code for a game I’m making which makes a part with minor wind physics and it works ok but keeps getting glitchy.
here is the code
--[[
Explaination on how to create the movement physics for a part by bettercat4
]]
--[[
Reflection formula
r = d - 2(d ⋅ n)n
Where ‘r’ is the resultant reflection normal, ‘d’ is the normal of
our ray, and ‘n’ is the surface normal that our ray hit
(n will be the value FindPartOnRay returns).
]]
--[[
to calculate the air resistance we need to direct a force that
pushes the part in a direction that is perpendicular to the force,
reflected off of the face.
we need to fire a ray from the negative move direction to the
part and calculate the reflection of the result and use a vector
force to move the part in the opposite direction of the reflection.
The force should be equal to about either two times the velocity,
or equal to the velocity, or half of the velocity.
]]
local part = script.Parent
local pos1 = part.Position
local p1x = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.X))
local p1y = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.Y))
local p1z = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.Z))
local pos2 = part.Position
local p2x = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.X))
local p2y = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.Y))
local p2z = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.Z))
local pos3 = Vector3.new(p1x,p1y,p1z)
local pos4 = Vector3.new(p2x,p2y,p2z)
game:GetService("RunService").Heartbeat:Connect(function()
local vel = part.Velocity
local raystartpos = part.Position + (vel.Unit*100)
local endpoint = part.Position
local startpoint = raystartpos
local distance = 200
local direction = ((endpoint - startpoint).Unit) * distance
local normal = -(vel.Unit)
local raycastparams = RaycastParams.new()
raycastparams.FilterType = Enum.RaycastFilterType.Whitelist
raycastparams.IgnoreWater = true
raycastparams.FilterDescendantsInstances = {part}
local ray = workspace:Raycast(raystartpos,direction,raycastparams)
--local ray2 = Ray.new(raystartpos,-(vel.Unit) * 500)
--local hit, position, surfaceNormal = game.Workspace:FindPartOnRay(ray2) -- Cast ray
if ray then
local hit = ray.Instance
local position = ray.Position
local surfaceNormal = ray.Normal
-- Get the reflected normal: (this is the formula applied)
local ReflectedNormal = (direction - (2 * direction:Dot(surfaceNormal) * surfaceNormal))
-- Override our current normal with the reflected one:
-- normal = reflectedNorma
local resistance = (math.pi*part:GetMass())/2
local vector = part.VectorForce
vector.Force = -(ReflectedNormal.Unit * vel.Magnitude*(part:GetMass()+resistance))
end
if part.AssemblyLinearVelocity.Magnitude > 10000 then
part.Anchored = true
part.AssemblyLinearVelocity = Vector3.new(0,0,0)
part.AssemblyAngularVelocity = Vector3.new(0,0,0)
part.VectorForce.Force = Vector3.new(0,0,0)
end
--[[pos1 = part.Position
p1x = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.X))
p1y = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.Y))
p1z = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.Z))
pos3 = Vector3.new(p1x,p1y,p1z)
if pos3.Unit ~= pos4.Unit then
print("move")
print(pos3)
print(pos4)
local direction = pos3 - pos4
local direction2 = direction.Unit
local speed = direction.Magnitude
local Raystartpos = part.Position + direction2
local part = Instance.new("Part",workspace)
part.Anchored = true
part.CanCollide = false
part.Position = Raystartpos
wait(.1)
part:Destroy()
--local Raycast = workspace:Raycast(Raystartpos,)
pos2 = part.Position
p2x = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.X))
p2y = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.Y))
p2z = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.Z))
pos4 = Vector3.new(p2x,p2y,p2z)
end]]
end)
--[[while wait() do
local vel = part.Velocity
local raystartpos = part.Position + (vel.Unit*100)
local endpoint = part.Position
local startpoint = raystartpos
local distance = 200
local direction = ((endpoint - startpoint).Unit) * distance
local normal = -(vel.Unit)
local raycastparams = RaycastParams.new()
raycastparams.FilterType = Enum.RaycastFilterType.Whitelist
raycastparams.IgnoreWater = true
raycastparams.FilterDescendantsInstances = {part}
local ray = workspace:Raycast(raystartpos,direction,raycastparams)
--local ray2 = Ray.new(raystartpos,-(vel.Unit) * 500)
--local hit, position, surfaceNormal = game.Workspace:FindPartOnRay(ray2) -- Cast ray
if ray then
local hit = ray.Instance
local position = ray.Position
local surfaceNormal = ray.Normal
-- Get the reflected normal: (this is the formula applied)
local ReflectedNormal = (direction - (2 * direction:Dot(surfaceNormal) * surfaceNormal))
-- Override our current normal with the reflected one:
-- normal = reflectedNorma
local resistance = 50
local vector = part.VectorForce
vector.Force = -(ReflectedNormal.Unit * vel.Magnitude*(part:GetMass()+(game.Workspace.Gravity/2)))
end
--[[pos1 = part.Position
p1x = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.X))
p1y = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.Y))
p1z = tonumber(string.format("%." .. (3 or 0) .. "f", pos1.Z))
pos3 = Vector3.new(p1x,p1y,p1z)
if pos3.Unit ~= pos4.Unit then
print("move")
print(pos3)
print(pos4)
local direction = pos3 - pos4
local direction2 = direction.Unit
local speed = direction.Magnitude
local Raystartpos = part.Position + direction2
local part = Instance.new("Part",workspace)
part.Anchored = true
part.CanCollide = false
part.Position = Raystartpos
wait(.1)
part:Destroy()
--local Raycast = workspace:Raycast(Raystartpos,)
pos2 = part.Position
p2x = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.X))
p2y = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.Y))
p2z = tonumber(string.format("%." .. (3 or 0) .. "f", pos2.Z))
pos4 = Vector3.new(p2x,p2y,p2z)
end]]
--end
how it works is it is supposed to fire a raycast from the negative velocity direction and use a vectorforce to move it in the negative direction of the mirror of that raycast. I used a bullet reflection formula for making the mirror raycast and it seems to work ok at first but sometimes it seems to gather too much velocity eventually and then it goes crazy and starts to fly around everywhere.
also dont mind the part clipping through the ground and the other two parts i clicked on were examples of other failed versions. (2 of about 26 failed versions) I have tried using multiple other modules made by people with no avail and idk what to do now.
also the code is located inside of a part in the workspace with a vectorforce and attachment in it.