How to make a small part with air resistance/drag

How do I make a part that acts like there is air around it?

I have been looking for a way to make a plane wing for my building game, but nothing I have found or tried so far has worked

I found multiple air-resistance scripts to use and they appeared to work but don’t work when I insert them into my part. I am trying to make a game similar to @madattak’s plane crazy, and I found out how he made his plane wings, but when I tried the same thing, it didn’t work. The method they used was a script made by @AtAltitude which adds in air resistance, and I tried to insert the air resistance script into the part, but it just falls out of the sky. I’m assuming this is because the part is too small but I don’t know how Madattak dealt with this or if they did not have this issue.

how should I go about creating something for the air resistance for my part?

here is the code from AtAltitude’s script


--Aerodynamic Brick by VolcanoINC

--Presets
Factor = -0.1

--Global Definitions
p = script.Parent
f = p.Force
vector = Vector3.new

--Area calculations
front = p.Size.x * p.Size.y
side  = p.Size.z * p.Size.y
top	= p.Size.x * p.Size.z

--Functions
function relpos(x, y)
	local HitPos = x
	local CJ = CFrame.new(HitPos) 
	local C0 = CFrame.new(-x) * CJ
	local C1 = y.CFrame:inverse() * CJ
	local ReturnCF = C0 * (C1:inverse())
	return ReturnCF:inverse().p
end

function pn(x)
	if (x > 0) then return 1 end
	if (x < 0) then return -1 end
	return 0
end

--Main
while true do
	wait()
	local fr
	local tr
	local sr
	local vp
	if (workspace:findFirstChild("Wind")) then
		fr = ((p.Velocity + workspace.Wind.Value) * p.CFrame.lookVector).magnitude * front
		tr = ((p.Velocity + workspace.Wind.Value) * (p.CFrame * CFrame.Angles(math.rad(90),0,0)).lookVector).magnitude * top
		sr = ((p.Velocity + workspace.Wind.Value) * (p.CFrame * CFrame.Angles(0,math.rad(90),0)).lookVector).magnitude * side
		vp = relpos(p.Position + p.Velocity + workspace.Wind.Value,p)
	else
		fr = (p.Velocity * p.CFrame.lookVector).magnitude * front
		tr = (p.Velocity * (p.CFrame * CFrame.Angles(math.rad(90),0,0)).lookVector).magnitude * top
		sr = (p.Velocity * (p.CFrame * CFrame.Angles(0,math.rad(90),0)).lookVector).magnitude * side
		vp = relpos(p.Position + p.Velocity,p)
	end
	local vpx = pn(vp.x)
	local vpy = pn(vp.y)
	local vpz = pn(vp.z)
	f.force = vector(sr * vpx,tr * vpy,fr * vpz) * Factor * p:GetMass()
end


and here is what happens to my part

robloxapp-20221218-1520418.wmv (4.6 MB)

also here is what the parts in plane crazy look like
robloxapp-20221218-1526096.wmv (1.6 MB)

To get that effect you need to break the drag calculation into each surface. You can get the component air speed for each surface by taking the dot product between the air velocity and the surface normal, then calculate drag from there however you want. This will not model interference drag effects very well, but that’s probably fine and I doubt plane crazy does that either. A real plate dropped like that will start to sway and eventually start tumbling around one of its edges.

1 Like

isn’t the air velocity in Roblox 0? that would then mean that no matter the direction the surface was facing the result would be (0,0,0)

also, how would I calculate the surface normal? would that be like:

script.Parent.CFrame.LookVector,
script.Parent.CFrame.XVector,
script.Parent.CFrame.YVector,
script.Parent.CFrame.ZVector,
script.Parent.CFrame.XVector,
script.Parent.CFrame.UpVector,
script.Parent.CFrame.RightVector

or just this:

print(script.Parent.CFrame.LookVector)
print(-(script.Parent.CFrame.LookVector))
print(script.Parent.CFrame.UpVector)
print(-(script.Parent.CFrame.UpVector))
print(script.Parent.CFrame.RightVector)
print(-(script.Parent.CFrame.RightVector))

?

You can do either of those. The air velocity I mentioned is relative to the surface. It will not be zero when the part is moving. If you do all your calculations in local space (you should) you can also just use this list. This represents all 6 surface normals for your block’s faces in local space.

local unitVectorSet = {
	Vector3.new(1,0,0),
	Vector3.new(-1,0,0),
	Vector3.new(0,1,0),
	Vector3.new(0,-1,0),
	Vector3.new(0,0,1),
	Vector3.new(0,0,-1)
}