Best way to calculate the amount of footsteps a player has done?

Hello, I have been recently trying to calculate the amount of footsteps a player has done, but I can’t find a good way to do that. One of my friends suggested me to take a look at this article but unfortunately I found it unhelpful. First of all the code that was provided there was deprecated, outdated and ridicolous:

(v first 2 lines of the code)

local player = game.Players:GetChildren()[1]
local character = game.Workspace:WaitForChild(player.Name)

Not only that but :GetKeyframeReachedSignal() was simply not working, it also threw an error “GetKeyframeReachedSignal is not a valid member of AnimationTrack” (I followed the example of the wiki). I am really confused and I do not know how to calculate the amount of footsteps a player has done. I tried making my own script but it wasn’t working as intended as the footsteps did not accurately get calculated when the player’s walkspeed changed.

Can someone tell how I can accurately calculate a player’s footsteps or at least tell me the steps of doing so? I want to create a script to accurately measure the amount of footsteps a player has done no matter how small or big the player’s walkspeed is or other factors which might prevent the script from accurately measuring footsteps.

3 Likes

Looking on the wiki, it is actually AnimationTrack:GetMarkerReachedSignal(). I’d agree with your friend, this is a pretty good way to calculate the number of steps. However, it does have some drawbacks which may make another method better for your use case. For example, the player may quickly tap forward causing their character to move, but no marker is ever reached. If a game mechanic assumes that to move they need to take steps, then they have broken the mechanic’s logic.

A better way to calculate the number of steps in that case would be the distance traveled divided by the studs per a step. If the distance traveled isn’t apparent, you can also find it by the time spent walking divided by the number of steps per a second seconds per a step.

edit: it looks like the code sample provided on that page is out of date…

4 Likes

If no marker ever gets reached then that would actually be better as I do not want my script to count rapid forward touches, I want it to count actual steps. So I will stick to the method I talked about above, also it is not just about the code. animTrack:GetKeyframeReachedSignal() is a method which is supposed to work.

You can just track the distance that the character has walked and use that… A character’s foot is exactly one stud so logically it works out too.

To do that you’d just check the distance they traveled since the last .Heartbeat event and this will accurately give you the distance they’ve walked.

Use what? Also the distance calculated must be precise or else some steps might not be counted, I’d probably need to calculate the distance using a loop so the footsteps could be calculated precisely. Also even if I managed to calculate the distance traveled precisely the result wouldn’t be accurate. Let me explain why:

game:GetService("RunService").RenderStepped:Connect(function()
    local distanceTraveled = (currentposition-lastposition).magnitude
    local totalDistanceTraveled = totalDistanceTraveled + distanceTraveled
end)

Except the fact that this method is not good (because I am using a loop to count the player’s footsteps meanwhile a loop could be avoided in this case), it is not even precise because the player can just spam walk forward and the script would assume the player traveled to his current position and then the script would assume that he made a step which is not what I want.

Also I think this is probably the only way you could do this, the reason for this is because the player’s speed is constantly changing and the measurements of the steps wouldn’t be accurate also because only :GetKeyframeReachedSignal("FootStep") guarantees that a footstep has been done by the player.

Use RunService.Heartbeat because it runs every physics frame. It can’t miss any steps.

Also you should probably zero out the Y value of each position so jumping/falling isn’t included.

Alright but that still doesn’t solve this problem:

Actually it does since it runs every physics frame. There’s no way for the player to have distance not counted since their position is only updated on the server on Heartbeat (the same is true for the client)

The problem is not in the distance. As I said even if I calculated the distance 100% precisely, the steps wouldn’t be calculated precisely. I explained why above but you probably didn’t understand why so I will give you a more concrete example. Lets suppose I travel 1 stud. If I just hold W and walk it would count that as a step, but what if I traveled 1 stud via rapidly tapping the W button in my keyboard? The steps wouldn’t be count. Also I also said that the player’s walk speed changes constantly so the studs/sec I am traveling constantly changes so the steps wouldn’t be accurately measured. I could calculate the distance the player traveled meanwhile his speed was is x stud per second and then find out the steps and add them all together but it is an inefficient way of doing it considering that the player’s speeds changes every step. Also considering that the footsteps that the player has done is a leaderstat, I would need to see how many steps a player has done immediately as the player makes a step to update the leaderstat.

If they tap W it will only count once they move a full stud… There is no way for the distance to inaccurately be measured. Do you mean you only want to count full steps instead of if they spam to move? If that’s the case you can floor the distance value each frame and then add that to the steps so it only counts if they walk a full step in one frame.

You could also try the keyframe method and make sure they’ve been walking for long enough before counting steps.

Edit: You should divide your distance by the value passed to Heartbeat before flooring and multiply after since they’d need to travel fps studs per second otherwise

Yes but the method you are suggesting is inefficient, I want to use the keyframe method but it is simply not working.

Actually this method still wouldn’t work considering that the player’s humanoid root part’s position’s Y axis varies depending on the terrain height so there would be no way to not count the distance that the player is doing by swimming or jumping. Also this is just really inefficient, as I said, I can just use :GetMarkerReachedSignal() but the problem is that it is not working for some reason.

Why don’t you use track.KeyframeReached?

1 Like

I mean I understand your problem but like said before, I believe just using .Heartbeat and only using the x and z coordinates of the position to find the distance traveled is the best way to go.

It is not. What if the player teleports? Swims? Jumps?

Problem fixed! The way I fixed the problem was by editing the ROBLOX’s default animations and adding trigger events to those animations called “FootSteps” and replaced the default animations then I used animTrack:GetMarkerReachedSignal("FootStep"):Connect(function() to detect when the player did a step. It works perfectly fine! Just as I wanted it work.

10 Likes