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

2d Collision Detection (With Many, Many Moving Parts)?

Asked by
x_Tso 48
4 years ago

Hi! The last sum of questions have helped me push my game forward as a bullet-board RPG, yet I come with one final question that stands in the way of finishing the groundwork for a typical battle.

Collision detection between the icon and the bullets.

Now I do already have some form of collision between parts set up. As in, there is a boundary that the game checks to make sure the player is constantly in. When they try to leave that boundary, it pushes them back (which in real time just makes it look like your player isn't moving if you try running into that wall.)

That system requires a little math and only really works with a single frame.

Here's the system I use to detect if the player is in-bounds at all times.

local pos1, size1 = script.Parent.Parent.Background.Icon.AbsolutePosition, script.Parent.Parent.Background.Icon.AbsoluteSize;
    local pos2, size2 = script.Parent.AbsolutePosition, script.Parent.AbsoluteSize;

    local top = pos2.Y-pos1.Y
    local bottom = pos2.Y+size2.Y-(pos1.Y+size1.Y)
    local left = pos2.X-pos1.X
    local right = pos2.X+size2.X-(pos1.X+size1.X)

    if top > 0 then
        script.Parent.Parent.Background.Icon.Position = script.Parent.Parent.Background.Icon.Position + UDim2.new(0,0,0,top)
    elseif bottom < 0 then
        script.Parent.Parent.Background.Icon.Position = script.Parent.Parent.Background.Icon.Position + UDim2.new(0,0,0,bottom)
    end
    if left > 0 then
        script.Parent.Parent.Background.Icon.Position = script.Parent.Parent.Background.Icon.Position + UDim2.new(0,left,0,0)
    elseif right < 0 then
        script.Parent.Parent.Background.Icon.Position = script.Parent.Parent.Background.Icon.Position + UDim2.new(0,right,0,0)
    end
end

Now this system works fine, and I run it on a RunService.Stepped speed. However, not only do I not think doing this for every bullet on the board at all times would be a very weird solution, but I also fear it might kill the performance of this game on low end devices.

Is there any way I can modify this script to be more optimized (if I must use this math script for every bullet) or is there a better solution you guys can point me towards to detect collision with a mass amount of frames / ImageLabels?

I've been on the lookout for solutions that aren't very heavy on the game's performance, but either it points to old articles (sometimes ones on the wiki that for some lame reason no longer exist), or solutions that require that heavy amount of math.

Suggestion: Why can't ROBLOX just implement a .Touched feature similar to what you use for parts, but for GUIs? Like seriously?

Thanks!

1 answer

Log in to vote
1
Answered by 4 years ago

I've tried making a function that should work as a collision box but only when the player is close enough, this should (in theory) optimize performance.

local rs = game:GetService("RunService")
local player = -- Player object here

function collisionDetection(object)
local pos1, size1 = player.AbsolutePosition, player.AbsoluteSize;
    local pos2, size2 = object.AbsolutePosition, object.AbsoluteSize;

    local top = pos2.Y-pos1.Y
    local bottom = pos2.Y+size2.Y-(pos1.Y+size1.Y)
    local left = pos2.X-pos1.X
    local right = pos2.X+size2.X-(pos1.X+size1.X)

    if top > 0 then
        player.Position = player.Position + UDim2.new(0,0,0,top)
    elseif bottom < 0 then
       player.Position = player.Position + UDim2.new(0,0,0,bottom)
    end
    if left > 0 then
     player.Position = player.Position + UDim2.new(0,left,0,0)
    elseif right < 0 then
       player.Position = player.Position + UDim2.new(0,right,0,0)
    end
end


rs.RenderStepped:Connect(function()
    for i,v in pairs(gui here:GetChildren()) do
        if v:FindFirstChild("CollisionBox") then -- add a "tag" to all objects with collision
            if (player.Position - v.Position).magnitude < (v.Size).magnitude then
                collisionDetection(v)
            end
        end
    end
end

I could however be horribly mistaken since the distance calculation in itself is pretty resource intensive, so it might actually be less effecient.

0
thanks! i had to modify the script a little with the distance detection (using absolute size / position and cutting magnitude), while also changing the function collisionDetection() to fire something whilst we're touching a bullet, not when we're not. also had to throw in some extra modifications to make it account for rotation, but all in all, worked nicely! thanks! x_Tso 48 — 4y
Ad

Answer this question