Recently I have been creating an obby sort of game, and found that the Touched event does not register when a player holds the spacebar down to jump twice quickly. I will show you what I mean.
Script:
local part = script.Parent
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
print("hm")
end
end)
Video:
When I land on the part and jump up quickly, nothing gets printed into the output. When I touch the part from the side or walk on the top of the part, the print statement fires.
I am not sure if this is due to the inaccuracy of the Touched event, which if it is please let me know alternatives, or if it is fixable with some tweaks to the code.
The issue here is that while the humanoid’s raytrace detects the part, and allows the player to jump, the character’s parts aren’t physically touching the part. With your animation set that’s a mild issue, but with some animations such as the levitating walk animation, you run into situations where the character never actually touches the ground. Some animations could enable your players could walk right across your obstacles without ever tripping the .Touched event.
You could try listening to the humanoids’ .Touched events instead, but from the developer hub page it looks like that event also relies on physical parts, and doesn’t detect collisions with the humanoid ray trace.
The simplest solution I could think of would be to make those parts non-collidable so that players don’t have the option of hopping across your obstacles in that way. Alternatively you could weld a “collision box” part to the character that spans the entire volume you’d like to be able to detect collisions with. That way you prevent players from gaining an advantage or being disadvantaged because of their character customizations.
OKAY so I am not that experienced in this field, so it took me an unbelievably long time to draft this out. It may not be the most ideal solution, but it works:
local Parts = {game.Workspace.Part1,game.Workspace.Part2,game.Workspace.Part3}
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAppearanceLoaded:Connect(function(character)
while true do
for i,v in pairs(Parts) do
wait(0.1)
local distance = (player.Character.HumanoidRootPart.Position - v.Position).magnitude
if distance < 9 then
print(player.Name.." touched "..v.Name.."!")
end
end
end
end)
end)
So it basically gets the player’s distance from the object, and if it’s close (the number 9 can be changed but it seemed to work well for me when it comes to small objects) then it will fire. Of course the use of tables is not necessary, but if all your objects are around the same size then this will work well since it will save you from using multiple scripts. The table is to store all the parts that can be touched.
If an object is bigger, just require a higher magnitude to make sure you don’t miss the player. Again this is not the most ideal method (I think) but it’s just a pretty convenient one to me haha.