So, here's my problem.

I'm using Magnitude to set up the hitbox of a part of size (10, 1, 10), and the hitbox formed is a circle, not a square. My goal is to not use Touched because Touched is infamously laggy.

There are two enemies, the Flame Mage and the Flame Warrior. The Flame Mage's attack hitbox is defined as...

local p = script.Parent -- Script called from the attack part
local damage = script.Damage -- Value used for dealing damage
local c = 0
while true do
	wait()
	for _, inst in pairs(workspace:GetChildren()) do
		if game:GetService("Players"):GetPlayerFromCharacter(inst) then
			if (inst.HumanoidRootPart.Position - p.Position).Magnitude <= p.Size.Z / 2 then -- The size of this part is 10, and the Vector3 defined is 10, 1, 10, respectively. 10 / 2 = 5, so the player must be within 5 studs of the part to take damage.
				inst.Humanoid:TakeDamage(damage.Value)
				c += 1
			end
		end
	end
	if c > 0 then
		break
	end
end

The Flame Mage's attack is a circle, not a square, so this works. The issue arises when calculating the hitbox of the Flame Warrior's attack.

See, the Flame Warrior uses a square part of size (10, 1, 10). Because this is a square, if I use p.Size.Z / 2, the corners of the part will not register damage. Therefore, I can't use this.

My second thought was to use the Pythagorean Theorem (a^2 + b^2 = c^2). This is because a square can be divided into two triangles, and the value I'm looking for is the distance from the center of the part to its corners. However, this makes the hitbox too large, because that math looks like this:

local p = script.Parent -- Script called from the attack part
local damage = script.Damage -- Value used for dealing damage
local c = 0
while true do
	wait()
	for _, inst in pairs(workspace:GetChildren()) do
		if game:GetService("Players"):GetPlayerFromCharacter(inst) then
			if (inst.HumanoidRootPart.Position - p.Position).Magnitude <= math.sqrt((p.Size.Z / 2)^2 * 2) then
				inst.Humanoid:TakeDamage(damage.Value)
				c += 1
			end
		end
	end
	if c > 0 then
		break
	end
end

In this case, math.sqrt((p.Size.Z / 2)^2 * 2) is the same as a * sqrt(2) when a == b. Plus, this only works when the part is a square. The issue this time is that another circle is created, except that the circle goes beyond the sides of the square, and only meets at the square's vertices.

What I want to know is how I'm supposed to even this out. This is something I haven't been able to wrap my head around for a few days.

3 comments

0

Is this the same as asking for the cartesian equation of a square or a rectangle? If so, this paper will interest you: https://atcm.mathandtech.org/EP2017/contributed/4202017_21456.pdf

0

In any case, checking magnitudes will always create a sphere. What you could instead be doing is check if a part is between x1,y1,z1 and x2,y2,z2 through region3s or otherwise.

0

Region3, raycasting from each side, GetTouchingParts would all work but if you want to solve this mathematically, you would have to get each corner, make a plane, use the dot product to check if it's being touched for each side.