跳转至

在这个教程中,我将向您展示如何制作一个火球射击系统。在开始之前,请记住,主要目的是为了向您介绍一些概念,您可以在游戏中应用这些概念。如果您愿意全部复制,那么您可能会遇到问题,并发现它不适合您的游戏。这个教程要求您具备基本的Roblox脚本知识。现在让我们开始吧!

设置中

制作火球

在工作区中添加一个球体。这个球体将成为我们的火球。我们将其命名为“Fire_Ball”。将球的大小设置为您认为合适的值。将球的透明度设置为 1。现在,在球体中添加一个 Fire 对象。在属性窗口中,将热量设置为 0,使其看起来像一个真实的火球,而不是一个被点燃的物体。

without heat

with heat

您还可以更改火焰的颜色。在本教程中,我将使用紫色作为主要颜色,次要颜色为粉色。最终的结果如下:

FireBall

设置对象

Fire_Ball 放置在 ServerStorage 中。在 ServerScriptService 中添加一个 Script,在 StarterPlayerScripts 中添加一个 Local Script,在 ReplicatedStorage 中添加一个 Remote Event。将远程事件的名称更改为 Shooter。我们的资源管理器层次现在如下所示:

explorer

客户端脚本编写

在 “Local Script” 中,我们将使用 UserInputService. 连接一个函数到 InputBegan。在函数中,检查输入类型。获取鼠标位置,并将其与远程事件一起发送到服务器。

local UIS = game:GetService("UserInputService")
local Shooter_Event = game.ReplicatedStorage.Shooter
local Mouse = game.Players.LocalPlayer:GetMouse()

local Clock = 0
local CoolDown = 1 -- 冷却时间长度

UIS.InputBegan:Connect(function(Input, GameProcessed)
    if Input.UserInputType == Enum.UserInputType.MouseButton1 and not GameProcessed then
        if os.clock() > Clock then

            Clock = os.clock() + CoolDown
            local Mouse_Pos = Mouse.Hit.Position -- 获取鼠标在3D世界中指向的位置。
            Shooter_Event:FireServer(Mouse_Pos) -- 使用鼠标位置触发远程事件发送到服务器。

        end
    end
end)

冷却时间

冷却时间用于防止某些任务(例如造成伤害)发生得太快,因此它们类似于冷却时间。尽管这种方法不是传统的 task.wait() 方法,但它更为先进和稳定。os.clock 基于CPU时间,因此它比 task.wait() 提供更稳定和准确的时间,但它用于比较时间而不是让出执行。

"服务器端脚本编写"

在服务器端,我们将连接一个函数到远程事件。在这个函数中,我们将执行以下步骤:

  • 克隆火球,将其位置设置为玩家角色的位置。
  • 设置附件。
  • 设置速度约束。
  • 设置速度矢量。
local Shooter_Event = game.ReplicatedStorage.Shooter
local Sample_Fireball = game.ServerStorage.FireBall

Shooter_Event.OnServerEvent:Connect(function(Player, Mouse_Pos)

    local Character = Player.Character

    local Fireball = Sample_Fireball:Clone()
    Fireball.CanCollide = false
    Fireball.Position = Player.Character.HumanoidRootPart.Position

    -- 创建附件
    local Attachment = Instance.new("Attachment")
    Attachment.Parent = Fireball

    -- 创建速度约束
    local Velocity = Instance.new("LinearVelocity")
    Velocity.Attachment0 = Attachment

    -- 设置速度方向
    local Speed = 50 -- 火球的速度/矢量的长度
    Velocity.MaxForce = 9e6 -- 将最大力设置为9 * 10^6
    local Directional_Vector = (Mouse_Pos - Fireball.Position).Unit * Speed
    Velocity.VectorVelocity = Directional_Vector -- 设置速度

    Velocity.Parent = Fireball
    Fireball.Parent = workspace
    game.Debris:AddItem(Fireball, 3) -- 在3秒后销毁火球
end)

现在,你可以测试它。

test

造成伤害

为了造成伤害,我们将使用“Touched”事件。当火球接触到任何物体时,我们将检查其父级并搜索人形角色。如果成功找到人形角色,那么我们就可以造成伤害。

local Shooter_Event = game.ReplicatedStorage.Shooter
local Sample_Fireball = game.ServerStorage.FireBall

Shooter_Event.OnServerEvent:Connect(function(Player, Mouse_Pos)

    local Character = Player.Character

    local Fireball = Sample_Fireball:Clone()
    Fireball.CanCollide = false
    Fireball.Position = Player.Character.HumanoidRootPart.Position

    -- 创建附件
    local Attachment = Instance.new("Attachment")
    Attachment.Parent = Fireball

    -- 创建速度约束
    local Velocity = Instance.new("LinearVelocity")
    Velocity.Attachment0 = Attachment

    -- 设置速度方向
    local Speed = 50 -- 火球的速度/矢量的长度
    Velocity.MaxForce = 9e6 -- 将最大力设置为9 * 10^6
    local Directional_Vector = (Mouse_Pos - Fireball.Position).Unit * Speed
    Velocity.VectorVelocity = Directional_Vector

    Velocity.Parent = Fireball
    Fireball.Parent = workspace
    game.Debris:AddItem(Fireball,3)

    Fireball.Touched:Connect(function(hit)
        if hit.Parent ~= Character and hit.Parent:FindFirstChild("Humanoid") then
            hit.Parent.Humanoid.Health -= 15
            Fireball:Destroy()
        end
    end)

end)

防止滥用

到目前为止,我们所做的一切看起来完全正常,但仍然存在一个问题!滥用者可以轻松地绕过冷却并大量触发远程事件。为了避免这种情况,我们需要对请求进行服务器端验证。

我们将创建一个表,记录每个玩家的冷却时间。该表将以玩家名称作为索引/键,持续时间作为值。我们将在Players服务的PlayerAddedPlayerRemoving事件中添加和移除玩家的名称。

local Shooter_Event = game.ReplicatedStorage.Shooter
local Sample_Fireball = game.ServerStorage.FireBall

local Players_Cooldown = {}
local CoolDown = 1 -- 冷却持续时间

-- 将玩家名称添加到表中
game.Players.PlayerAdded:Connect(function(Player)
    Players_Cooldown[Player.Name] = 0
end)

-- 从表中移除玩家名称
game.Players.PlayerRemoving:Connect(function(Player)
    Players_Cooldown[Player.Name] = nil
end)

Shooter_Event.OnServerEvent:Connect(function(Player, Mouse_Pos)

    if os.clock() > Players_Cooldown[Player.Name] then

        Players_Cooldown[Player.Name] = os.clock() + CoolDown

        local Character = Player.Character

        local Fireball = Sample_Fireball:Clone()
        Fireball.CanCollide = false
        Fireball.Position = Player.Character.HumanoidRootPart.Position

        -- 创建附件
        local Attachment = Instance.new("Attachment")
        Attachment.Parent = Fireball

        -- 建速度约束
        local Velocity = Instance.new("LinearVelocity")
        Velocity.Attachment0 = Attachment

        -- 设置速度方向
        local Speed = 50 -- 火球的速度/矢量的长度
        Velocity.MaxForce = 9e6 -- 设置最大力为9 * 10^6
        local Directional_Vector = (Mouse_Pos - Fireball.Position).Unit * Speed
        Velocity.VectorVelocity = Directional_Vector

        Velocity.Parent = Fireball
        Fireball.Parent = workspace
        game.Debris:AddItem(Fireball,3)

        -- 造成伤害
        Fireball.Touched:Connect(function(hit)

            if hit.Parent ~= Character and hit.Parent:FindFirstChild("Humanoid") then

                hit.Parent.Humanoid.Health -= 15
                Fireball:Destroy()

            end
        end)
    end
end)

现在,如果你不想要,可以从客户端移除冷却。

结束

这就是全部了!希望你喜欢这个教程并能在你的游戏中使用它。再次提醒,不要简单地复制整个教程。它的设计目的是为了给你一些概念和思路,让你了解如何制作一个火球系统。你的任务是利用这些概念。感谢阅读!