This still happens. I also assumed what was written on the Developer Hub would be correct, but I ran in to this issue when testing on PC. This gave me a headache while undoing recent changes until I diagnosed this as the problem.
On mobile it was working fine, but I don’t know of any way of finding if the button will exist or not - I guess I could rely on a timeout, but that’s not a sufficient solution. This method would preferably act as it says on the Developer hub, or give us a method to detect whether or not the button exists. It seems odd that it will hang indefinitely without warning, I hope this is not intended behaviour and incorrect documentation.
Sanity check the actionName that you want to do a ContextActionService:GetButton() on prior with ContextActionService:GetBoundActionInfo() ie. It’s not nil, has non-nil inputTypes…
For completeness, you should check for the existence of TouchGui.TouchControlFrame prior as well
(an exercise for the reader.)
This still wouldn’t work, even if I sanity check. On PC, there isn’t a button so it will yield indefinitely.
Your suggestion to check for the TouchGui.TouchControlFrame is what I was already doing, but this is still not a sufficient solution as it isn’t at all future proof. The GUI could be renamed or removed entirely at any point in a future update.
You say you’re already doing it, so you know it does work.
(Don’t call GetButton() if no TouchControlFrame in use.)
Nothing is future-proof. But it’s what you can use until they fix this bug.
While this is technically true, you can assume that API methods will be supported for the forseeable future - even if their behaviour changes, it’d be extremely unlikely that the behaviour would break usage of it.
Although the work-around will suffice for now, it can’t be relied upon (whereas API methods can). People will use this work-around and forget about the fact that a future update could easily break it, this bug being fixed could prevent that - which is the whole reason I bumped this old thread.
Behavior changing breakage happens all the time in the real world. Yes, of course in an ideal world you
try to stick to defined APIs, and avoid internals, but after all, this is the Engine Bugs category, where new
Engine Bugs crop up all the time so people need to come up with workarounds in the interim which
means their code has already been broken, forcing them to change their code; just the same as if they
were using not-guaranteed-to-be-stable internals and something changed. As someone who has been
programming for decades, I can tell you that this is more true today than ever–In the past it wasn’t so
easy to push out a software update at the drop of a hat. So nowadays if someone breaks an API for you,
the attitude is “well we can just push out a fix” and “the users of the API can push out their workarounds to
our breakage anyway.” BTW, I appreciate you bumping this thread even if others don’t.
This is still an issue, been scratching my head trying to figure this out until I realized what was going on. Easy to reproduce:
local cas = game:GetService('ContextActionService')
cas:BindAction('TestAction', print, true, Enum.KeyCode.E)
print('before')
local button = cas:GetButton('TestAction')
print('after')
If you test this on any interface that would create a button, “before” and “after” are printed. Otherwise, GetButton yields infinitely.
I think I found a way to see if the button gui exists:
if PlayerGui:FindFirstChild("ContextActionGui") then
local button = ContextActionService:GetButton("Button")
button .Size = UDim2.new(0.3, 0, 0.35, 0) -- i just needed to size but only if the player on mobile
end
This is still occurring today. Was wondering why my BindToRenderStep wasn’t running the function below it, and it turns out that since I’m calling this function on a touchless device, it yields indefinitely. I expect the behavior of this to try and get the button, and if it doesn’t exist, return nil.
Even a wiki page states that it can return nil, but it can never return anything other than the button, if touch controls are present. If this is somehow intentional, clearer documentation would be useful.
Bumping this as the bug is still present and it made me resort to spamming prints all over an 8k line script for an hour or so till i could pin it down to this exact thing.
This issue makes me want to outright avoid using this. It’s simply too hazardous. At the very least this should show a warning after a few seconds so it can be nailed down when it hangs your code.
I’m getting a nil error with :GetButton that I haven’t had happen before, I haven’t edited this script and just found this comment so I’m just guessing the update might have something to do with it
ContextActionService:BindAction("TauntMenu", function(name, state, input)
if state == Enum.UserInputState.Begin then
if script.Parent.Enabled == false then
script.Parent.Enabled = true
else
script.Parent.Enabled = false
end
end
return Enum.ContextActionResult.Pass
end, true, TauntKey, Enum.KeyCode.ButtonR2)
ContextActionService:SetPosition("TauntMenu",UDim2.new(.65,0,0,0))
ContextActionService:GetButton("TauntMenu").Size = UDim2.new(0.35,0,0.35,0)
ContextActionService:SetTitle("TauntMenu", "🔊")
Hi! If you’re testing on a non touch device, a button is never created and GetButton will return nil, like mentioned in the documentation here. Please check if the button exists before trying to change the size or checking if the device is a touch device.
Please note that on any non touch device SetTitle would not have been called as GetButton would hang silently. The behavior is the same, you’re now just correctly seeing the error.