Your first method might actually just work fine, but I think you also need to do a raycast to see if the player is touching any ground.
most of the time when the character lands or jumps .StateChanged doesnt trigger
raycast wouldn’t work because pointing it from the center of the character’s foot would mean that if the character is standing on the edge of it’s foot the raycast will detect as not standing, when actually the character is standing on a part, just on the edge of its foot
Well, if something works with a standard rig and doesn’t work with your rig, there may be something wrong with your rig. Maybe you’re troubleshooting the wrong problem here.
I never made my own rig so I’m not sure what it could be though.
I guess a smarter way to do it is incorporate JumpRequest event while using humanoid.Jumping to see if it’s currently jumping before being able to operate.
Are you running this script on the Server or the Client?
The client is usually better at detecting humanoid events.
You cast it down from the middle of the character’s HumanoidRootPart because that part always needs to stay on ground or the character will fall off the edge.
Never raycast from body parts unless you have a very good reason to.
Also, I suggest you do the raycast like 0.1 seconds after the jump, otherwise it might still hit the ground and think the player is standing.
Alternatively, you can also just raycast to the ground anyways and just check if the distance is more than 3.5 studs to count as a jump.
The issue he is talking about is referring to when a player is barely standing on a ledge like so:
Because the character is centered over nothing, the raycast won’t work properly.
The best way to solve this problem is to detect the jump/landing on the client, then fire a RemoteEvent to the Server. It would be something like this:
Client (StarterCharacterScripts):
local event = (the remote event)
local char = game.Players.LocalPlayer.Character
local countJump = false
char.Humanoid.StateChanged:Connect(function(old, new)
if new == Enum.HumanoidStateType.Jumping then
countJump = true
elseif new == Enum.HumanoidStateType.Landed then
if countJump then
countJump = false
event:FireServer()
end
end
end)
Server (ServerScriptService):
local event = (the remote event)
local debounces = {}
local jumpCD = 0.5 -- minimum time between jumps
event.OnClientEvent:Connect(function(plr))
if not table.find(debounces, plr.Name) then
table.insert(debounces, plr.Name)
-- update leaderstats or whatever
task.wait(jumpCD)
table.remove(debounces, table.find(debounces, plr.Name))
end
end)
The only flaw to this is that an exploiter could fire the remote event. However, a cooldown on the server prevents it from going up too quickly.
More raycasts should solve this, or doing a shapecast down which is just a singular block raycast that should hit about anything.