To be more specific, in a battlegrounds game lets say that you are stunned and you hold F (to block).
When your stunned you obviously can’t block, I want it so when you aren’t stunned anymore (still holding F from when you were stunned) you run the block function. That’s basically what I want to find out
While I don’t know for sure the exact way they achieved that in The Strongest Battlegrounds, I created a proof of concept which would make that possible through the usage of loops and the ContextActionService.
My general thought process for achieving that was the following:
Detect when a player presses the intended keybind
Check if the player is currently stunned
If the player is already stunned when trying to block, yield the code until they are no longer stunned
If the player releases the keybind or is unstunned, allow the code to continue
Before successfully processing the request to activate the block, check one more time if the player is still trying to block (and has not released the keybind while stunned)
Lastly (not included in the code below), make sure the code that handles the request to activate the block ability on the server-side performs additional sanity checks to ensure that the player has met all of the necessary requirements to block, as to avoid situations where exploiters skip past all of the client-sided checks.
In order to test that, I created two scripts:
#1 - LocalScript in the StarterPlayerScripts container that handles the user input and checks for the conditions mentioned above. (This is the most important script out of the two for this example)
#2 - Script in the ServerScriptService, specifically for creating a “Stunned” Attribute for the player and also having a quick way to swap its current value (by walking over a Part in the Workspace). This enables you to quickly simulate what would happen in different scenarios.
To test the scenario outlined in the original post, you would walk over the part once, then begin holding the block keybind. Walk over the part again while still holding down the keybind and then it should warn “Request to activate the Block ability has succeeded” in the Output since the player is no longer stunned and was already holding down the correct key.
I can explain it further if you’d like, but for now, here’s the example code:
#1 - Example LocalScript
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
---
local blockKeybind = Enum.KeyCode.F
local currentlyStunned = false
local tryingToBlock = false
local function updateCurrentlyStunned()
currentlyStunned = player:GetAttribute("Stunned")
print("currentlyStunned Value: "..tostring(currentlyStunned))
player:GetAttributeChangedSignal("Stunned"):Connect(function()
currentlyStunned = player:GetAttribute("Stunned")
warn("New 'Stunned' value is "..tostring(currentlyStunned))
end)
end
if player:GetAttribute("Stunned") then
updateCurrentlyStunned()
else
local temporaryConnection
temporaryConnection = player.AttributeChanged:Connect(function(attributeName)
if attributeName == "Stunned" then
updateCurrentlyStunned()
temporaryConnection:Disconnect()
temporaryConnection = nil
end
end)
end
local function activateBlockAbility(actionName, userInputState, inputObject)
if userInputState == Enum.UserInputState.End then
tryingToBlock = false
print("Player is no longer holding the block keybind")
elseif userInputState == Enum.UserInputState.Begin then
if tryingToBlock == true then return end
tryingToBlock = true
print("Player is trying to block")
if currentlyStunned == true then
warn("Player is currently stunned!")
while true do
if currentlyStunned ~= true then
print("Player is no longer stunned")
break
end
if tryingToBlock ~= true then
print("Player is no longer trying to block")
break
end
RunService.RenderStepped:Wait()
end
end
-- Player is now allowed to block
if tryingToBlock == true then
warn("Request to activate the Block ability has succeeded")
-- Run relevant code here since player is still holding down the key
end
tryingToBlock = false
end
end
ContextActionService:BindAction("Block", activateBlockAbility, true, blockKeybind)
#2 - Example Script
local Players = game:GetService("Players")
local function onPlayerJoin(player)
player:SetAttribute("Stunned", false)
end
for _, player in Players:GetPlayers() do
task.spawn(onPlayerJoin, player)
end
Players.PlayerAdded:Connect(onPlayerJoin)
---
local Part = workspace:FindFirstChild("BlockTestPart")
if not Part then
local newPart = Instance.new("Part")
newPart.Name = "BlockTestPart"
newPart.Anchored = true
newPart.Position = Vector3.new(0, 5, 0)
newPart.Parent = workspace
Part = newPart
end
local debounce = false
Part.Touched:Connect(function(otherPart)
local model = otherPart:FindFirstAncestorOfClass("Model")
if not model then return end
local Player = Players:GetPlayerFromCharacter(model)
if not Player then return end
if debounce == true then return end
debounce = true
local currentStunnedValue = Player:GetAttribute("Stunned")
Player:SetAttribute("Stunned", not currentStunnedValue)
print("Part touched")
task.wait(3)
debounce = false
end)