This right here is a script collated directly from EgoMoose's tutorial on how to implement 2D collision with rotation. Works perfectly. (Thanks! @Egomoose, if you are reading this.) But I have no idea how I would implement this into my own 2D engine without messing things up. My 2D enigne just has 2D collision without the support of rotation. The script from my 2D engine is below this script right here.
local f1 = script.Parent:WaitForChild("Frame1");
local f2 = script.Parent:WaitForChild("Frame2");
function getPerpendicular(vec)
return Vector2.new(vec.y, -vec.x).unit;
end;
function getAxis(shape1Corners, shape2Corners)
local axis = {};
axis[1] = getPerpendicular(shape1Corners[1] - shape1Corners[2]);
axis[2] = getPerpendicular(shape1Corners[1] - shape1Corners[4]);
axis[3] = getPerpendicular(shape2Corners[1] - shape2Corners[2]);
axis[4] = getPerpendicular(shape2Corners[1] - shape2Corners[4]);
return axis;
end;
function getAxis(shape1Corners, shape2Corners)
local axis = {};
-- it doesn't matter if the vector's x and y values are positive or negative (just no repeats via opposite vectors)
axis[1] = (shape1Corners[2] - shape1Corners[1]).unit;
axis[2] = (shape1Corners[2] - shape1Corners[3]).unit;
axis[3] = (shape2Corners[2] - shape2Corners[1]).unit;
axis[4] = (shape2Corners[2] - shape2Corners[3]).unit;
return axis;
end;
function getAxis(c1, c2)
local axis = {};
axis[1] = (c1[2] - c1[1]).unit;
axis[2] = (c1[4] - c1[1]).unit;
axis[3] = (c2[2] - c2[1]).unit;
axis[4] = (c2[4] - c2[1]).unit;
return axis;
end;
function dot2d(a, b)
-- dot product for vector2
return a.x * b.x + a.y * b.y;
end;
function collide(shape1, shape2)
local c1, c2 = getCorners(shape1), getCorners(shape2);
local axis = getAxis(c1, c2);
local scalars, mtv = {}, Vector2.new(math.huge, math.huge); -- huge magnitude
local a = nil;
for i = 1, #axis do
for i2, set in pairs({c1, c2}) do
scalars[i2] = {};
for _, point in pairs(set) do
table.insert(scalars[i2], dot2d(point, axis[i]));
end;
end;
local s1max, s1min = math.max(unpack(scalars[1])), math.min(unpack(scalars[1]));
local s2max, s2min = math.max(unpack(scalars[2])), math.min(unpack(scalars[2]));
if s2min > s1max or s2max < s1min then
return false, Vector2.new(); -- mtv is nothing because there isn't collision
end;
-- we are getting the overlap of shape 1 on shape 2 which means we apply the mtv onto shape 2
local overlap = s1max > s2max and -(s2max - s1min) or (s1max - s2min);
if math.abs(overlap) < mtv.magnitude then
-- overlap might be negative to account for proper direction
mtv = axis[i] * overlap;
end;
end;
return true, mtv;
end;
-- example
game:GetService("RunService").RenderStepped:connect(function()
f1.Rotation = f1.Rotation + 1;
f2.Rotation = f2.Rotation - 1;
local doesCollide, mtv = collide(f2, f1);
if doesCollide then
f1.Position = f1.Position + UDim2.new(0, mtv.x, 0, mtv.y);
end;
end);
Right here!
tether = function(frame)
local hb = frame:FindFirstChild("hitbox")
if not hb then print'no hitbox found' out('missing hitbox < error') return end
local v = hb:FindFirstChild("velocity") --Vector3
local m = hb:FindFirstChild("motion") --Vector3
local b = hb:FindFirstChild("bounce") --Vector3
if not (v or m) then print'missingno' out('missing property < error') return end
local data = fg:GetChildren()
--applying physical limitations with seemingly no rotation...--
v.Value = Vector3.new(m.Value.X==1 and math.min(v.Value.X-unit>0 and v.Value.X-unit or (v.Value.X+unit<0 and v.Value.X+unit or 0),terminal_velocity) or m.Value.X,m.Value.Y==1 and math.min(v.Value.Y+gravity,terminal_velocity) or m.Value.Y,0)
for _,obj in next, data do if obj~=frame then check_hit(frame,obj,v) end end
if frame~=player then check_hit(frame,player,v) end
if b then
if b.Value.Z>=1 then b.Value = Vector3.new(b.Value.X,b.Value.Y,b.Value.Z-1) print'delayed' elseif b.Value~=Vector3.new(0,0,0) then print'successful'
v.Value = v.Value + b.Value b.Value = Vector3.new(0,0,0)
end
end
frame.Position = frame.Position + UDim2.new(v.Value.X,0,v.Value.Y,0)
end
