So here's the deal. I am trying to make a diving simulator game. However, I don't know how to make the diving work. I have found it challenging to program a way that scans when the player falls then hits the water, and other ways to do it. I have tried connecting with scripts using RemoteEvents, I have tried doing it all through local script, I have tried doing it all through normal script.
Since Scripting Helpers is made to help people who have issues with their script or get people going in the right direction on projects, I can not give you exact code for your project. I am able to give you some examples and resources to look into.
First off, you're going to want to think about where your script is going to go. Since you're tracking changes of Humanoid states and we'll be discussing RunService events, we'll want to pick out a LocalScript.
With local scripts, you're going to want to keep those within the player. Since we'll be messing with the Character quite a bit with state changes we'll want to have the script load with the Character. In the StarterPlayer service, you can place the LocalScript in StarterCharacterScripts.
Now that the LocalScript has been placed in the appropriate location, we can grab the Humanoid from the script's parent. This way, whenever a new character loads, the script can start listening for the changes to the Humanoid's state. Since the Humanoid object might take a moment to load, I would recommend using a WaitForChild
yield on it. Once the Humanoid is loaded, we can connect directly to the StateChanged event. The StateChanged event passes two parameters to our function, the old state of the humanoid and the new state of the humanoid.
script.Parent:WaitForChild("Humanoid",5).StateChanged:Connect(function(old, new) print(old.Name .. "\t\t" .. new.Name) end)
From here, we're given the following results in the output.
From that, we can determine when the jump had begun, the player is actively falling through the air, and when the user hits the water. You can send information to the server stating that the jump and splash have been completed.
For every project, big or small, the most necessary part for a game is to have server validation. You can send information from the client to the server, but the server should also be doing checks to indicate if that action was actually allowed. The general rule is to never trust the client as false information may be passed by the client (a potential exploiter) to the server. You'll always want the server to check in some way that the user had enough money for a tool or has a sight on a target.
If you understand the concept of server validation, then this advanced information may be suitable for you. You can set up a loop to a Heatbeat
event fire and, while the player is falling through the air, gather how fast it is falling. This can be achieved by using the Character's Torso
or UpperTorso
, and getting the Velocity.Y value with every "Heartbeat".
With events, you can set them up to wait. This means, instead of setting up the event to a function, you can have it as a wait in a while loop. For example, we can say...
while game:GetService("RunService").Heartbeat:Wait() do --Logic Here end
Every time the event happens (which is based off the client's frame rates), then whatever is inside the loop will run. From this we can continually see what the Torso Velocity is. Personally, I prefer the RenderStepped as it is faster than Heartbeat; however, the Roblox Developer pages recommend Heartbeat so morally I must go by that.
Using the code below, I was able to determine the highest and lowest velocity of a Torso from a 50-jump sample on default settings with my own character. The fastest fall was at -55.727523803711
studs per second and the fastest jump was at 52.182495117188
studs per second.
wasMin = 0 wasMax = 0 function getMinMax() print(wasMin .. "\t" .. wasMax) end while game:GetService("RunService").RenderStepped:Wait() do local y = game.Players.LocalPlayer.Character.UpperTorso.Velocity.Y if y ~= 0 then print(y) wasMax=math.max(y,wasMax) wasMin=math.min(y,wasMin) end end
Different samples and different models may produce varying results. Make sure your scripts can accurately determine a player's jump speeds.
game.Players.PlayerAdded:Connect(function(plr) local hum = plr.Character.Humanoid if (hum.HumanoidStateType == Enum.HumanoidStateType.Swimming) then print('Player is swimming!') end end