In one of my games, there is a cannon feature where players can, pick a player they want to launch a cannon ball at that is in-game, and a cannon will be launched at the chosen player, and they will lose a life.
However, this feature has become broken completely recently, as seen below. Nothing happens!
It’s supposed to function like seen in this video, but after a few uses, the cannon ball just randomly shoots out into the void, not hitting anything. This video was taken in studio, not in-game.
Features Broken:
- In regular games, buying the developer product for the cannon will not put you in the seat for it, and therefore also will not display the necessary targeting UI
- In studio, a few shots of the cannon will result in it not hitting anything, and aiming at totally something random.
I need to get this fixed ASAP. Below is the code:
---- server sided code
--- below is the projectile module code:
local ball = {}
local CFrame_New = CFrame.new
local Vector3_New = Vector3.new
local T = 1;
local Gravity = Vector3_New(0, -workspace.Gravity, 0)
function ball:Create(RootPart:BasePart,Target:BasePart)
local X0 = RootPart.CFrame * Vector3_New(0, 0, 0)
-- calculate the v0 needed to reach mouse.Hit.p
local V0 = (Target.Position - X0 - 0.5*Gravity*T*T)/T;
-- have the ball travel that path
local ball = Instance.new("Part")
ball.Material = Enum.Material.Neon
ball.BrickColor = BrickColor.new("Black")
ball.Shape = Enum.PartType.Ball
ball.Velocity = V0;
ball.CanCollide = false;
ball.CFrame = CFrame_New(X0)
ball.Parent = workspace
return ball
end
return ball
--- below is the code for the cannon script
local currentGunner = nil
local projectile = require(scripts.Modules.projectile)
local rootPart = cannon.Cannon.Barrel.LaunchOrigin
local function calculateServoAngle(hinge,target)
local Turn,Tilt,Roll = hinge.Attachment1.WorldCFrame:ToObjectSpace(CFrame.new(hinge.Attachment0.WorldPosition, target.Position)):ToOrientation()
return math.deg(Turn)-90
end
cannon.Controls.control.ProximityPrompt.Triggered:Connect(function(player: Player)
if gameInfo:GetAttribute("playing") == true then
market:PromptProductPurchase(player,menu.cannon)
local marketConnect
marketConnect = market.PromptProductPurchaseFinished:Once(function(userId: number, productId: number, isPurchased: boolean)
if userId == player.UserId and productId == menu.cannon and isPurchased == true and not cannon.Controls.control.Occupant then
currentGunner = player
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:FindFirstChildOfClass("Humanoid")
cannon.Controls.control:Sit(hum)
clientRemotes.cannonToggle:FireClient(player,true)
cannon.Controls.control.ProximityPrompt.Enabled = false
task.wait(1)
cannon.Controls.control:GetPropertyChangedSignal("Occupant"):Once(function()
if not cannon.Controls.control.Occupant then
print("byebyebye")
clientRemotes.cannonToggle:FireClient(player,false)
currentGunner = nil
cannon.Controls.control.ProximityPrompt.Enabled = true
end
end)
end
end)
else
clientRemotes.notify:FireClient(player,"Cannon Error","You may not attempt to fire the cannon at this time!")
end
end)
serverRemotes.cannon.OnServerEvent:Connect(function(plr:Player,target:Player)
if plr == currentGunner and plr.Team == teams.Lobby then
target = Players:FindFirstChild(tostring(target)) -- make sure target is still in-game
if target and target.Team == teams.Survivors then
local char = target.Character or target.CharacterAdded:Wait()
local hum = char:FindFirstChildOfClass("Humanoid")
local toHit = char:FindFirstChild("Head")
local hinge = cannon.Cannon.Base:FindFirstChildOfClass("HingeConstraint")
if not toHit then clientRemotes.notify:FireClient(plr,"Cannon Failure","Invalid Target!") return end
if hinge then
local angle = calculateServoAngle(hinge,toHit)
hinge.TargetAngle = angle
task.wait(1)
end
local ball = projectile:Create(rootPart,toHit)
sound.CannonLaunch:Play()
debris:AddItem(ball,5)
local char2 = plr.Character or plr.CharacterAdded:Wait()
local hum2 = char2:FindFirstChildOfClass("Humanoid")
hum2.Jump = true
local soundClone = sound.CannonBallExplode:Clone()
soundClone.Parent = ball
--- disable the gui for this here.
ball.Touched:Connect(function(part:BasePart)
if part.Parent == char then
local newExp = Instance.new("Explosion")
newExp.Position = part.Position
newExp.BlastPressure = 0
newExp.BlastRadius = 5
newExp.Parent = workspace
debris:AddItem(newExp)
hitPlr(target)
ball:Destroy()
end
end)
else
clientRemotes.notify:FireClient(plr,"Cannon Failure","Invalid Target!")
end
else
warn(tostring(plr).." is likely exploiting")
end
end)
--- ui/client code
local rs = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local sound = game:GetService("SoundService")
local player = players.LocalPlayer
local gui = script.Parent
local killColor = Color3.fromRGB(255, 0, 0)
local defaultColor = Color3.fromRGB(244, 136, 42)
local target = nil
local function clearPlayers()
for _,i in pairs(gui.Background.ScrollingFrame:GetChildren()) do
if i:IsA("TextButton") then
i:Destroy()
end
end
end
local function changeColor(ignore: TextButton)
for _,i in pairs(gui.Background.ScrollingFrame:GetChildren()) do
if i:IsA("TextButton") and i ~= ignore then
i.BackgroundColor3 = defaultColor
end
end
end
rs.clientRemotes.cannonToggle.OnClientEvent:Connect(function(val:BoolValue)
if val == true then
gui.Enabled = true
for _,p in pairs(players:GetPlayers()) do
if p ~= player and p.Team ~= game:GetService("Teams").Lobby then
local clone = script.Player:Clone()
clone.Name = p.Name
clone.Username.Text = string.sub(p.DisplayName, 1, 20)
clone.Parent = gui.Background.ScrollingFrame
clone.MouseButton1Click:Connect(function()
clone.BackgroundColor3 = killColor
changeColor(clone)
sound["Click/Touch"]:Play()
target = p
end)
end
end
else
gui.Enabled = false
target = nil
clearPlayers()
end
end)
gui.Background.FireButton.MouseButton1Click:Connect(function()
if target ~= nil and players:FindFirstChild(tostring(target)) then
sound["Click/Touch"]:Play()
rs.serverRemotes.cannon:FireServer(target)
gui.Enabled = false
target = nil
clearPlayers()
end
end)
How do I fix this? When the errors mentioned above occur, there is no output.