The code is using ContextActionService to handle player inputs for a combat framework. It has bound two actions to the E key; ‘Barrage’, and ‘MegaHit’. ‘MegaHit’ has a higher priority than ‘Barrage’, meaning that if the E key is pressed, it will fire the function associated with ‘MegaHit’. What if we want ‘Barrage’ to be fired instead? When you return Enum.ContextActionResult.Pass in the binding’s associated function, you pass control to the next lower priority binding. When the player presses a key, the highest priority binding’s function is fired, the function is inputHandler which uses a remoteFunction to check if the action that is trying to be used is able to be used (is the action on cooldown?). A remoteFunction is used because data related to cooldowns is stored on the server in a module script. The remoteFunction will return false (meaning the move can’t be used) if the move is on cooldown. If false is returned, the client side will return Enum.ContextActionResult.Pass which should allow the lower priority move to fire instead, right? No, testing this code I have found that Enum.ContextActionResult.Pass is not passing control to the lower priority binding. Why is this so?
ContextActionService priorities are working just fine.
Both actions run when returning ContextActionResult.Pass
local ContextActionService = game:GetService("ContextActionService")
local function InputHandler(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
print(actionName)
--task.wait(.2)
end
return Enum.ContextActionResult.Pass
end
ContextActionService:BindActionAtPriority("Barrage", InputHandler, false, 1, Enum.KeyCode.E)
ContextActionService:BindActionAtPriority("MegaHit", InputHandler, false, 2, Enum.KeyCode.E)
I think it’s the yield that stops the script. If the halt lasts long enough, it continues into the next frame and fresh user input cycle.
What to do?
Perhaps only bind one action to a key, and handle the rest in one take. ContextActionService returns sink result implicitly. I suggest you also return either true or false instead of nil or false in the remote function.
Result
local ContextActionService = game:GetService("ContextActionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage.Remotes.RemoteFunction
local function MegaHit()
print("Mega hit")
end
local function Barrage()
print("Barrage")
end
local function InputHandler(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
local megahit_in_cooldown = remoteFunction:InvokeServer("MegaHit")
if megahit_in_cooldown then
local barrage_in_cooldown = remoteFunction:InvokeServer("Barrage")
if barrage_in_cooldown then return end
Barrage()
else
MegaHit()
end
end
end
ContextActionService:BindAction("Attack", InputHandler, false, Enum.KeyCode.E)