Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Why is my raycasting detecting more parts than there are around a player?

Asked by 5 years ago

I am trying to find an empty location around a player for another player to spawn at. Someone suggested raycasting and so that is what I am using. The code works fine when there are no parts around the player. The problem comes when there are some parts. I have a ceiling and two walls I put up to see if my code worked. When I stood under the ceiling and two walls and tried to get the other player to teleport to me, it did not work. So I put some prints in to see where the problem was and apparently my raycasting is detecting parts in all directions even the directions where there are none. Here is the script:

local function findEmptyDirection(character)

    local hRPart = character:FindFirstChild("HumanoidRootPart")

    if hRPart then

        local xYOrZ
        local offset

        for i = 1, 5 do

            if i == 1 then
                xYOrZ = Vector3.new(0, 10, 0)
                offset = Vector3.new(0, 7, 0)
            elseif i == 2 then
                xYOrZ = Vector3.new(8, 0, 0)
                offset = Vector3.new(5, 0, 0)
            elseif i == 3 then
                xYOrZ = Vector3.new(-8, 0, 0)
                offset = Vector3.new(-5, 0, 0)
            elseif i == 4 then
                xYOrZ = Vector3.new(0, 0, 8)
                offset = Vector3.new(0, 0, 5)
            elseif i == 5 then
                xYOrZ = Vector3.new(0, 0, -8)
                offset = Vector3.new(0, 0, -5)
            end

            local ray = Ray.new(hRPart.Position, hRPart.Position + xYOrZ)
            local part, hitPosition = workspace:FindPartOnRay(ray, character)

            if not part then

                return hRPart.Position + offset

            else

                print(part.Name) -- this prints 5 times even though there should be only three parts

            end

        end

        return false

    end

end

Thanks!

1 answer

Log in to vote
1
Answered by
ozzyDrive 670 Moderation Voter
5 years ago

Your issue seems to be on this line: local ray = Ray.new(hRPart.Position, hRPart.Position + xYOrZ), more specifically the second argument. It is supposed to be the direction vector, you're now passing it the direction vector translated with the root part's position. Taking out the translation should fix the issue: local ray = Ray.new(hRPart.Position, xYOrZ)

I wrote this little demonstration to capture empty points around the player, in case you want to see a more cleaner approach to the problem:

local character = script.Parent
local root = character.PrimaryPart

--

local function drawPoint(v3, brickColor, parent)
    local part = Instance.new("Part")
    part.Anchored = true
    part.CanCollide = false
    part.BrickColor = brickColor
    part.CFrame = CFrame.new(v3)
    part.Size = Vector3.new(0.5, 0.5, 0.5)
    game:GetService("Debris"):AddItem(part, 0.1)
    part.Parent = parent or workspace
    return part
end

local function isPointEmpty(origin, direction)
    local ray = Ray.new(origin, direction)
    local collision, position = workspace:FindPartOnRayWithIgnoreList(ray, {character})
    return collision == nil, position
end

local function findEmptyPoints(character, segments, radius)
    local emptyPoints = {}

    radius = radius or 10
    local rad = math.rad(360 / segments)
    local origin = character.PrimaryPart.CFrame

    for i = 1, segments do
        local direction = origin.p - (origin * CFrame.Angles(0, rad * i, 0) * CFrame.new(0, 0, radius)).p
        local isEmpty, position = isPointEmpty(origin.p, direction)
        drawPoint(position, isEmpty and BrickColor.Green() or BrickColor.Red(), character)
        if isEmpty then
            table.insert(emptyPoints, position)
        end 
    end

    --  Check above the head
    do
        local direction = Vector3.new(0, radius, 0)
        local isEmpty, position = isPointEmpty(origin.p, direction)
        drawPoint(position, isEmpty and BrickColor.Green() or BrickColor.Red(), character)
        if isEmpty then
            table.insert(emptyPoints, position)
        end
    end

    return emptyPoints
end

--

game:GetService("RunService").Heartbeat:Connect(function()
    print(unpack(findEmptyPoints(character, 8, 5)))
end)
0
Thank you so much! User#21908 42 — 5y
Ad

Answer this question