Hello. I was going to make a sword fight arena for my game but there are some bugs. Check the video and script for more info. Thank you for your time!
local character = script.Parent -- The script is located is StarterCharacterScripts
local Player = game.Players:GetPlayerFromCharacter(script.Parent)
local PlrBackPack = Player.Backpack
character.HumanoidRootPart.Touched:Connect(function(zone)
if zone.Name == "PvPZ" and not PlrBackPack:FindFirstChild("LinkedSword") and not character:FindFirstChild("LinkedSword") then
local Sword = game.Lighting.Storage.LinkedSword:Clone()
Sword.Parent = PlrBackPack
end
end)
character.HumanoidRootPart.TouchEnded:Connect(function(zone)
if zone.Name == "PvPZ" and PlrBackPack:FindFirstChild("LinkedSword") or zone.Name == "PvPZ" and character:FindFirstChild("LinkedSword")then
character.LinkedSword:Destroy()
PlrBackPack.LinkedSword:Destroy()
end
end)
-- the sword only gets destroyed when I have the sword equiped and the sword keeps on
Ignor the messages on the video due to the resolution. All I explain was that the sword keeps on destroying even though touch hasn’t ended and that the Tool only deletes when Workspace.(MyCharacter) is the Parent of the tool.
Hello, I think that the problem here is that you might have a part(floor) on touched event so whenever you touch the floor player gets the sword you need to change that to something bigger for example make transparent part with can collide and scale it up(above the character height even when it jumps) and scale its x and z to the zones size.
So basically touch and touchended keeps repeating over and over can you screen the box in the workspace pls? And also 1thing can you add prints in your touched events so we know if repeating Is the problem.
Both the Touched & TouchEnded Events are detecting the current names of the zone, so it’s repeatedly firing over & over again (Or removing & adding the Tool in a fast way)
I wouldn’t rely on detecting for a TouchEnded event, as it can become extremely unreliable in certain instances
What I’d recommend doing, is using Region3 which can be used to obtain a specific region of the world area (It’d be really useful in this Instance) or Magnitude through a loop:
--Server Script inside ServerScriptService
local Part = workspace.PvPZ
local Tool = game.Lighting.Storage:WaitForChild("LinkedSword")
while true do
for _, Player in pairs(game.Players:GetPlayers()) do
local Character = Player.Character
if Character and Player.Backpack:FindFirstChild("LinkedSword") == nil and Character:FindFirstChild("LinkedSword") == nil then
if (Character.HumanoidRootPart.Position - Part.Position).Magnitude < 25 then
local Clone = Sword:Clone()
Clone.Parent = Player.Backpack
end
else
if Player.Backpack:FindFirstChild("LinkedSword") then
Player.Backpack.LinkedSword:Destroy()
else
Character.LinkedSword:Destroy()
end
end
end
wait(1)
end
I think it’s better to use region3 then magnitude in this case, so you won’t have to use while loop.
Edit: but the script works perfectly fine and fixes the problem
Thing is, you’d still need to detect when a Player enters a Region by encasing it inside a loop so that it updates frequently & have it not fire just once
And you’d also need to detect when players exit out of a Region so you can remove the Tool
Yes but also no. The native Region3 checks can be considerably expensive, so you want to avoid constantly polling them in an infinite loop. What I do is use Touched to start the loop that polls for Region3 checks, and have that loop stop it’s self the first time it detects no characters within the Region3.
Here’s that logic being used for a sliding door; apologies for the mess.
function SlidingDoor:Start()
self:Disconnect('TouchSignal')
self.TouchSignal = self.TouchPart.Touched:Connect(function(touchedPart)
if self.StepSignal then return end -- early exit from the Touched handler if we're currently polling Region3's
-- check touched by character
if touchedPart.Parent:FindFirstChild('Humanoid') then
local playerTouched = game:GetService('Players'):GetPlayerFromCharacter(touchedPart.Parent)
if playerTouched then
self.PlayerTouchedBindable:Fire(playerTouched, true)
end
-- every server step check to make sure at least 1 character still standing in region
self.StepSignal = RunService.Heartbeat:Connect(function()
local tryCycle = true
local playersInRegion = {}
local parts = self.Region:Cast(self.IgnoreList)
for i = 1, #parts do
if parts[i].Parent:FindFirstChild('Humanoid') then
tryCycle = false
local player = game:GetService('Players'):GetPlayerFromCharacter(parts[i].Parent)
if player then
playersInRegion[player] = true
if not self.PlayersTouching[player] then
self.PlayersTouching[player] = true
self.PlayerTouchedBindable:Fire(player, true)
end
end
end
end
for player, _ in pairs(self.PlayersTouching) do
if not playersInRegion[player] then
self.PlayerTouchedBindable:Fire(player, false)
self.PlayersTouching[player] = nil
end
end
-- no chars in region; make sure we're not still opening and close doors
if self.IsAnimating then return end
if tryCycle then
self:Animate()
self:Disconnect('StepSignal')
end
end)
self:Animate()
end
end)
end