Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Why is this Fireball script not working?

Asked by
awfulszn 394 Moderation Voter
8 years ago

Okay, I am making a new game and I want a Fireball to shoot out and kill somebody when the letter F is pressed , but, 2 problems, when I press 'F' the fireball just stays in one place, and secondly, it does not kill somebody when it touches them. Here is the script:

Player = game.Players.LocalPlayer
Char = Player.Character
Torso = Char.Torso
Mouse = Player:GetMouse()
Attack = false

function onKeyDown(key)
    Attack = false
    key = key:lower()
    if key == "f" and Attack == false then
        Attack = true
        print("Fireball successful!")
        Ball = Instance.new("Part")
        Ball.Parent = workspace
        Ball.Shape = "Ball"
        Ball.Size = Vector3.new(5,5,5)
        Ball.BrickColor = BrickColor.new("Really red")
        Ball.Transparency = 0.4
        Ball.TopSurface = 0
        Ball.BottomSurface = 0
        Ball.CFrame = Torso.CFrame * CFrame.new(0,0.5,-5)
        Bv = Instance.new("BodyVelocity")
        Bv.Parent = Ball
        Bv.maxForce = Vector3.new(math.huge,math.huge,math.huge)
        Bv.velocity = Torso.CFrame.lookVector * 100
        game.Debris:AddItem(Ball,4)
        wait(3)
        Attack = false

    end
end
Mouse.KeyDown:connect(onKeyDown)

I hope this can be fixed, thanks.

0
Well where is the kill script? dragonkeeper467 453 — 8y
0
Any errors in the developer console? General_Scripter 425 — 8y
0
No kill script, and no errors what so ever awfulszn 394 — 8y
0
I hate no error problems. Vezious 310 — 8y

1 answer

Log in to vote
2
Answered by
Legojoker 345 Moderation Voter
8 years ago

Skip to the bottom if you just want the working code, but if you want to understand why your script didn't work, read the analysis below. I explain things that aren't necessarily errors as well, so some things will work, I just prefer a differing method. I changed some variables to make them shorter, sorry.

Use local whenever you define a variable (not when you call it again since it's already defined). It generally helps the script lag less, though the effect is minimal unless you call the variable a lot. It's just a good habit to get into.

The character will presumably die (especially if you're throwing a bunch of deadly fireballs around) so you'll need an update for characters of players. The first character won't cut it!

You have a boolean that keeps the player from spamming fireballs, except that you make it false as soon as the function runs, so it's essentially useless. The other two portions of the boolean are ok, and definition was ok.

You are making this ball fly at the speed of sound; I doubt anyone can even see it. I personally find Body-userdata things and the Touched event to be unreliable. Because of this, I tend to CFrame everything that moves. I know a lot of people like Lerp. I've never been a fan; I just write out something similar.

You lack a kill script. This is the part where I say "You're giving the client too much power" because I'm a FilteringEnabled fanatic. Personally, I would add a RemoteEvent for this thing. You'll see what I mean in the final code.

Now, you could make this code even more efficient than what I did by having the client project the object since it will be less of a burden to the server, with the server giving position values for the ball, but that isn't really what you asked for, so I'm going to give you the object being spawned in Workspace by the server.

Add this portion to the Server Script.

local cDownTab = {}
local range = 100 -- This is in studs.
local speed = 90 -- This is in studs per second.
local fps = 20 -- This is how many times your fireball position is
-- updated a second. Higher values may cause your speed lag, especially 
-- when more balls are in-game. You can solve this by making 
-- graphics local but keeping game logic server controlled.
local intialTrans = .4

function checkFireBall(obj,plrN)
    if obj then
        for _,v in pairs(game.Players:GetChildren()) do
            if v.Name~=plrN and v.Character then
                local torso = v.Character:FindFirstChild("Torso")
                local humanoid = v.Character:FindFirstChild("Humanoid")
                if torso and humanoid and humanoid.Health>0 and (torso.Position-obj.Position).magnitude<obj.Size.X/2 then
                    humanoid.Health = 0
                end
            end
        end
    end
end

game.Workspace.Caller.OnServerEvent:connect(function(plr,arg)
    if arg[1] == "Fireball" and arg[2] then
        local plrN = plr.Name
        if not cDownTab[plrN] then
            if plr.Character then
                local humanoid = plr.Character:FindFirstChild("Humanoid")
                local torso = plr.Character:FindFirstChild("Torso")
                if humanoid and humanoid.Health>0 and torso then
                    local Ball = Instance.new("Part")
                    Ball.Parent = game.Workspace
                    Ball.Shape = "Ball"
                    Ball.Size = Vector3.new(5,5,5)
                    Ball.BrickColor = BrickColor.new("Really red")
                    Ball.Transparency = intialTrans
                    Ball.TopSurface = 0
                    Ball.BottomSurface = 0
                    Ball.Anchored = true
                    Ball.CanCollide = false
                    Ball.CFrame = torso.CFrame*CFrame.new(0,0.5,-5)
                    print("Fireball started.")
                    local vectorCalc = (arg[2].p-Ball.Position).unit
                    print("Arg", arg[2].p, "Pos", Ball.Position, "Calc", vectorCalc)
                    coroutine.resume(coroutine.create(function()
                        checkFireBall(Ball,plrN) -- Check its initial position.
                        for i = 0,range*fps/speed do
                            Ball.CFrame = CFrame.new(Ball.Position)*CFrame.new(vectorCalc*speed/fps)
                            checkFireBall(Ball,plrN)
                            wait(1/fps)
                        end
                        for i = .1,.9,.1 do
                            Ball.Transparency = intialTrans+((1-intialTrans)*i)
                            wait()
                        end
                        Ball:Destroy()
                    end))
                    cDownTab[plrN] = true
                    wait(3)
                    print("Fireball successful!")
                    cDownTab[plrN] = nil
                end
            end 
        end
    end
end)

Add this portion to the Client Script, like in the StarterPlayerScripts.

local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()

mouse.KeyDown:connect(function(key)
    if key:lower() == "f" then
        game.Workspace.Caller:FireServer({"Fireball",mouse.Hit})
    end
end)

You will need a RemoteEvent that looks like this in Workspace in order for this code to work. Hope this helped, and if it did, don't forget to upvote!

0
Can you show me a print screen of where everything goes? awfulszn 394 — 8y
0
There is an error: 10:51:43.852 - Caller is not a valid member of Workspace 10:51:43.853 - Script 'Players.Player.PlayerScripts.LocalScript', Line 6 10:51:43.854 - Stack End awfulszn 394 — 8y
0
Nvm about that now xD But the fireball does not shoot awfulszn 394 — 8y
0
Alright, I'll make a print screen of all the userdata. I tested it repeatedly so I'm pretty confident about its functionality. Make sure you're testing using the Server + Players method INSTEAD of the Play Solo method - play solo sucks. http://prntscr.com/8us40b Legojoker 345 — 8y
Ad

Answer this question