Anaminus / roblox-bug-tracker

Formerly an unofficial bug tracker for Roblox.
33 stars 24 forks source link

Humanoids may jump without touching the ground #299

Closed TheSneak closed 10 years ago

TheSneak commented 10 years ago

The ROBLOX update on the night of April 30, 2014 further exacerbated the problem with the touched event not firing when jumping on top of blocks. As of the specified update, only every other block registers a touch event when jumping across a series of blocks that have a handler tied to the Touched event. Previous to the specified update a block would irregularly (and with much less frequency) manifest this behavior. Since the update, the issue manifests frequently and with regularity on every other block in the sequence.

A non-copylocked place demonstrating the problem is here: http://www.roblox.com/BadPhysicsDemos-Place-place?id=155746026

A video of the problem in action: https://www.youtube.com/watch?v=6rn1sBLLNS8

In this video, I am holding down "w" to move forward and "space" to jump across the series of blocks. When a block is touched it turns black, then, after a wait of 0.2 seconds, it becomes unanchored and non-colliding. You see that a mere half of touched blocks register a touched event.

Code:

function blockTouched(block, bodyPart)
    if bodyPart.Parent then
        local humanoid = bodyPart.Parent:FindFirstChild("Humanoid")
        if humanoid then
            local player = game.Players:GetPlayerFromCharacter(humanoid.Parent)
            if player and block.Anchored and not block.Locked then
                block.Locked = true
                block.BrickColor = BrickColor.new("Black")
                wait(0.2)
                block.Anchored = false
                block.CanCollide = false
            end
        end
    end
end
--all blocks are contained in workspace.Model
for i,v in ipairs(workspace.Model:GetChildren()) do
    v.Touched:connect(function(part) blockTouched(v, part) end)
end
Anaminus commented 10 years ago

This is an issue with the Humanoid, not the Touched event.

So that jumping is more responsive, the character is able to jump without actually touching the ground. This would explain why touched events are not firing; because the character's legs never actually collide with the ground. Try this:

  1. Create a new place (with BasePlate at position 0,-0.61,0).
  2. Play solo with a character.
  3. Remove any hats you might be wearing.
  4. Insert a BodyPosition into the character's HumanoidRootPart.
    • D = 500
    • P = 10000
    • maxForce = 0,4000,0
    • position = 0,4.8,0
  5. Observe how the character is able to jump despite hovering nearly 2 studs over the ground.

One way to solve this might be to have the humanoid trigger the Touched event when it "collides" with a part. Though I'm not certain what object should be passed to the event, if any. Alternatively, you could do it yourself with FindPartOnRay.

Anaminus commented 10 years ago

Renamed from "Since update, every other block fails to trigger Touched event when jumping across"

TheSneak commented 10 years ago

I appreciate the suggestions for workarounds. I have tried using raycasting to solve this problem but the problem with it is that it requires a busy wait loop. Unless I am mistaken, there is no event associated with rays and intersections of rays by parts. In my game I have hundreds of blocks at a time that depend on the touched event being triggered. Polling each of them is processor intensive and makes the game quite unresponsive. Increasing the poll time makes the game more responsive, but the blocks decrease in touch-responsiveness. Are you aware of any event driven solutions to the problem?

einsteinK commented 10 years ago

.TouchEnded also altered? EDIT: Never mind, if the explanation I read here is right, it doesn't touch at all, so this won't work

Anaminus commented 10 years ago

You should do the raycasting on the character, not every single part. For example,

local hit = Workspace:FindPartOnRay(
    Ray.new(
        torso.Position,
        torso.Position + Vector3.new(0,-3 - 2,0) -- -3 for character height, -2 for jump collision distance
    ),
    character
)

if hit then
    triggerTouch(hit)
end

You might have this running every frame in a single loop. It would probably be necessary to do things like ignoring parts you don't care about, and adding a debounce per part so that it doesn't trigger them every tick. It may also be necessary to cast rays on each corner of the character's legs, so that they can't get around by walking along the edges of parts.

einsteinK commented 10 years ago

If your parts that need this event are on the same level, checking Torso.Position.Y would be better.

RobloxCodeWriter commented 10 years ago

This should be fixed now.