You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Roblox中如何让火球LocalScript触发sprint脚本扣除玩家stamina?

解决Roblox中两个LocalScript的通信问题(火球发射扣除耐力)

要实现火球发射时扣除Sprint脚本里的玩家耐力,有两种实用的LocalScript通信方案,下面是具体操作:


方法一:用BindableEvent通信(更推荐,脚本解耦性强)

BindableEvent是Roblox里专门用于同一客户端内脚本通信的工具,适合这种场景。

步骤1:创建BindableEvent

在ReplicatedStorage里新建一个BindableEvent,命名为FireballStaminaDeductionEvent。

步骤2:修改Sprint LocalScript(监听扣耐力事件)

在Sprint脚本里添加事件监听,收到信号就扣除对应耐力,同时修正原脚本里的RunService写法错误:

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
-- 新增:获取绑定事件
local fireballStaminaEvent = ReplicatedStorage:WaitForChild("FireballStaminaDeductionEvent")

local SPRINT_SPEED = 25
local DEFAULT_SPEED = 10
local MAXIMUM_STAMINA = 200
local Crouch_Speed = 4
local exhausted_speed = 4

local STAMINA_DECREASE = 0.25
local SPRINT_KEY = Enum.KeyCode.LeftShift
local StaminaAmount = MAXIMUM_STAMINA
local crouching = false
local sprinting = false
local exhausted = true
local FIREBALL_STAMINA_DECREASE = 15

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local cam = workspace.CurrentCamera

local Exterior = script.Parent.Exterior
local Bar = Exterior.Bar

Character:FindFirstChild("HumanoidRootPart").CanCollide = false

-- 新增:监听火球触发的扣耐力事件
fireballStaminaEvent.Event:Connect(function()
    -- 确保耐力足够再扣除
    if StaminaAmount >= FIREBALL_STAMINA_DECREASE then
        StaminaAmount -= FIREBALL_STAMINA_DECREASE
    else
        print("耐力不足,没法发射火球")
    end
end)

UserInputService.InputBegan:Connect(function(Input)
    if Input.KeyCode == SPRINT_KEY and crouching == false then 
        sprinting = true
        game:GetService("TweenService"):Create(cam, TweenInfo.new(0.2, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out), {FieldOfView = cam.FieldOfView*1.125}):Play()
    end
end)

RunService.RenderStepped:Connect(function()
    if StaminaAmount > 0 and not exhausted then
        if sprinting and Humanoid.MoveDirection.Magnitude > 0 and Humanoid.WalkSpeed == SPRINT_SPEED then 
                StaminaAmount -= STAMINA_DECREASE
        end
    end
    
    -- 改成<=0更严谨,避免出现负数耐力
    if StaminaAmount <= 0 then
        sprinting = false
        exhausted = true
        Humanoid.WalkSpeed = exhausted_speed
    end
    
    if StaminaAmount <50 and exhausted==false and sprinting==true    then
        Humanoid.JumpPower = 50
        Humanoid.WalkSpeed = SPRINT_SPEED
    elseif StaminaAmount <50 and exhausted==true then
        Humanoid.WalkSpeed = exhausted_speed
        Humanoid.JumpPower = 20
    end
    
    if StaminaAmount > 50 and exhausted==true then
        Humanoid.JumpPower = 50
        Humanoid.WalkSpeed = DEFAULT_SPEED
        exhausted = false
    end
    
    if StaminaAmount > 50 and Humanoid.MoveDirection.Magnitude > 0 and sprinting==true then
        Humanoid.WalkSpeed = SPRINT_SPEED
        exhausted = false
    end
    
    if StaminaAmount > 0 and Humanoid.MoveDirection.Magnitude == 0 and sprinting==true then
        Humanoid.WalkSpeed= DEFAULT_SPEED
    end
    
    if StaminaAmount < 50 then
        Humanoid.JumpPower = 20
    else
        Humanoid.JumpPower = 50
    end
    
    if StaminaAmount < MAXIMUM_STAMINA then 
        Exterior.Visible = true

        local Formula = (StaminaAmount/MAXIMUM_STAMINA)
        Bar:TweenSizeAndPosition(UDim2.new(1, 0, Formula, 0), UDim2.new(0, 0, 1-Formula, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)

        if  Humanoid.WalkSpeed ~= SPRINT_SPEED then
            StaminaAmount += STAMINA_DECREASE
        end
    else
        Exterior.Visible = false
    end
end)

UserInputService.InputEnded:Connect(function(Input)
    if Input.KeyCode == SPRINT_KEY then
        sprinting = false
        Humanoid.WalkSpeed = DEFAULT_SPEED
        game:GetService("TweenService"):Create(cam, TweenInfo.new(0.2, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out), {FieldOfView = cam.FieldOfView/1.125}):Play()
    end
    
    if Input.KeyCode == SPRINT_KEY and crouching == true then
        Humanoid.WalkSpeed = Crouch_Speed
        game:GetService("TweenService"):Create(cam, TweenInfo.new(0.2, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out), {FieldOfView = cam.FieldOfView}):Play()
    end
end)

步骤3:修改火球LocalScript(触发扣耐力事件)

在火球发射的逻辑里,触发BindableEvent通知Sprint脚本扣耐力:

local fireballModel = game.ReplicatedStorage.Fireball
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 新增:获取绑定事件
local fireballStaminaEvent = ReplicatedStorage:WaitForChild("FireballStaminaDeductionEvent")

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local canFire = true
local maxCharges = 3
local currentCharges = maxCharges
local rechargeTime = 2
local fireballSpeed = 12
local fireballDistance = 20
local FIREBALL_STAMINA_DECREASE = 15

local rightPunchAnimation = Instance.new("Animation")
rightPunchAnimation.AnimationId = "rbxassetid://13525189932"

local leftPunchAnimation = Instance.new("Animation")
leftPunchAnimation.AnimationId = "rbxassetid://13525204331"

local currentHand = "Right"
local punchAnimationPlaying = false

game:GetService("UserInputService").InputBegan:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        print("Fireball")

        if canFire and currentCharges > 0 and not punchAnimationPlaying then
            canFire = false
            currentCharges -= 1
            
            -- 新增:触发扣耐力事件
            fireballStaminaEvent:Fire()
            
            local character = player.Character
            local humanoid = character and character:FindFirstChildOfClass("Humanoid")
            if humanoid then
                punchAnimationPlaying = true
                local punchAnimation
                local handPart
                if currentHand == "Right" then
                    punchAnimation = humanoid:LoadAnimation(rightPunchAnimation)
                    handPart = character:WaitForChild("RightHand")
                    currentHand = "Left"
                else
                    punchAnimation = humanoid:LoadAnimation(leftPunchAnimation)
                    handPart = character:WaitForChild("LeftHand")
                    currentHand = "Right"
                end
                punchAnimation:Play()

                punchAnimation.Stopped:Wait()
                punchAnimationPlaying = false
                canFire = true

                local fireball = fireballModel:Clone()
                fireball.Parent = workspace

                local directionUnitVector = (mouse.Hit.p - handPart.Position).Unit

                fireball.CFrame = CFrame.new(handPart.Position, handPart.Position + directionUnitVector * fireballDistance)
                
                -----damage---------------------------
                local damageAmount = 25
                local hasHit = false

                fireball.Touched:Connect(function(part)
                    if not hasHit then
                        local humanoid = part.Parent:FindFirstChild("Humanoid")
                        if humanoid then
                            if humanoid.Parent.Name ~= player.Name then
                                print("target hit")
                                humanoid:TakeDamage(damageAmount)
                                hasHit=true
                                fireball:Destroy()
                            end
                        end
                    end
                end)
                ---------------------------------------
                
                spawn(function()
                    local startTime = tick()
                    while tick() - startTime < fireballDistance / fireballSpeed do
                        fireball.Position += directionUnitVector * fireballSpeed * (tick() - startTime)
                        wait()
                    end
                    fireball:Destroy()
                end)
            end
        end
    end
end)

spawn(function()
    while true do
        wait(rechargeTime)
        if currentCharges < maxCharges then
            currentCharges += 1
        end
    end
end)

方法二:用ModuleScript共享耐力状态

如果不想用事件,可以把耐力变量放到ModuleScript里,让两个脚本直接共享数据:

步骤1:创建ModuleScript

在ReplicatedStorage里新建ModuleScript,命名为StaminaManager,内容如下:

local StaminaManager = {}

-- 定义常量和初始状态
StaminaManager.MAX_STAMINA = 200
StaminaManager.CurrentStamina = StaminaManager.MAX_STAMINA
StaminaManager.FIREBALL_COST = 15

-- 扣除耐力的方法,返回是否扣除成功
function StaminaManager:Deduct(amount)
    if self.CurrentStamina >= amount then
        self.CurrentStamina -= amount
        return true
    end
    return false
end

-- 恢复耐力的方法,不会超过最大值
function StaminaManager:Restore(amount)
    self.CurrentStamina = math.min(self.CurrentStamina + amount, self.MAX_STAMINA)
end

return StaminaManager

步骤2:修改Sprint LocalScript

替换原有的耐力变量,改用ModuleScript里的状态:

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
-- 引入耐力管理模块
local StaminaManager = require(ReplicatedStorage.StaminaManager)

local SPRINT_SPEED = 25
local DEFAULT_SPEED = 10
local Crouch_Speed = 4
local exhausted_speed = 4

local STAMINA_CHANGE = 0.25
local SPRINT_KEY = Enum.KeyCode.LeftShift
local crouching = false
local sprinting = false
local exhausted = true

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local cam = workspace.CurrentCamera

local Exterior = script.Parent.Exterior
local Bar = Exterior.Bar

Character:FindFirstChild("HumanoidRootPart").CanCollide = false

UserInputService.InputBegan:Connect(function(Input)
    if Input.KeyCode == SPRINT_KEY and crouching == false then 
        sprinting = true
        game:GetService("TweenService"):Create(cam, TweenInfo.new(0.2, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out), {FieldOfView = cam.FieldOfView*1.125}):Play()
    end
end)

RunService.RenderStepped:Connect(function()
    local currentStamina = StaminaManager.CurrentStamina
    if currentStamina > 0 and not exhausted then
        if sprinting and Humanoid.MoveDirection.Magnitude > 0 and Humanoid.WalkSpeed == SPRINT_SPEED then 
                StaminaManager:Deduct(STAMINA_CHANGE)
        end
    end
    
    if currentStamina <= 0 then
        sprinting = false
        exhausted = true
        Humanoid.WalkSpeed = exhausted_speed
    end
    
    if currentStamina <50 and exhausted==false and sprinting==true    then
        Humanoid.JumpPower = 50
        Humanoid.WalkSpeed = SPRINT_SPEED
    elseif currentStamina <50 and exhausted==true then
        Humanoid.WalkSpeed = exhausted_speed
        Humanoid.JumpPower = 20
    end
    
    if currentStamina > 50 and exhausted==true then
        Humanoid.JumpPower = 50
        Humanoid.WalkSpeed = DEFAULT_SPEED
        exhausted = false
    end
    
    if currentStamina > 50 and Humanoid.MoveDirection.Magnitude > 0 and sprinting==true then
        Humanoid.WalkSpeed = SPRINT_SPEED
        exhausted = false
    end
    
    if currentStamina > 0 and Humanoid.MoveDirection.Magnitude == 0 and sprinting==true then
        Humanoid.WalkSpeed= DEFAULT_SPEED
    end
    
    if currentStamina < 50 then
        Humanoid.JumpPower = 20
    else
        Humanoid.JumpPower = 50
    end
    
    if currentStamina < StaminaManager.MAX_STAMINA then 
        Exterior.Visible = true

        local Formula = (currentStamina/StaminaManager.MAX_STAMINA)
        Bar:TweenSizeAndPosition(UDim2.new(1, 0, Formula, 0), UDim2.new(0, 0, 1-Formula, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)

        if  Humanoid.WalkSpeed ~= SPRINT_SPEED then
            StaminaManager:Restore(STAMINA_CHANGE)
        end
    else
        Exterior.Visible = false
    end
end)

UserInputService.InputEnded:Connect(function(Input)
    if Input.KeyCode == SPRINT_KEY then
        sprinting = false
        Humanoid.WalkSpeed = DEFAULT_SPEED
        game:GetService("TweenService"):Create(cam, TweenInfo.new(0.2, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out), {FieldOfView = cam.FieldOfView/1.125}):Play()
    end
    
    if Input.KeyCode == SPRINT_KEY and crouching == true then
        Humanoid.WalkSpeed = Crouch_Speed
        game:GetService("TweenService"):Create(cam, TweenInfo.new(0.2, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out), {FieldOfView = cam.FieldOfView}):Play()
    end
end)

步骤3:修改火球LocalScript

直接调用ModuleScript的方法扣除耐力:

local fireballModel = game.ReplicatedStorage.Fireball
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 引入耐力管理模块
local StaminaManager = require(ReplicatedStorage.StaminaManager)

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local canFire = true
local maxCharges = 3
local currentCharges = maxCharges
local rechargeTime = 2
local fireballSpeed = 12
local fireballDistance = 20

local rightPunchAnimation = Instance.new("Animation")
rightPunchAnimation.AnimationId = "rbxassetid://13525189932"

local leftPunchAnimation = Instance.new("Animation")
leftPunchAnimation.AnimationId = "rbxassetid://13525204331"

local currentHand = "Right"
local punchAnimationPlaying = false

game:GetService("UserInputService").InputBegan:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        print("Fireball")

        -- 先检查耐力是否足够支付火球消耗
        local canAfford = StaminaManager:Deduct(StaminaManager.FIREBALL_COST)
        if canFire and currentCharges > 0 and not punchAnimationPlaying and canAfford then
            canFire = false
            currentCharges -= 1
            
            local character = player.Character
            local humanoid = character and character:FindFirstChildOfClass("Humanoid")
            if humanoid then
                punchAnimationPlaying = true
                local punchAnimation
                local handPart
                if currentHand == "Right" then
                    punchAnimation = humanoid:LoadAnimation(rightPunchAnimation)
                    handPart = character:WaitForChild("RightHand")
                    currentHand = "Left"
                else
                    punchAnimation = humanoid:LoadAnimation(leftPunchAnimation)
                    handPart = character:WaitForChild("LeftHand")
                    currentHand = "Right"
                end
                punchAnimation:Play()

                punchAnimation.Stopped:Wait()
                punchAnimationPlaying = false
                canFire = true

                local fireball = fireballModel:Clone()
                fireball.Parent = workspace

                local directionUnitVector = (mouse.Hit.p - handPart.Position).Unit

                fireball.CFrame = CFrame.new(handPart.Position, handPart.Position + directionUnitVector * fireballDistance)
                
                -----damage---------------------------
                local damageAmount = 25
                local hasHit = false

                fireball.Touched:Connect(function(
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 23:35:10