How to check if a Player is moving (Alternatively, what's the best way to check the Player's Y axis consistently)

Hello, I have a small issue today

i’m making a system that logs the position of the player whenever they move but i don’t exactly know how i’d do this properly.

I saw that the usage of MoveDirection is something used however upon using this, I came to the realization that the Y axis isn’t updated if the player is Falling or Jumping, which can provide some inconsistencies.

I was then redirected to Heartbeat but this fires every frame after the physics is calculated (or something along those lines) which also works but sounds somewhat expensive in terms of preformance. since every Client will have this, I don’t think this’d be the best option. Especially considering that I noticed frame drops whenever I added a Print statement to the Function.

I then thought of trying to combine these two together;

Hum:GetPropertyChangedSignal("MoveDirection"):Connect(function()
	if Hum.MoveDirection.Magnitude > 0 then
		TrackFunction = RS.Heartbeat:Connect(function()
			local YAxis = HRP.Position.Y
			print("Heartbeat is Running")
			script.Parent.DepthStat.Text = "Depth: "..math.round(YAxis)
			if Hum.MoveDirection.Magnitude <= 0 and Hum:GetState() ~= Enum.HumanoidStateType.Freefall then
				TrackFunction:Disconnect()
				print("Disconnected function")
			end
		end)
	end
end)

The idea behind this was that the script would check if the player is moving, if they are, then the heartbeat function is started. which logs the y axis of the player and updates it to a GUI. it also checks if the player is in the Freefall state or if the player’s magnitude from MoveDirection is at 0. (i know that MoveDirection can’t go below zero that was just habit.)

If it checks that either of these values are true, it should disconnect the heartbeat function, stopping the entire function until the movedirection changes to being above one again.

This script doesnt work however;
image

The function just re-activates itself even if the Player is standing still.

I’m assuming I misunderstand what :Disconnect() actually does? unsure.

All of this is to just check the Player’s Y Position whenever it changes (Before anyone says: No, You can’t use GetPropertyChangedSignal on the Player’s Position. I’ve tried this already and it is never activated. I was told this was because it only detects changes made by scripts and not physic changes.)

Any help? I’m looking for something that won’t just run in the background 24/7 like Heartbeat but I do want it to fire constantly as long as the player is moving. Thank you.

(^^ when I say “Players” I’m referring to their character.)

Judging the code you gave us, you have a memory leak because you’re creating the heartbeat connection inside of the movedirection connection in a global scope, so you’re creating new connections every time the move direction changes and are removing the reference to them when creating a new TrackFunction, so old connections will still exist anonymously while you’d be disconnecting the new connection multiple times. This will also likely be the biggest issue with your code in terms of performance.

You also run into the issue where if the player just jumps/falls without walking, the label will not show their actual Y position (since humanoid.MoveDirection doesn’t fire the changed signal for the Y axis in my testing)

Now, realistically, I think simply setting the label’s text to be the Y position every frame without conditionally disconnecting connections is going to be fast enough and an easy solution. All you’re doing in that case is reading a property once, then writing to a property once which should be very fast.

print is notoriously slow because it needs to format text in the output, so if you’re noticing frame drops while using print, especially so often as every frame, it isn’t necessarily a good indicator that something in your code is wrong.

2 Likes

Hello, sorry for the late response i’ve been off for a bit.

I did think of trying that but this would be applied to every player and would basically be running all the time for reach player. that sounded like it’d have an impact on preformance so the conditional factor was an attempt to migitate that by not having it run when tis not needed but i’m not exactly sure how much impact heartbeat has on preformance, For reference, I can imagine myself setting server size limits to be around 20-30

would this actually be an issue or am I overestimating how preformance heavy heartbeat is?

I think if you made TrackConnection not a global it would fix the memory leak issue, tho there are probably still better ways to achieve the same effect here is the code for the non global variable version

Hum:GetPropertyChangedSignal("MoveDirection"):Connect(function()
	if Hum.MoveDirection.Magnitude > 0 then
		local TrackFunction -- define TrackFunction as a local variable to prevent memory leak
		TrackFunction = RS.Heartbeat:Connect(function()
			local YAxis = HRP.Position.Y
			print("Heartbeat is Running")
			script.Parent.DepthStat.Text = "Depth: "..math.round(YAxis)
			if Hum.MoveDirection.Magnitude <= 0 and Hum:GetState() ~= Enum.HumanoidStateType.Freefall then
				TrackFunction:Disconnect()
				print("Disconnected function")
			end
		end)
	end
end)
1 Like

It shouldn’t be an issue, all you’d be doing is reading then writing to a property 20-30 times per frame which shouldn’t have much of an impact. Worst case scenario you could do this every .1 seconds instead of every frame but I really don’t think it will be a hindrance to performance whatsoever.

2 Likes

I see, thanks for your awnsers, its just something i’ve been concerned with as it gets difficult to track down sources of poor preformance when you add more to a project

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.