I need to know how to make this script run more efficiently
local RayCastCount = 0
local function TowerPlacing(TowerModel, RayCast)
RayCastCount += 1
RayCast = MouseRayCast({TowerModel, Enemies, Towers, PlayerModels})
if RayCast then
TweenService:Create(TowerModel.PrimaryPart, TweenInfo.new(0.125, Enum.EasingStyle.Sine), {CFrame = CFrame.new(RayCast.Position + Vector3.new(0, _G.TowerDataBase.Placing[1].YOffset, 0)) * CFrame.Angles(0, math.rad(PlacingTowerRotation.Value), 0)}):Play()
end
if RayCastCount >= 3 then
RayCastCount = 0
RayCheck(TowerInfoDataBase[TowerModel.Name].Range, TowerModel)
end
end
---Script that calls the function if a tower is placing
The ray check thing looks weird if it is updated every 0.1 seconds
local function RayCheck(RangeValue, Tower)
local Degrees = 36 / RangeValue
local RayCastResult1, RayCastResult2, RayCastResult3
for Degree = Degrees, 360 + 0.001, Degrees do
RayCastResult1 = workspace:Raycast(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), (CFrame.new(Tower.PrimaryPart.Position) * CFrame.Angles(0, math.rad(Degree - 90), 0)).lookVector * RangeValue, RaycastParamsRay)
RayCastResult2 = workspace:Raycast(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), (CFrame.new(Tower.PrimaryPart.Position) * CFrame.Angles(0, math.rad(Degree - 90 + (Degrees/2)), 0)).lookVector * RangeValue, RaycastParamsRay)
RayCastResult3 = workspace:Raycast(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), (CFrame.new(Tower.PrimaryPart.Position) * CFrame.Angles(0, math.rad(Degree - 90 + Degrees), 0)).lookVector * RangeValue, RaycastParamsRay)
if RayCastResult1 or RayCastResult2 or RayCastResult3 then
if RayCastResult1 then
if RayCastResult2 then
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult1.Distance, -Degree), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult2.Distance, -Degree - (Degrees/2)), false, nil, Degree)
if RayCastResult3 then
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult2.Distance, -Degree - (Degrees/2)), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult3.Distance, -Degree - Degrees), false, nil, Degree, true)
else
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult2.Distance, -Degree - (Degrees/2)), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - Degrees), false, nil, Degree, true)
end
else
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult1.Distance, -Degree), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - (Degrees/2)), false, nil, Degree)
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - (Degrees/2)), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - Degrees), false, nil, Degree, true)
end
elseif RayCastResult2 then
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult2.Distance, -Degree - (Degrees/2)), false, nil, Degree)
if RayCastResult3 then
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult2.Distance, -Degree - (Degrees/2)), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult3.Distance, -Degree - Degrees), false, nil, Degree, true)
else
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult2.Distance, -Degree - (Degrees/2)), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - Degrees), false, nil, Degree, true)
end
elseif RayCastResult3 then
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - (Degrees/2)), false, nil, Degree)
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - (Degrees/2)), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RayCastResult3.Distance, -Degree - Degrees), false, nil, Degree, true)
end
else
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - (Degrees/2)), true, nil, Degree)
DrawRangeCircle(Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - (Degrees/2)), Vector3.new(Tower.PrimaryPart.Position.X, RangeY, Tower.PrimaryPart.Position.Z) + GetPointOnCircle(RangeValue, -Degree - Degrees), true, nil, Degree, true)
end
end
end
Then the part which makes the game lag
local function DrawRangeCircle(a, b, c, NoHit, Setup, Degrees, Filler)
local ab, ac, bc = b - a, c - a, c - b;
local abd, acd, bcd = ab:Dot(ab), ac:Dot(ac), bc:Dot(bc)
local Wedge = RangeWedge1
if NoHit == false then
Wedge = RangeWedge2
if (abd > acd and abd > bcd) then
c, a = a, c
elseif (acd > bcd and acd > abd) then
a, b = b, a
end
ab, ac, bc = b - a, c - a, c - b
end
local Right = ac:Cross(ab).unit
local Up = bc:Cross(Right).unit
local Back = bc.unit
local Height = math.abs(ab:Dot(Up))
local w1, w2
if Setup then
w1 = Wedge:Clone()
w2 = Wedge:Clone()
elseif NoHit and not Setup and not Filler then
w1 = RangePartsNoHit[Degrees..1]
w2 = RangePartsNoHit[Degrees..2]
RangePartsHit[Degrees..1].Transparency = 1
RangePartsHit[Degrees..2].Transparency = 1
elseif not NoHit and not Setup and not Filler then
w1 = RangePartsHit[Degrees..1]
w2 = RangePartsHit[Degrees..2]
RangePartsNoHit[Degrees..1].Transparency = 1
RangePartsNoHit[Degrees..2].Transparency = 1
elseif NoHit and not Setup and Filler then
w1 = RangePartsNoHit[Degrees..11]
w2 = RangePartsNoHit[Degrees..12]
RangePartsHit[Degrees..11].Transparency = 1
RangePartsHit[Degrees..12].Transparency = 1
elseif not NoHit and not Setup and Filler then
w1 = RangePartsHit[Degrees..11]
w2 = RangePartsHit[Degrees..12]
RangePartsNoHit[Degrees..11].Transparency = 1
RangePartsNoHit[Degrees..12].Transparency = 1
end
w1.Size = Vector3.new(0.1, Height, math.abs(ab:Dot(Back)))
w1.CFrame = CFrame.fromMatrix((a + b) / 2, Right, Up, Back)
w2.Size = Vector3.new(0.1, Height, math.abs(ac:Dot(Back)))
w2.CFrame = CFrame.fromMatrix((a + c) / 2, -Right, Up, -Back)
if Setup then
if NoHit and not Filler then
w1.Parent = RangePartsNoHit
w2.Parent = RangePartsNoHit
w1.Name = Degrees..1
w2.Name = Degrees..2
w1.Transparency = 1
w2.Transparency = 1
elseif not NoHit and not Filler then
w1.Parent = RangePartsHit
w2.Parent = RangePartsHit
w1.Name = Degrees..1
w2.Name = Degrees..2
w1.Transparency = 1
w2.Transparency = 1
elseif NoHit and Filler then
w1.Parent = RangePartsNoHit
w2.Parent = RangePartsNoHit
w1.Name = Degrees..11
w2.Name = Degrees..12
w1.Transparency = 1
w2.Transparency = 1
elseif not NoHit and Filler then
w1.Parent = RangePartsHit
w2.Parent = RangePartsHit
w1.Name = Degrees..11
w2.Name = Degrees..12
w1.Transparency = 1
w2.Transparency = 1
end
else
w1.Transparency = 0.75
w2.Transparency = 0.75
end
end
Now I have tested it without the 3rd function, and it works fine, but I need the range to be visible and accurate. I now have it updating evey 3 frames, which is the maximum I will make it go to.
I’m just not sure how to make it work more accurately. Using Runservice:BindToRenderStep() for the towerplacing function