How to do a Cone AOE, like in most Anime Tower Defense games?


So I want to create a Cone AOE. I have locked at posts, but I don’t really understand what’re talking about with angles, and I think someone said to use math.atan2(), but I don’t really understand it. So what I want to do is make a function that detects all enemies inside the cone in the image, keep in mind that the enemies don’t physically exist on the server side, but rather I have their position stored inside of a table with their index being their “speical” name/like the GUID, but it’s the time they were created instead

if you want to avoid all that math stuff you could make a cone mesh and check if anything is within the cone

I don’t really mind the math, I just want a proper explanation on how it works, because the other posts just confused me.

i can’t solve your problem cuz idk how to do that too lol

The area you are looking for is the area encompassed by the tower’s position and the cone between the two points that lie on the edge of a circle. Here is a small illustration of what you are looking for:

image

T is going to be the position of your tower, or the midpoint of your circle (assume it’s facing north). E_1 and E_2 are the left and right endpoints of the cone you are wanting to check; the farther apart they are, the more your tower will be able to see. Of course, you want to find the enemies in area A. r is the radius of the circle, or the distance at which your tower can see enemies. Theta (ϴ) is the central angle, or the degree with which you want your tower to be able to see enemies.

The line s has a fancy name. It’s referred to as the arc length of the circle with radius r and central angle ϴ, and it is calculated by s = 2πr × ϴ/360.

With that out of the way, this is what you are looking for, which I will sum up below.

To validate whether or not an enemy is inside your tower’s view radius, we need to know how to determine if a point (x, y) inside a circle is contained within the area formed between the arc length and the midpoint T of the circle. To do that, we have to verify that

  1. the point lies within the central angle, or lies between the lines formed from T to E_1 and T to E_2, which we can call S and E
  2. the point lies within the radius of the circle

We can convert to polar coordinates to check. Let Tx and Ty be the x and y position of the circle’s midpoint. This is where the math.atan2 function comes in. Then,

  • R = sqrt((X - tX)^2 + (Y - tY)^2)
  • A = atan2(Y - tY, X - tX)

If R < r, then we know the point is in the circle. Then, if S < E, then we know the point is inside the area A if S < A < E. If S > E, then there are two possible scenarios: if A > S or A < E, then the point lies inside the area A. All other cases mean the point is outside area A.

I’m not going to write the script for you, but here’s everything you need.

1 Like

Your cone is really just a restricted area of a circle. The AOE attack will first collect all players in your given radius with WorldRoot:GetPartBoundsInRadius. Make sure to filter for living players. Once you have these players, you need only check the angle of the direction to the attacked from the attacker against the direction of the attack. Having done these things satisfies two conditions:

  1. The attacked are within a certain angle of the attack direction
  2. The attacked are within a certain distance of the attack.

This effectively draws your cone.

Now, assuming the attack originates from the attacker and occurs in forward-facing direction of the attacker:

local function calculateAttackAngle(attacker: Entity, attackee: Entity): number
    local attackerCFrame = attacker:GetPivot()
    local attackeeCFrame = attackee:GetPivot()
    
    -- Eliminate elevation from the equation
    local attackerPositionXZ = attackerCFrame.Position * Vector3.new(1, 0, 1)
    local attackeePositionXZ = attackeeCFrame.Position * Vector3.new(1, 0, 1)

    local attackeeDirection = (attackeePositionXZ - attackerPositionXZ).Unit
    local angleRadians      = attackeeDirection:Angle(attackerCFrame.LookVector)

    return math.deg(angleRadians)
end

Use the above function to verify that the player is within the desired angle of your cone

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.