Soo today i thought about making range system similar to TDX, i decided to check if enemy is in range with tower, and if it is i’ll use this code to check if tower can shoot without obstructions
-- Settings
local Radius = 32
local Triangles = 64
local Indicator = workspace.Indicator
local function IsInPolygon(Points: {Vector3}, part: BasePart): boolean
local intersections = 0
local x, y = part.Position.X, part.Position.Z
for i = 1, #Points do
local x1, y1 = Points[i].X, Points[i].Z
local nextVertex = Points[i+1] or Points[1]
local x2, y2 = nextVertex.X, nextVertex.Z
if (y < y1) ~= (y < y2) and x < (x2 - x1)*(y - y1)/(y2-y1)+x1 then
intersections += 1
end
end
return intersections % 2 == 1
end
local function GetFinishPoints(start: Vector3): {Vector3}
local Points = {}
for i = 1, Triangles do
local angle = i * (math.pi*2/Triangles)
Points[i] = start + Vector3.new(math.sin(angle) * Radius, 0, math.cos(angle) * Radius)
end
return Points
end
local function Visualize(Points: {Vector3})
local result
for i, position in Points do
local previousPoint = Points[i - 1] or Points[#Points]
local currentPoint = Points[i]
local nextPoint = Points[i + 1] or Points[1]
local Line = Instance.new("Part")
Line.Name = "Line"..i
Line.Anchored = true
Line.CanCollide = false
Line.CanQuery = false
Line.CastShadow = false
Line.Color = Color3.new(0.333333, 0.666667, 1)
Line.Material = Enum.Material.Neon
Line.Size = Vector3.new(0.5,0.5,(currentPoint - nextPoint).Magnitude)
Line.CFrame = CFrame.lookAt(currentPoint, nextPoint)
Line.Position = (currentPoint:Lerp(nextPoint,0.5))
Line.Parent = script.Parent.Parts
local Line2 = Instance.new("Part")
Line2.Name = "Line"..i
Line2.Anchored = true
Line2.CanCollide = false
Line2.CanQuery = false
Line2.CastShadow = false
Line2.Color = Color3.new(1, 0, 0.498039)
Line2.Material = Enum.Material.Neon
Line2.Size = Vector3.new(4/Triangles,4/Triangles,(script.Parent.Position - currentPoint).Magnitude)
Line2.CFrame = CFrame.lookAt(script.Parent.Position, currentPoint)
Line2.Position = (script.Parent.Position:Lerp(currentPoint,0.5))
Line2.Parent = script.Parent.Parts
end
local result = IsInPolygon(Points, Indicator)
if result then
Indicator.Material = Enum.Material.Neon
else
Indicator.Material = Enum.Material.SmoothPlastic
end
end
local function GetObstacles(start: Vector3, Points: Vector3): {Vector3}
local FixedPoints = {}
for i, position in Points do
local finish
local raycastResult = workspace:Raycast(start, (position - start))
if raycastResult then
finish = raycastResult.Position
end
FixedPoints[i] = finish or position
end
return FixedPoints
end
while true do
script.Parent.Parts:ClearAllChildren()
local Points = GetFinishPoints(script.Parent.Position)
local Fixed = GetObstacles(script.Parent.Position, Points)
Visualize(Fixed)
task.wait(0)
end
I used raycasting algorithm from this and of course some visual checking, i only ask if i can optimize it soo it can run few hundred times per second without performance issues on server, consider that triangle count will be around 16
Here is a video of how system looks for now:
thx for help