I have this very frustrating problem with Fireball/Energy Ball projectile scripts. The thing is they work perfectly fine in roblox studio and honestly they work pretty well in game. But sometimes it does this random thing where while holding the ball of energy, it disappears and causes the welding to not destroy as intended. I’ve tried to fix this for a couple of months, trying literally everything that comes to mind. Here is the server script for creating the Fireball and attaching it to the player’s character:
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local fireballConjureEvent = replicatedStorage.Events.FireballConjure
local fireballThrowEvent = replicatedStorage.Events.FireballThrow
local fireballPart = replicatedStorage:WaitForChild(“FireballPart”)
local sounds = replicatedStorage.Sounds
local currentAnimationTrack
local fireballInPlay = false
local fireball
– Function to reset the fireball state for the player
local function resetFireballState()
fireballInPlay = false
if fireball then
– Ensure any Weld attachments are removed
local weld = fireball:FindFirstChild(“FireballWeld”)
if weld then
weld:Destroy()
end
-- Remove any lingering sounds
for _, child in pairs(fireball:GetChildren()) do
if child:IsA("Sound") then
child:Destroy()
end
end
-- Add the fireball to debris for cleanup
game:GetService("Debris"):AddItem(fireball, 0)
fireball = nil -- Set to nil after ensuring cleanup
end
end
– Connection to handle character respawn
local function onCharacterAdded(character)
resetFireballState() – Reset the fireball state for the player
end
– Set up the player to listen for character respawns
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character)
end)
end
– Connect player added event
game.Players.PlayerAdded:Connect(onPlayerAdded)
for _, player in ipairs(game.Players:GetPlayers()) do
onPlayerAdded(player)
end
fireballConjureEvent.OnServerEvent:Connect(function(player)
if fireballInPlay and fireball then
resetFireballState() – Reset any lingering fireball
end
local character = player.Character or player.CharacterAdded:Wait()
if character and character.Name == "Alistair" and not fireballInPlay then
fireballInPlay = true -- Set this to true immediately to prevent duplicate conjuring
-- Load Alistair's animation
local animator = character:FindFirstChild("Humanoid"):FindFirstChild("Animator")
local fireballAnimation = Instance.new("Animation")
fireballAnimation.AnimationId = "rbxassetid://86098413114865"
local conjureAnimationTrack = animator:LoadAnimation(fireballAnimation)
conjureAnimationTrack:Play()
-- Create FireballPart and attach it to Alistair's hand
fireball = fireballPart:Clone()
fireball.Parent = workspace
fireball.CFrame = character.RightHand.CFrame * CFrame.new(0, 0, 0)
-- Attach "FireballStart" sound and play it
local fireballStartSound = sounds.FireballStart:Clone()
fireballStartSound.Parent = fireball
fireballStartSound:Play()
-- Create a Weld to attach the fireball to Alistair's hand
local weld = Instance.new("Weld")
weld.Part0 = character.RightHand
weld.Part1 = fireball
weld.Name = "FireballWeld"
weld.C0 = CFrame.new(0, 0, 0)
weld.Parent = character.RightHand
conjureAnimationTrack:GetMarkerReachedSignal("Hold"):Connect(function()
conjureAnimationTrack:AdjustSpeed(0)
end)
wait(5)
fireballStartSound:Destroy()
local fireTransformationSound = sounds.FireTransformation:Clone()
fireTransformationSound.Parent = fireball
fireTransformationSound:Play()
conjureAnimationTrack:AdjustSpeed(1)
currentAnimationTrack = conjureAnimationTrack
end
end)
fireballThrowEvent.OnServerEvent:Connect(function(player, targetPosition)
local character = player.Character
if character and character.Name == “Alistair” and fireballInPlay and fireball then
– Detach the fireball from Alistair’s hand
local weld = character.RightHand:FindFirstChild(“FireballWeld”)
if weld then
weld:Destroy()
print(“FIREBALL weld attachment has been destroyed.”)
else
warn(“WELD PART FOR FIREBALL NOT FOUND!!!”)
end
fireball.CFrame = character.RightHand.CFrame * CFrame.new(0, 0, 0)
local fireTransformationSound = fireball:FindFirstChild("FireTransformation")
if fireTransformationSound then
fireTransformationSound:Destroy()
end
local fireballLaunchSound = sounds.FireballLaunch:Clone()
fireballLaunchSound.Parent = fireball
fireballLaunchSound:Play()
fireball.Anchored = false
local direction = (targetPosition - fireball.Position).unit
local velocity = Instance.new("BodyVelocity")
velocity.Velocity = direction * 50
velocity.MaxForce = Vector3.new(10000, 10000, 10000)
velocity.Parent = fireball
game:GetService("Debris"):AddItem(fireball, 5)
local launchAnimation = Instance.new("Animation")
launchAnimation.AnimationId = "rbxassetid://128069439618404"
local launchAnimationTrack = character:FindFirstChild("Humanoid"):FindFirstChild("Animator"):LoadAnimation(launchAnimation)
if currentAnimationTrack then
currentAnimationTrack:Stop()
end
launchAnimationTrack:Play()
launchAnimationTrack.Stopped:Wait()
fireballInPlay = false
fireball = nil
end
end)
Then here is the server script inside of the actually Fireball part for when it impacts something or someone:
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local fireballExplosionPart = replicatedStorage:WaitForChild(“FireballExplosionPart”)
local sounds = replicatedStorage.Sounds – Assuming all sounds are in ReplicatedStorage > Sounds
– Detect when the fireball touches another object
script.Parent.Touched:Connect(function(hit)
– Ensure this only triggers once per fireball and not when touching “Alistair”
if not script.Parent:IsDescendantOf(workspace) then return end
-- Check if the touched part belongs to "MacyForcefield" collision group and ignore if true
if hit.CollisionGroup == "MacyForcefield" then
return
end
-- Check if the touched part is part of "Alistair" and ignore if true
local character = hit:FindFirstAncestorOfClass("Model")
if character and character.Name == "Alistair" then
return
end
-- Clone the explosion part and position it at the impact point
local explosionClone = fireballExplosionPart:Clone()
explosionClone.Parent = workspace
explosionClone.CFrame = script.Parent.CFrame -- Position at the point of impact
-- Add "FireballImpact" sound to explosion part and play it
local impactSound = sounds.FireballImpact:Clone()
impactSound.Parent = explosionClone
impactSound:Play()
-- Emit particles from the particle emitter inside the explosion part
local particleEmitter = explosionClone:FindFirstChildOfClass("ParticleEmitter")
if particleEmitter then
particleEmitter.Rate = 100 -- Set emission rate
particleEmitter:Emit(250) -- Emit a burst of particles
end
-- Check if the character has a Humanoid (indicating it's a target humanoid)
local humanoid = character and character:FindFirstChild("Humanoid")
if humanoid then
-- Apply damage only if the target has a humanoid
humanoid:TakeDamage(30)
local TRagdoll = character:FindFirstChild("Ragdoll")
if TRagdoll then
TRagdoll.Value = TRagdoll.Value + 2 -- Activate ragdoll effect
print("Ragdoll activated for target")
else
print("Ragdoll not found for target")
end
-- Apply backward force on the hit character
local primaryPart = character:FindFirstChild("HumanoidRootPart") or character.PrimaryPart
if primaryPart then
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(5000, 5000, 5000) -- Adjusted force for subtle knockback
bodyVelocity.Velocity = -primaryPart.CFrame.LookVector * 20 -- Small backward push
bodyVelocity.Parent = primaryPart
-- Remove the force after a short time
game:GetService("Debris"):AddItem(bodyVelocity, 0.2)
end
end
-- Clean up the explosion part after a short delay
game:GetService("Debris"):AddItem(explosionClone, 2) -- Adjust time as needed
-- Destroy the fireball itself
script.Parent:Destroy()
end)
and here is the Local Script for the specific character:
wait(10.2)
warn(“Fireball script has loaded.”)
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local mouse = player:GetMouse()
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local fireballConjureEvent = replicatedStorage:WaitForChild(“Events”):WaitForChild(“FireballConjure”)
local fireballThrowEvent = replicatedStorage:WaitForChild(“Events”):WaitForChild(“FireballThrow”)
local isAnimating = false
local UserInputService = game:GetService(“UserInputService”)
local TweenService = game:GetService(“TweenService”)
local Camera = workspace.CurrentCamera
local cooldown = 20
local lastActivationTime = 0
local function setupGui()
– Wait for the GUI to load properly, 5
local alistairPowersGui = player:WaitForChild(“PlayerGui”):WaitForChild(“AlistairPowersGui”, 5)
local frame = alistairPowersGui:WaitForChild(“Frame”)
local TPButton = frame:WaitForChild(“FireballButton”)
-- Connect button press logic
TPButton.TouchTap:Connect(function()
buttonPressed = true -- Button was pressed
end)
--print("GUI successfully set up")
end
– Function to activate the fireball animation
local function activateFireballAnimation()
local currentTime = tick()
if character.Name == "Alistair" and not isAnimating and (currentTime - lastActivationTime) >= cooldown then
isAnimating = true
lastActivationTime = currentTime
-- Fire the event to conjure the fireball
fireballConjureEvent:FireServer()
-- Zoom in effect
local originalFieldOfView = Camera.FieldOfView
local zoomedFieldOfView = originalFieldOfView - 20
local zoomTween = TweenService:Create(Camera, TweenInfo.new(0.5), {FieldOfView = zoomedFieldOfView})
zoomTween:Play()
zoomTween.Completed:Wait() -- Wait for the tween to finish
-- Red color correction effect
local colorCorrection = Instance.new("ColorCorrectionEffect")
colorCorrection.Brightness = -0.2
colorCorrection.Contrast = 5.5
colorCorrection.Saturation = -0.5
colorCorrection.TintColor = Color3.new(1, 0, 0) -- Red tint
colorCorrection.Parent = Camera
local redTweenIn = TweenService:Create(colorCorrection, TweenInfo.new(0.5), {Brightness = 0.3})
redTweenIn:Play()
redTweenIn.Completed:Wait()
wait(0.1) -- Short wait for effect duration
local redTweenOut = TweenService:Create(colorCorrection, TweenInfo.new(0.5), {Brightness = 0})
redTweenOut:Play()
redTweenOut.Completed:Wait()
colorCorrection:Destroy() -- Cleanup
-- Zoom back out
local zoomOutTween = TweenService:Create(Camera, TweenInfo.new(0.5), {FieldOfView = originalFieldOfView})
zoomOutTween:Play()
zoomOutTween.Completed:Wait() -- Wait for the tween to finish
end
end
– Variable for target mode
local isTargeting = false
– Function to handle touch input and determine target position in the world using raycasting
local function onTouchInput(inputObject)
if not isTargeting then return end
if inputObject.UserInputType == Enum.UserInputType.Touch then
local ray = Camera:ScreenPointToRay(inputObject.Position.X, inputObject.Position.Y)
local targetPosition = ray.Origin + ray.Direction * 1000 -- Set a large distance for the ray
fireballThrowEvent:FireServer(targetPosition) -- Fire the throw event with the raycast position
isAnimating = false -- Allow reactivation
isTargeting = false -- Exit targeting mode
end
end
– Function to handle PC left-click input
–local function onWorldClick(inputObject)
– if not isTargeting then return end
– if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
– local targetPosition = mouse.Hit.p – Get the position where the mouse clicked
– fireballThrowEvent:FireServer(targetPosition) – Fire the throw event with target position
– isAnimating = false – Allow reactivation
– isTargeting = false – Exit targeting mode
– end
–end
– Handling mouse click for fireball throw
local function onWorldClick()
if isTargeting then
local fireballPosition = mouse.Hit.p – Get the position where the mouse clicked
fireballThrowEvent:FireServer(fireballPosition) – Fire the throw event with target position
isAnimating = false – Allow reactivation after throw
isTargeting = false – Exit targeting mode
end
end
– Connect the mouse click event
– Key press detection for PC
– Key press detection for PC
local function onInputBegan(input, gameProcessed)
if gameProcessed then return end
if character.Name ~= "Alistair" then return end
if input.KeyCode == Enum.KeyCode.F and not isAnimating then
activateFireballAnimation()
-- Start listening for the left click to launch fireball
isTargeting = true
warn("Target mode activated, click to launch.")
end
end
– Connect the input began event for PC
game:GetService(“UserInputService”).InputBegan:Connect(onInputBegan)
– Function to handle button press to activate targeting mode
local function onFireballButtonPressed()
if character.Name == “Alistair” and not isAnimating then
activateFireballAnimation()
-- Start targeting mode
isTargeting = true
warn("Target mode activated, click to aim and throw the fireball.")
end
end
– Set up FireballButton for Mobile
local fireballButton = player.PlayerGui:WaitForChild(“AlistairPowersGui”):WaitForChild(“Frame”):WaitForChild(“FireballButton”)
– Debugging to check if the button is being found
if not fireballButton then
warn(“Fireball Button not found!”)
else
fireballButton.TouchTap:Connect(onFireballButtonPressed)
buttonPressed = true
end
– Reset the script when the player respawns
player.CharacterAdded:Connect(function(newCharacter)
character = newCharacter
isAnimating = false
lastActivationTime = 0
isTargeting = false – Reset targeting mode on respawn
buttonPressed = false
setupGui()
local alistairPowersGui = player:WaitForChild("PlayerGui"):WaitForChild("AlistairPowersGui", 5)
local frame = alistairPowersGui:WaitForChild("Frame")
local TPButton = frame:WaitForChild("FireballButton")
-- Connect button press logic
if UserInputService.TouchEnabled then
-- Reconnect the TouchTap event to handle mobile button press
TPButton.TouchTap:Connect(onFireballButtonPressed)
end
-- Wait for the GUI to load properly, 5
--print("GUI successfully set up")
end)
setupGui()
– Connect to user clicks to trigger targeting
UserInputService.InputBegan:Connect(function(inputObject)
if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
onWorldClick(inputObject)
elseif inputObject.UserInputType == Enum.UserInputType.Touch then
onTouchInput(inputObject)
end
end)
Like i said I can use this ability as much as I want in Studio and it never glitches. But in game it randomly destroys the fireball before it is launched. Then it bugs and keeps the attachment to the player when thrown so the player flies away with the fireball too. PLEASE PLEASE someone help me I’ve been trying to find this solution. I’m the sole creator/owner of my game and I want to make it as good as I possibly can. Thank you!