Every time I activate the tool, the character gets teleported 20 studs toward mouse position 1 more time.

So, after the first activation, the character is teleported 20 studs toward mouse position, but the second activation, it is teleported 40 studs and "teleported" is printed twice.

I originally made only one event, but I made another one because I thought that using the same event caused this effect, but this had no effect.

I also moved the teleport out of the repeat and used a flag instead, but it didn't have an effect either.

How can I make it so it always makes the character teleport once?

Tool Script:

local tool = script.Parent

local character = workspace:WaitForChild(tool.Parent.Parent.Name)
local player = game.Players:GetPlayerFromCharacter(character)

local animator = character.Humanoid:FindFirstChildOfClass("Animator")
local assets = tool.Assets

local swing = assets.Swing
local swingAnim = animator:LoadAnimation(swing)

local mouseEvent = game.ReplicatedStorage.GetMousePos
local mouseBack = game.ReplicatedStorage.BackMouseServer

local hrp = character.HumanoidRootPart
local torso = character.Torso

tool.Activated:Connect(function()
	swingAnim:Play()
	
	wait(0.7)
	
	mouseEvent:FireClient(player)
	mouseBack.OnServerEvent:Connect(function(plr, mouseP)
		local overrideTp = false
		
		local targets = {}
		local rayDirection = mouseP.Unit * 20
		
		local rayParams = RaycastParams.new()
		rayParams.FilterDescendantsInstances = {character:GetDescendants()}
		rayParams.FilterType = Enum.RaycastFilterType.Blacklist
		
		repeat
			local res = workspace:Raycast(torso.Position, rayDirection, rayParams)

			if res then
				local hitPart = res.Instance
				if hitPart.Parent:FindFirstChild("Humanoid") then
					table.insert(targets, res.Instance)
					rayParams.FilterDescendantsInstances = targets
					print("player hit")
				else
					local hitPoint = res.Position
					character.PrimaryPart.CFrame = CFrame.new(hitPoint)
					overrideTp = true
				end
			end
		until not res
		
		if overrideTp == false then
			character.PrimaryPart.CFrame = character.PrimaryPart.CFrame + (mouseP - hrp.Position).Unit * 20
			print("teleporting")
		end
	end)
end)

Local Script:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local event = game.ReplicatedStorage.GetMousePos
local eventend = game.ReplicatedStorage.BackMouseServer

local function getPosition()
	eventend:FireServer(mouse.Hit.p)
end

event.OnClientEvent:Connect(getPosition)

5 comments

0

Also to add, every time a player is in the path "player hit" gets printed so many times script runtime is exhausted

0

did you mean until res in line 49 or that is intended, i don't understand the logic here that you are trying to repeat until the raycast doesn't work

0

It's to check for multiple instances, since raycasts can only return one instance and not a table of them. If a player is hit, they are added to a table of targets that will be ignored and the ray is fired again to check for other players.

0

And if it's not a player, it's a wall or something that isn't meant to be teleported through, so the player is teleported to the point of intersection instead of through the wall

0

Update: it seems like the server event is repeating this way. I put a print in the local script's function and inside the script's OnServerEvent function. The print only activated once in the local script but activated the same times as the teleport in the OnServerEvent function