So, this script is supposed to print that a Player is close to a gate when they are within 6 studs. But, for some reason, it does not do so, even when they are within the specified amount of studs. Can you help me understand why it is not working?
----------------- --| Variables |-- ----------------- local Players = game:GetService("Players") local Gates = script.Parent:GetChildren() local RequiredDistance = 6 ----------------- --| Functions |-- ----------------- function GetDistance(Object) if (Object:IsA("Player")) then for _,Child in pairs(Gates) do if (Child:IsA("Part")) then local Distance = Object:DistanceFromCharacter(Child.Position) if (Distance <= RequiredDistance) then return true end end return false end end end ----------------- --| Main Code |-- ----------------- Players.PlayerAdded:connect(function(Player) local Character = Player.Character or Player.CharacterAdded:wait() repeat wait() until Character.Torso local Torso = Character.Torso Torso.Changed:connect(function() if (GetDistance(Player)) then print(Player.Name.." is close to a gate!") end end) end)
Child
is a poor name for a Gate
.Object
is a poor name for a Player
.GetDistance
is a poor name for something that doesn't return a number. IsNearGate
or NearGate
makes more sense.GetDistance
/NearGate
to only continue if it's given a player. The only check that might belong is assert(Player:IsA("Player"))
. It is the caller's responsibility to give the right parameters.There are two problems with this code.
First, that only the first torso will be tracked by this script -- if they die, you'll still have Torso
pointing to the first torso they had. This actually won't matter, because of the second point:
.Changed
doesn't fire for changes caused by physics. Consequently, while teleporting the player will trigger the changed event, walking won't.
There isn't really a good event to get when the player moves (it would happen too often anyway). It's much more straightforward to just check every half a second with a while
loop:
Players.PlayerAdded:connect(function(Player) while Player.Parent do if NearGate(Player) then print(Player.Name .. " is close to a gate") end -- check twice a second wait(1/2) end end)
Note that DistanceFromCharacter returns 0 if the player doesn't have a head, so between lives this will believe that they are near the gate. It might be a good idea to require Distance
to also be above, say, .01
in addition to being less than RequiredDistance