Getting Humanoid:MoveTo() to actually work

I literally took the code from the dev hub, and it don’t work. Even with the moveTo function firing,y my character doesn’t always move. It’s like a 1/20 touches

local CustomiseDoor = workspace:WaitForChild('CustomiseDoor')

local Debounce = false

local function moveTo(humanoid, targetPoint)
	local targetReached = false
 
	-- listen for the humanoid reaching its target
	local connection
	connection = humanoid.MoveToFinished:Connect(function(reached)
		targetReached = true
		connection:Disconnect()
		connection = nil
	end)
 
	-- start walking
	humanoid:MoveTo(targetPoint)
 
	-- execute on a new thread so as to not yield function
	spawn(function()
		while not targetReached do
			-- does the humanoid still exist?
			if not (humanoid and humanoid.Parent) then
				break
			end
			-- has the target changed?
			if humanoid.WalkToPoint ~= targetPoint then
				break
			end
			-- refresh the timeout
			humanoid:MoveTo(targetPoint)
			wait(6)
		end
		
		-- disconnect the connection if it is still connected
		if connection then
			connection:Disconnect()
			connection = nil
		end
	end)
end

CustomiseDoor.PrimaryPart.Touched:Connect(function(hit)
	local Character = hit.Parent
	if not Character then return end
	
	local Player = game.Players:GetPlayerFromCharacter(Character)
	if not Player then return end
		
	if Debounce then return end
	
	Debounce = true
	
	print(1)
	
	moveTo(Character.Humanoid, CustomiseDoor.Point.Position)
	
	wait(2)
	
	Debounce = false
end)

Go nuts
Customise Test.rbxl (21.2 KB)

And how can I prevent the player interferring with this? If the player does start moving, they can easily just press a key to stop the move happening. I want once they touch the door, they are forced to that part, theres nothing they can do

This may be due to your wait() thread. I’ve tried it for myself and I have reason to believe that the reason why only sometimes does the MoveTo work is because your wait() threads prevent functions from stacking.
This is just a theory and it could be something else, but have a play around and let me know if you ever find the root cause of the issue.

I thought that too, but when I first touch the door, it does nothing.

Try using:

if Debounce == true then return end

I’m pretty sure using

if Debounce then return end

Will return true, if it is anything other than nil.

Also, as an alternative to using a wait(time) debounce, you could index players in a table by tick() time.

Debounce can only be true or false… doing == true is redundant

I apologize you are correct. I typically do not use a debounce like you do. It’s not a very good method.

I use a table with tick index like I mentioned. It looks like this:

local PlayersTouching = {}
local cooldown = 2
Object.Touched:Connect(function(hit)
		local player = hit.Parent
		local humanoid = player:FindFirstChild("Humanoid")
		if humanoid then
			PlayersTouching[player.Name] = PlayersTouching[player.Name] or tick()-cooldown
			if tick() - PlayersTouching[player.Name] >= cooldown then
				PlayersTouching[player.Name] = tick()
				print(player.Name .. " Contact")
			end 
		end
end)

:man_facepalming:

Yes, because in your example Debounce is = false and so doing if Debounce then won’t happen unless you set it to true, so of course it won’t print :man_facepalming:

Not too sure you understand how the debounce works

Yea sorry about that. Don’t have time to go over your code thoroughly. That’s all I can try to help. Good day.

This is pretty straight forward. Once they are signaled to move to ensure that the actual command comes from the server.

At the moment they trip this, and sense you can determine where they should be, you can use a delay function to check after a time if they are where you expect them to be, within reason.

So think of it like.

If I touch part A, server says char to move to position 34, 0,56. Even if they override this locally, when your delay kicks it can read their position and if they are too far outside of what you expected, you can force snap them there. Using the clapping power of the server.

To ensure another command cant be executed while that one is going is just a standard state lock.

Have a true false that can be flagged that will block all further inputs till at a time you choose to flag it able.

1 Like

No need to be rude.
(30 chars)