Ways to use what .WalkToPoint does

Yes, but just if used on a Model with a PrimaryPart set, using the method on a Humanoid will set the WalkToPoint and WalkToPart (WalkToPart will be set if second parameter is used) properties making the character walk to the given point on its parameters.

Character.Humanoid:MoveTo(Model.WalkToPoint.Position)
print(Model.WalkToPoint.Position)

Doesn’t move the player at all still :confused:

Are you sure the code is being executed ?. Is there any error being shown on the Output ?.

No error, and the print I run after it is printing

Try defining the Character and its Humanoid using .CharacterAdded and :WaitForChild().

I can’t define using CharacterAdded as this is a touched event

local function Teleport(hit, from, to)
	local Character = hit.Parent -- Check for body parts
	if not Character then  return end
	
	local Player = Players:GetPlayerFromCharacter(Character)
	if not Player then
		Character = hit.Parent.Parent -- if player didn't exist then try again with .Parent.Parent (could have been accessory that touched)
		if not Character then return end
		
		Player = Players:GetPlayerFromCharacter(Character)
		if not Player then return end
	end
		
	if not Player then return end
	
	local Model = from.Parent

	Character.Humanoid:MoveTo(Model.WalkToPoint.Position)
	print(Model.WalkToPoint.Position)
end

Oh, i’m really distracted, Models don’t have a WalkToPoint property, you need to set the first parameter on the :MoveTo() method as the position of the PrimaryPart of the Model.

Model.WalkToPoint is a part (I named the part WalkToPoint, sorry if that’s confusing :grimacing:)

EDIT Got it working like 10% of the time

Character.Humanoid:MoveTo(Model.WalkToPoint.Position, Model.WalkToPoint)
print(Model.WalkToPoint.Position)

But the print prints several times before the player ever gets moved. So you have to keep touching the part before it actually moves you :confused: Not sure how to fix

You could add a short debounce to prevent the event firing multiple times.

Already got a debounce on the call of the function

for _, v in pairs(Teleporters) do
		v.Touched:Connect(function(hit)
			if Debounce then return end
			
			Debounce = true
			Teleport(hit, v, Rooms) -- hit, teleportFrom v.Parent, teleportTo Rooms
			
			wait(1)
			
			Debounce = false
		end)
	end

Could you please send the whole script ?

Don’t really think a lot of this is necessary to the problem

local function GetNearestDoor()
	local Character = Player.Character
	if not Character then return end
	
	local HumanoidRootPart = Character:FindFirstChild('HumanoidRootPart')
	if not HumanoidRootPart then return end
	
	local MinDistance, Door = 8, nil
	
	for _, v in pairs(AllDoors) do
		local Distance = (v.Position - HumanoidRootPart.Position).Magnitude
		if Distance < MinDistance then
			MinDistance, Door = Distance, v
		end
	end
	
	return Door
end

-- Teleport the player to the allocated spot
local function Teleport(hit, from, to)
	local Character = hit.Parent -- Check for body parts
	if not Character then  return end
	
	local Player = Players:GetPlayerFromCharacter(Character)
	if not Player then
		Character = hit.Parent.Parent -- if player didn't exist then try again with .Parent.Parent (could have been accessory that touched)
		if not Character then return end
		
		Player = Players:GetPlayerFromCharacter(Character)
		if not Player then return end
	end
		
	if not Player then return end
	
	local Model = from.Parent

	Character.Humanoid:MoveTo(Model.ToPoint.Position, Model.ToPoint)
	print(Model.ToPoint.Position)
	--Character:SetPrimaryPartCFrame((from.TeleportTo.Value).Teleporter.CFrame * CFrame.new(5, 0, 0))
end

local function CheckDoorsTouch()
	for _, v in pairs(Teleporters) do
		v.Touched:Connect(function(hit)
			if Debounce then return end
			
			Debounce = true
			Teleport(hit, v, Rooms) -- hit, teleportFrom v.Parent, teleportTo Rooms
			
			wait(1)
			
			Debounce = false
		end)
	end
end

-- Collect all the doors and put them in a table
for _, v in pairs(Buildings:GetChildren()) do
	if v.PrimaryPart.Name == 'Teleporter' then
		table.insert(Teleporters, v.PrimaryPart)
		CheckDoorsTouch()
	end
	
	if v:FindFirstChild('Door') then
		table.insert(AllDoors, v.Door)
	end
end

for _, v in pairs(Rooms:GetChildren()) do
	if v.PrimaryPart.Name == 'Teleporter' then
		table.insert(Teleporters, v.PrimaryPart)
		CheckDoorsTouch()
	end
	
	if v:FindFirstChild('Door') then
		table.insert(AllDoors, v.Door)
	end
end

I recreated and tested the important part of your code and it seems to work just fine:

local Players = game:GetService("Players")
local Debounce = false 

local Teleporters = {workspace.Part}

local Rooms = "Nothing"

local function Teleport(hit, from, to)
	local Character = hit.Parent -- Check for body parts
	if not Character then  return end
	
	local Player = Players:GetPlayerFromCharacter(Character)
	if not Player then
		Character = hit.Parent.Parent -- if player didn't exist then try again with .Parent.Parent (could have been accessory that touched)
		if not Character then return end
		
		Player = Players:GetPlayerFromCharacter(Character)
		if not Player then return end
	end
		
	if not Player then return end

	Character.Humanoid:MoveTo(Vector3.new(-85.2, 0.5, 6.6))
	print("Moving")
end
	
local function CheckDoorsTouch()
	for _, v in pairs(Teleporters) do
		v.Touched:Connect(function(hit)
			if Debounce then return end
			
			Debounce = true
			Teleport(hit, v, Rooms) -- hit, teleportFrom v.Parent, teleportTo Rooms
			
			wait(1)
			
			Debounce = false
		end)
	end
end

CheckDoorsTouch()

Of course i modified a bit the code to make it work but it’s basically the same, i’m not sure what’s your issue but maybe seeing the modified code you can identify it?.

EDIT: May have you set the “Debounce” variable wrongly ?

I can’t have set the debounce variably wrongly, as you’ve done it the exact same way as me.

Only thing I could think of is these

for _, v in pairs(Buildings:GetChildren()) do
	if v.PrimaryPart.Name == 'Teleporter' then
		table.insert(Teleporters, v.PrimaryPart)
		CheckDoorsTouch()
	end
	
	if v:FindFirstChild('Door') then
		table.insert(AllDoors, v.Door)
	end
end

for _, v in pairs(Rooms:GetChildren()) do
	if v.PrimaryPart.Name == 'Teleporter' then
		table.insert(Teleporters, v.PrimaryPart)
		CheckDoorsTouch()
	end
	
	if v:FindFirstChild('Door') then
		table.insert(AllDoors, v.Door)
	end
end

Calling the CheckDoorsTouch() multiple times for each door in the server. I need to do this, as in the future when players join theyll get given their own door, and thus need to be able to call doors in game after the fact

Yes, that’s the problem, by calling the CheckDoorsTouch() function multiple times you are connecting multiple Touched events to every door on the table, this can be fixed by creating a table containing the doors that already have a connection.

I can’t do that. As doors will get removed/added as players join/leave. So I’m gonna be connecting a ChildAdded function, and firing the CheckDoorsTouch() table.

That won’t fix the problem since you are still calling the function multiple times without any checks creating multiple connections, if the whole system is written on a single script you could remove the door from the table when it gets removed from the game, if not, you can use a Module Script and set the tables inside it. (Doing this is a little confusing but i can’t think of another solution right now)

This code is all being run from a module.

How can I get the 1 .Touched event to look for every door in game, both preplaced doors that I have placed in studio manually, as well as doors that get placed in during game, as well as removed. because I can’t just do

for _, v in pairs(AllDoors) do
    v.Touched:Connect(function(hit)

    end)
end

As that wont detect new doors that have been added, or been removed

Just create the connections table, then add a check on the CheckDoorsTouch() function: if the door isn’t found on the connections table then connect a .Touched event to it and add it to the table, otherwise just skip it and continue the iteration, this way you can call the function as many times as you want without creating multiple Touched events for every element on the “Teleports” table. When a door is removed (Or your system’s player removing function is called) search for it on the connections table and remove it by setting it to nil.

Even seperating the touched function from seperate loops still doesn’t work :confused: The walk to only occurs like 1 in every 10 shots

for _, v in pairs(Buildings:GetChildren()) do
	if v:FindFirstChild('Door') then
		table.insert(AllDoors, v.Door)
	end
	
	v.PrimaryPart.Touched:Connect(function(hit)
		Teleport(hit, v) -- hit, teleportFrom v.Parent, teleportTo Rooms
	end)
end

for _, v in pairs(Rooms:GetChildren()) do	
	if v:FindFirstChild('Door') then
		table.insert(AllDoors, v.Door)
	end
	
	v.PrimaryPart.Touched:Connect(function(hit)
		Teleport(hit, v) -- hit, teleportFrom v.Parent, teleportTo Rooms
	end)
end
1 Like