What are you not satisfied with?
This code is for my automatic cannon I’m working on. I want to make it as efficient as possible, and I am looking for some feedback on it.
How does the code work?
- The player clicks a button on the cannon that says “Fire”
- A part is created just outside of the barrel.
- An explosion is created for the ball to move
- A CannonBallExplosionScript is cloned to the ball
- Every time the cannon fires, there is a counter script that counts how many cannon balls have been fired, this number is stored in an IntValue and is displayed on the cannon.
- After a set number of cannon ball fires, the cannon destroys.
What potential improvements have you considered?
- The cannon currently only works in four directions, and I was trying to figure out an easy way to make it work in any direction.
- There is usually a lot of lag whenever I run it.
- There is an invisible barrier around the cannon so players don’t get launched. A non-collision constraint is created in the cannonball to prevent it from colliding with the barrier.
Code:
LaunchScript:
local minPower = script.Parent.Parent:GetAttribute("MinPower")
local maxPower = script.Parent.Parent:GetAttribute("MaxPower")
local stop = script.Parent.Parent:GetAttribute("Break")
local initialWaitTime = script.Parent.Parent:GetAttribute("InitialWaitTime")
local started = false
local click = script.Parent.ClickDetector
function shoot()
local power = math.random(minPower,maxPower)
local oLeft = script.Parent.Parent:GetAttribute("OffsetLeft")
local oRight = script.Parent.Parent:GetAttribute("OffsetRight")
script.Parent.Parent.Counter.CannonBalls.Value = script.Parent.Parent.Counter.CannonBalls.Value + 1
local ball = Instance.new("Part",script.Parent.Parent)
ball.Name = "CannonBall"
ball.Shape = "Ball"
ball.Size = Vector3.new(2,2,2)
ball.BrickColor = BrickColor.Black()
ball.CastShadow = false
ball.Material = "Metal"
ball.AssemblyLinearVelocity = Vector3.new(0,0,math.random(oLeft,oRight))
local barrel = script.Parent.Parent.Barrel.Position
local base = script.Parent.Parent.Base
local explosion = Instance.new("Explosion",ball)
explosion.ExplosionType = "NoCraters"
explosion.DestroyJointRadiusPercent = 0
explosion.BlastRadius = 2
explosion.BlastPressure = power*10000000
if base.Orientation == Vector3.new(0,0,0) then
ball.Position = Vector3.new(barrel.X+7.05,barrel.Y+2.6,barrel.Z)
explosion.Position = Vector3.new(ball.Position.X-0.1,ball.Position.Y-0.1,ball.Position.Z)
elseif base.Orientation == Vector3.new(0,180,0) then
ball.Position = Vector3.new(barrel.X-7.05,barrel.Y+2.6,barrel.Z)
explosion.Position = Vector3.new(ball.Position.X+0.1,ball.Position.Y-0.1,ball.Position.Z)
elseif base.Orientation == Vector3.new(0,-90,0) then
ball.Position = Vector3.new(barrel.X+0.5,barrel.Y+2.6,barrel.Z+10)
explosion.Position = Vector3.new(ball.Position.X,ball.Position.Y-0.1,ball.Position.Z-0.1)
elseif base.Orientation == Vector3.new(0,90,0) then
ball.Position = Vector3.new(barrel.X+0.5,barrel.Y+2.6,barrel.Z-10)
explosion.Position = Vector3.new(ball.Position.X,ball.Position.Y-0.1,ball.Position.Z+0.1)
else
error("Incompatible orientation! Orientation.X and Orientation.Z must be set to 0, while Orienation.Y must be either 0, 180, -90, or 90!")
end
local noCollisionConstraint = Instance.new("NoCollisionConstraint")
noCollisionConstraint.Parent = ball
noCollisionConstraint.Part0 = ball
noCollisionConstraint.Part1 = script.Parent.Parent.Barrier.Front
local cloneScript = script.Parent.Parent.CannonBallExplosionScript:Clone()
cloneScript.Disabled = false
cloneScript.Parent = ball
end
click.MouseClick:Connect(function()
if started == true then return end
started = true
wait(initialWaitTime)
local delayTime = script.Parent.Parent:GetAttribute("DelayTime")
local maxBullets = script.Parent.Parent:GetAttribute("MaxBullets")
while wait(delayTime) do
shoot()
if script.Parent.Parent.Counter.CannonBalls.Value > maxBullets and stop == true then
script.Parent.BrickColor = BrickColor.Red()
script.Parent.Parent.Barrier:Destroy()
for _, part in pairs(script.Parent.Parent:GetChildren()) do
if part.ClassName == "Part" or part.ClassName == "UnionOperation" then
part.Anchored = false
end
end
wait(3)
script.Parent.Parent:Destroy()
break
end
end
end)
CannonBallExplosionScript:
local ball = script.Parent
wait(0.3)
script.Parent.Touched:Connect(function(t)
if t.Name ~= "CannonBall" then
local explosion = Instance.new("Explosion",game.Workspace)
explosion.Position = ball.Position
explosion.ExplosionType = "NoCraters"
explosion.BlastRadius = 12
explosion.BlastPressure = 100000
ball:Destroy()
end
end)
CounterScript:
local v = script.Parent.CannonBalls
script.Parent.SurfaceGui.TextLabel.Text = v.Value
v.Changed:Connect(function()
script.Parent.SurfaceGui.TextLabel.Text = v.Value
end)
Any suggestions would be strongly appreciated, feel free to ask any questions!