ContextActionService: Unexpected error while invoking callback

					if table.find(GuiObjects, button) then
							StartHighlight:Play()
							StartHighlight.Completed:Wait()
							EndHighlight:Play()
							EndHighlight.Completed:Wait()
						end

That’ll highlight it and then immediately de-highlight it. You also need to use different tweens for different buttons.

I looped through all of the buttons and applied the same tweens.

Alright.

Ok, so, what doesn’t work about your code currently?

Can you also send the full updated script?

local ContextActionService = game:GetService('ContextActionService')
local GuiService = game:GetService('GuiService')

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvents = ReplicatedStorage:FindFirstChild("RemoteEvents")
local RegisterSlot = RemoteEvents:WaitForChild("RegisterSlot")
local SetSlotData = RemoteEvents:WaitForChild("SetSlotData")

local UserInputService = game:GetService("UserInputService")

local Keybind = nil

local hasPrompted = false

local debounce = false

local UserInputs = {}

if UserInputService.KeyboardEnabled then
	Keybind = "Press "..UserInputService:GetStringForKeyCode(Enum.KeyCode.M)
elseif UserInputService.TouchEnabled then
	Keybind = "Press anywhere"
elseif UserInputService.GamepadEnabled then
	Keybind = "Press "..UserInputService:GetStringForKeyCode(Enum.KeyCode.ButtonA)
end

local TweenService = game:GetService("TweenService")

local SoundService = game:GetService("SoundService")
local InterfaceSounds = SoundService.InterfaceSounds
local TypewriterSound = InterfaceSounds.TypewriterSound
local PromptSound = InterfaceSounds.PromptSound
local HoverSound = InterfaceSounds.HoverSound
local ButtonSound = InterfaceSounds.ButtonSound
local NavigateSound = InterfaceSounds.NavigateSound
local InterfaceMusic = SoundService.InterfaceMusic
local DesertOST = InterfaceMusic["Desert - OST"]

local Player = game.Players.LocalPlayer
local PlayerGui = Player.PlayerGui

local Interface = PlayerGui.Interface

local Main = Interface.Main
local Title = Interface.Title
local SaveSlots = Interface.SaveSlots

local Searchbar = SaveSlots.Searchbar

local SaveSlotsList = {}

for i = 1, 5 do -- Loop through the number of save slots.
	table.insert(SaveSlotsList, SaveSlots["Slot"..tostring(i)])
end

local Scripture = Main.Scripture

local GameName = Title.GameName
local InputText = Title.InputText

local MessageTable = {
	"So... you are new around here?",
	"Time to show you the ropes I guess...",
	Player.DisplayName.."... you are the light.",
	"Go...",
}

function Typewriter(String)
	for i = 1, #String do
		TypewriterSound:Play()
		Scripture.Text = string.sub(String, 1, i)
		task.wait(0.1)
	end
end

warn("Script starting...")

for i, text in pairs(MessageTable) do
	Typewriter(text)
	task.wait(2)
end

Scripture.Text = ""

local OpeningScreen = TweenService:Create(
	Title,
	TweenInfo.new(2),
	{BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		BackgroundTransparency = 0
	}
)

local GameNameFade = TweenService:Create(
	GameName,
	TweenInfo.new(3),
	{TextTransparency = 0}
)


local InputTextFadeIn = TweenService:Create(
	InputText,
	TweenInfo.new(2),
	{TextTransparency = 1}
)


local InputTextFadeOut = TweenService:Create(
	InputText,
	TweenInfo.new(2),
	{TextTransparency = 0}
)


task.wait(3)

OpeningScreen:Play()
GameNameFade:Play()

InputText.Text = Keybind

InputTextFadeOut:Play()

DesertOST:Play()

task.spawn(function()
	while true do
		InputTextFadeIn:Play()
		InputTextFadeIn.Completed:Wait()
		InputTextFadeOut:Play()
		InputTextFadeOut.Completed:Wait()
	end
end)



UserInputService.InputBegan:Connect(function(Input, gameProcessedEvent)
	if gameProcessedEvent then return end
	if Input.UserInputType == Enum.UserInputType.Keyboard then -- If the user is using a keyboard.
		if Input.KeyCode == Enum.KeyCode.M then
			if hasPrompted == false then
				hasPrompted = true
				PromptSound:Play()
				SaveSlots:TweenPosition(UDim2.new(0.5, 0, 0.5, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 2)
			end
		end
	elseif Input.UserInputType == Enum.UserInputType.Touch then -- If the user is using a touch screen.
		UserInputService.TouchTap:Connect(function()
			if hasPrompted == false then
				hasPrompted = true
				PromptSound:Play()
				SaveSlots:TweenPosition(UDim2.new(0.5, 0, 0.5, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 2)
			end
		end)
	elseif Input.UserInputType == Enum.UserInputType.Gamepad1 then -- If the user is using a gamepad.
		if Input.KeyCode == Enum.KeyCode.ButtonA then
			if hasPrompted == false then
				hasPrompted = true
				PromptSound:Play()
				SaveSlots:TweenPosition(UDim2.new(0.5, 0, 0.5, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 2)
			end
		end
	end
end)


task.spawn(function()
	while true do
		task.wait()
		for i, child in pairs(SaveSlotsList) do

			local ChangeButtonProperties = TweenService:Create(
				child,
				TweenInfo.new(0.25),
				{Size = UDim2.new(1, 0, 0.175, 0), BackgroundColor3 = Color3.fromRGB(0, 206, 255)}
			)

			local RevertButtonProperties = TweenService:Create(
				child,
				TweenInfo.new(0.25),
				{Size = UDim2.new(0.8, 0, 0.15, 0), BackgroundColor3 = Color3.fromRGB(25, 25, 25)}
			)
			
			child.MouseEnter:Connect(function()
				HoverSound:Play()
				ChangeButtonProperties:Play()
				ChangeButtonProperties.Completed:Wait()
			end)

			child.MouseLeave:Connect(function()
				RevertButtonProperties:Play()
				ChangeButtonProperties.Completed:Wait()
			end)
			
			child.MouseButton1Click:Connect(function()
				ButtonSound:Play()
				if not debounce then
					debounce = true
					RegisterSlot:FireServer(child.Name)
					task.wait(3)
					debounce = false
				end
			end)
		end
	end
end)


task.spawn(function()
	local selectedKey = 0
	UserInputService.InputBegan:Connect(function(Input, gameProcessedEvent)
		if gameProcessedEvent then return end
		if Input.UserInputType == Enum.UserInputType.Keyboard then
			local index = if Input.KeyCode == Enum.KeyCode.Down then 1
				elseif Input.KeyCode == Enum.KeyCode.Up then -1 else nil

			if not index then return nil end
			selectedKey = math.clamp(selectedKey + index, 1, #SaveSlotsList)
		
			NavigateSound:Play()
			GuiService:Select(SaveSlotsList[selectedKey])

			local StartHighlight = TweenService:Create(
				SaveSlotsList[selectedKey],
				TweenInfo.new(0.25),
				{BackgroundColor3 = Color3.fromRGB(0, 206, 255)}
			)

			local EndHighlight = TweenService:Create(
				SaveSlotsList[selectedKey],
				TweenInfo.new(0.25),
				{BackgroundColor3 = Color3.fromRGB(25, 25, 25)}
			)

			task.spawn(function()
				local MouseLocation = nil
				local GuiObjects = nil

				while true do
					task.wait(1)
					MouseLocation = UserInputService:GetMouseLocation()
					GuiObjects = PlayerGui:GetGuiObjectsAtPosition(MouseLocation.X, MouseLocation.Y)
					for i, button in pairs(SaveSlotsList) do
						if table.find(GuiObjects, button) then
							StartHighlight:Play()
							StartHighlight.Completed:Wait()
							EndHighlight:Play()
							EndHighlight.Completed:Wait()
						end
					end
				end
			end)

		elseif Input.UserInputType == Enum.UserInputType.Gamepad1 then
			local index = if Input.KeyCode == Enum.KeyCode.DPadDown then 1
				elseif Input.KeyCode == Enum.KeyCode.DPadUp then -1 else nil

			if not index then return nil end
			selectedKey = math.clamp(selectedKey + index, 1, #SaveSlotsList)

			NavigateSound:Play()
			GuiService:Select(SaveSlotsList[selectedKey])

			local StartHighlight = TweenService:Create(
				SaveSlotsList[selectedKey],
				TweenInfo.new(0.25),
				{BackgroundColor3 = Color3.fromRGB(0, 206, 255)}
			)

			local EndHighlight = TweenService:Create(
				SaveSlotsList[selectedKey],
				TweenInfo.new(0.25),
				{BackgroundColor3 = Color3.fromRGB(25, 25, 25)}
			)

			task.spawn(function()
				local MouseLocation = nil
				local GuiObjects = nil

				while true do
					task.wait(1)
					MouseLocation = UserInputService:GetMouseLocation()
					GuiObjects = PlayerGui:GetGuiObjectsAtPosition(MouseLocation.X, MouseLocation.Y)
					for i, button in pairs(SaveSlotsList) do
						if table.find(GuiObjects, button) then
							StartHighlight:Play()
							StartHighlight.Completed:Wait()
							EndHighlight:Play()
							EndHighlight.Completed:Wait()
						end
					end
				end
			end)
		end
	end)
end)


task.spawn(function()
	Searchbar:GetPropertyChangedSignal("Text"):Connect(function()
		local preferredText = string.lower(Searchbar.Text)
		for i, slot in pairs(SaveSlotsList) do
			if slot:IsA("TextButton") then
				slot.Visible = string.find(string.lower(slot.Name), preferredText, 1, true)
			end
		end
	end)
end)



task.spawn(function()
	SetSlotData.OnClientEvent:Connect(function(slotData, attributeData)
		local stageTextFormat = "Lv. "..tostring(slotData[1])..", Mage"

		for i, child in pairs(SaveSlotsList) do
			if child.Name == attributeData[1] then
				child.Level.Text = stageTextFormat
				child:SetAttribute("ChosenSlot", child.Name)
			end
		end
	end)
end)

Yeah, so really what I’m trying to do is stop the button from changing back to it’s default color when you use arrow key inputs on the button while hovering over it, if that makes sense.

Ok, that script is going to cause a tonne of memory leaks.

You’re constantly creating connections without ever disconnecting them. This will eat up your game’s memory and eventually cause a crash. You should only create connections for each button once and disconnect them after they are no longer needed. Consider using :Once() if you only need it to run once.

1 Like

So is looping through all the buttons a bad idea?

It’s not a bad idea, just don’t create new connections every time. They’ll build up in memory. Create connections once for each button.

Uh, what’s a connection? For clarification. I may have forgotten.

Like this:

local Connection = Part.Touched:Connect(function(Hit)

end)

Connection:Disconnect()

This iteration, you are constantly creating connections (anywhere you used :Connect()) and new tweens. Create them once and use them appropriately after that. Maybe store them in a dictionary.

1 Like

OHHHHHH

that makes so much sense now!

I’m gonna redo the whole thing.

Yeah, but if I move the Tween variables outside of the for loop, I can no longer access the instance ‘child’


			local ChangeButtonProperties = TweenService:Create(
				child,
				TweenInfo.new(0.25),
				{Size = UDim2.new(1, 0, 0.175, 0), BackgroundColor3 = Color3.fromRGB(0, 206, 255)}
			)

			local RevertButtonProperties = TweenService:Create(
				child,
				TweenInfo.new(0.25),
				{Size = UDim2.new(0.8, 0, 0.15, 0), BackgroundColor3 = Color3.fromRGB(25, 25, 25)}
			)

Set them up in an initial iteration and store them in a dictionary.

local tweens: {[Instance]: {["Highlight"]: Tween, ["Unhighlight"]: Tween}} = {}

for _, object: Instance in next, selectableObjects, nil do
    tweens[object] = {
        ["Highlight"] = TweenService:Create(--[[...]]),
        ["Unhighlight"] = TweenService:Create(--[[...]])
    }
end

--then, you can just do...
tweens[object].Highlight:Play()
tweens[object].Unhighlight:Play()
--as needed
1 Like

That solution is pretty smart. Thanks. So is this better?

		for i, child in pairs(SaveSlotsList) do
			SlotTweens[child] = {
				["Highlight"] = TweenService:Create(
					child,
					TweenInfo.new(0.25),
					{Size = UDim2.new(1, 0, 0.175, 0), BackgroundColor3 = Color3.fromRGB(0, 206, 255)}
				),
				["Unhighlight"] = TweenService:Create(
					child,
					TweenInfo.new(0.25),
					{Size = UDim2.new(0.8, 0, 0.15, 0), BackgroundColor3 = Color3.fromRGB(25, 25, 25)}
				)}
			
			child.MouseEnter:Connect(function()
				HoverSound:Play()
				SlotTweens[child].Highlight:Play()
				SlotTweens[child].Highlight.Completed:Wait()
			end)

			child.MouseLeave:Connect(function()
				SlotTweens[child].Unhighlight:Play()
				SlotTweens[child].Unhighlight.Completed:Wait()
			end)

There’s no difference, but the code is more organized and effective. There’s also not really a point in arrow key navigation on a UI like this. That’s about it. Thank you. I will notify you if I need any help.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.