Making an SkyDive Physics

Hello there! I’m making skydive system for my game, and I need to make when you fly down you will gain speed and when up the speed will decrease and when you will hit speed 0 the fly will cancel, Anyway I don’t know how could I achieve that

Because I don’t really know how to detect if player is going up or down!

If anyone could help me please reply!

To see if they are falling down, you could check to see if their humanoidRootPart’s Y axis is decreasing.

Or increasing hmm, but how? I think of saving last Y and then comparing it to the actual to see if player is going up or down

Yeah, that would work. I think you could also see if the humanoid is in the falling state.

Not really because when flying the state will be always falling state

This seems to be not working and I’m doing this

if not lastY == nil then
 		if lastY <= Character.HumanoidRootPart.Position.Y then
 			print("We are falling down")
 		else
 			print("We are flying up")
 		end
 		
 	end

Checking to see if the last Y position is less than the current literally means that they are going up. If they fly up, the Y increases. If they go down, the Y decreases. Compare it like this:

if lastY > Character.HumanoidRootPart.Position.Y then
   print("We are falling. The last Y position was higher, and we are going down.")
end

Weird it is not printing anything

How are you recording the last Y value? Do you get any errors?

Hmm I doing this

spawn(function()
   while wait(1) do
   	lastY = Character.HumanoidRootPart.Position.Y
   end
end)

Alright, lets clean up this code a bit.

spawn is highly unreliable. Use coroutine instead. Also, while wait(x) loops are bad practice. Lets try something like this:

local lastY = nil
local canUpdate = true

local function setLastYValue() -- Make an "infinite" loop with renderstepped.
   while true do
      if not canUpdate then return end

      canUpdate = false
      
      lastY = Character.HumanoidRootPart.Position.Y
      print(lastY)

      wait(.1)
      canUpdate = true
   end
end

local newThread = coroutine.wrap(setLastYValue) -- Set up a new thread. Basically what spawn does.

newThread()

Tell me if it prints anything, at all.

One thing you might try is checking the velocity of the HumanoidRootPart, the magnitude and direction can be found from the Velocity property

 local Velocity = HumanoidRootPart.Velocity.magnitude;  --- for speed
 local dir = HumanoidRootPart.Velocity.Unit -- direction
1 Like

This is a good model if you want to use it or at least look at the code: R15 and R6 Skydiving [MUST CREATE ANIMATION!] - Roblox

1 Like

Also, instead of using loops, you could just update it when the position changes.

local lastY = nil

Character.HumanoidRootPart:GetPropertyChangedSignal("Position"):Connect(function()
   if Character.HumanoidRootPart.Position.Y ~= lastY and Character.HumanoidRootPart.Position.Y < lastY then
      lastY = Character.HumanoidRootPart.Position.Y
   end
end)

This is working, Ima try do the speed system now

See my new reply, it should update faster and isn’t relying on while true loops.

Ok I did the system and works fine, but can I ask how can I make the SFX sound being synchonized with player speed

There is a handy property called PlaybackSpeed.

Something like this could work:

local lastY = nil
local speedSound = -- path to sound

Character.HumanoidRootPart:GetPropertyChangedSignal("Position"):Connect(function()
   if Character.HumanoidRootPart.Position.Y ~= lastY and Character.HumanoidRootPart.Position.Y < lastY then
      lastY = Character.HumanoidRootPart.Position.Y

      local speed = Character.HumanoidRootPart.Velocity.magnitude
      speedSound.PlaybackSpeed = ((speed / 100) * 2)
   end
end)

If the sound sounds weird, try changing it from times 2 to something else like times 1.5 etc

1 Like