ContextActionService: Unexpected error while invoking callback

You cant call :Select() on the service it self.

1 Like

So can I have a number variable and add +1 every time the player activates the context?

1 Like

Yes. Remember, variables are just pointers to locations in memory. If the variable is assigned to in a higher scope than the bound action or is created as a global, it’ll be accessible and changed accordingly.

--for example...
local x = 0

local function foo(num: number)
    x += num
end

foo(3)
foo(5)

print(x) --> 8
1 Like

Does it make sense in a scenario like this?

What should normally be done

local x = 0

game.Players.PlayerAdded:Connect(function(Player)
x = x + 1
print(x)
end)

Errors

game.Players.PlayerAdded:Connect(function(Player)
local x = 0
x = x + 1
print(x)
end)

Putting the variable outside the function.

Yes. If you define x outside of the function, it will be incremented as expected. If you define it inside of the function, it’s not accessible by any greater scope level, e.g. the rest of the script, so attempting to use it would give you editor warning “Unknown global” and errors like “Attempt to perform arithmetic (add) on nil and number”.

1 Like

I found this from another post related:

Also, how can I check if like the player is going up or down?

I’m not sure if this would work:

local function NavigateArrowKeys(input)
	if input.UserInputType == Enum.UserInputType or Enum.UserInputType.Gamepad1 then
		if input.KeyCode == Enum.KeyCode.Up then
			-- selectButton(buttons[table.find(buttons, selected_button) + 1])
		elseif input.KeyCode == Enum.KeyCode.Down then
			--selectButton(buttons[table.find(buttons, selected_button) - 1])
		end
	end
end
1 Like

Looks like they used a table for holding their buttons, using user input to change the selection appropriately. That kind of system works, if you don’t want to manually make a table you could tag your buttons and use CollectionService:GetTagged().

It looks like it might be better to use UserInputService instead of ContextActionService, but both can be used because both provide an InputObject holding the KeyCode.

I’m pretty sure Roblox already provides a built-in navigation system for PC, using the # key to toggle it.

I guess you’re right. I’ll use UserInputService.

How can I print out what object the player currently has selected? By using GuiService.SelectedObject?

Edit: Yeah, but it prints out nil like every time.

You’d just do:

print(GuiService.SelectedObject)
--or, for the ancestry:
print(GuiService.SelectedObject:GetFullName())

Edit (in response to your edit):
Try printing it out after using the Roblox navigator (# or \ key). If it still comes out as nil, you might need to make your own custom system.

1 Like

I have no idea what to do right now. My mind is just cluttered. I will try again later, but thank you for explaining.

Wait, so really all I have to do is just use UserInputService/ContextActionService, bind that to Enum.KeyCode.Up or Enum.KeyCode.Down, then set the first button as a parameter in GuiService:Select().

And make a variable that increases by 1 every time the bind runs. Depends on what direction the player is going. Whether it’s up, down, left, or right.

When the player reaches the last button, reset the variable.

I guess that’s it O_O

Yeah, something like this:

local guiService = game:GetService("GuiService")
local uis = game:GetService("UserInputService")

local items = {} --add your selectable items
local currentSelected = 0

local function onInputBegan(input: InputObject, processed: boolean)
	if processed then return nil end
	
	local toAdd = if input.KeyCode == Enum.KeyCode.Down then -1
		elseif input.KeyCode == Enum.KeyCode.Up then 1 else nil
	
	if not toAdd then return nil end
	currentSelected += math.clamp(toAdd, 1, #items)
	
	guiService:Select(items[currentSelected])
end

uis.InputBegan:Connect(onInputBegan)
1 Like

So, can I make the button have a highlight effect like this? Or is there a better way to do it?

SaveSlotsList[selectedKeys].BackgroundColor3 = Color3.fromRGB(255, 255, 0)
task.wait(0.25)
SaveSlotsList[selectedKeys].BackgroundColor3 = Color3.fromRGB(25, 25, 25)

So it was really as simple as having a variable that increases or decreases when the player does a certain input, then plugging that into a table and using GuiService:Select(). And adding some highlight effects. :sweat_smile:

Man, I was overthinking. By the way I put SelectionOrder manually on every button so it works.

I’m assuming there’s more than one way to do it, with the effects as well.

Yeah, you could show the highlight like that. There’s some other ways, like placing a UIStroke with Border mode to show it. All depends on what you think would look better.

1 Like

Yeah, but the button has a UICorner. So I just tweened the color.

Sounds good!

Let me know if you have any more questions or issues. Otherwise, make sure to mark this topic as solved so it can close.

If you want a simpler way to have all your buttons selectable, tag them and then use CollectionService:GetTagged().

1 Like

I’m just going to make console support now. I disabled the default GuiService.AutoSelectGuiEnabled.

By the way, for console, I just used Enum.KeyCode.DPadUp and DPadDown.

1 Like

This is kind of personal, but. What should I name my game? It’s an RPG/party game.