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(
相关产品推荐
相关产品推荐

