High-order function not working

I’m trying to make a system where whenever you pick up a banana, it attaches to your hand and is animatable. I also want an action to bind on the client-side when they have this banana so they can eat it when pressing E.

The problem is whenever I try to use an HOF to send over a signal, it won’t work.

Client side script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ContextActionService = game:GetService("ContextActionService")

local Remotes = ReplicatedStorage.Remotes


local function Unbinder(signal)
	if signal == "BindActionRewardBanana" then
		print("Signal is right in function")
		return function(actionName,inputState)
			print("INRighadsasanfoiasnndosaodnsadsa")
			print(actionName,inputState)
			if inputState == Enum.UserInputState.Begin then
				print("Success")
				--ContextActionService:UnbindAction(signal)
			end
		end
	end
end

Remotes.ToClient.OnClientEvent:Connect(function(signal,par1)
	print("Client Side")
	if signal == "BindActionRewardBanana" then
		print("Signal is right")
		ContextActionService:BindAction(signal,Unbinder(signal),false,Enum.KeyCode.E)
	end
end)

For now I’ll just make a plain variable to not get stuck on this problem but if anyone has an idea to this issue let me know.

Note: Any print statements inside the return function of the Unbinder function does not print.

2 Likes

Does it work if you change to:

ContextActionService:BindAction("Signal", Unbinder(signal), false, Enum.KeyCode.E)

2 Likes

When using ContextActionService:BindAction(), pay attention that the first parameter is always a string that is a reference to the action. Give it a name and unbind it with the same name on another script(and it works). The second parameter is a function that should handle the action upon the fourth parameter’s input.

Try using a common identifier on the global scope. Like this:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ContextActionService = game:GetService("ContextActionService")

local Remotes = ReplicatedStorage.Remotes
local ACTION_BANANA_REWARD = "Reward Banana"

local function Unbinder(signal)
	if signal == "BindActionRewardBanana" then
		print("Signal is right in function")
		return function(actionName,inputState)
			print("INRighadsasanfoiasnndosaodnsadsa")
			print(actionName,inputState)
			if inputState == Enum.UserInputState.Begin then
				print("Success")
				ContextActionService:UnbindAction(ACTION_BANANA_REWARD)
			end
		end
	end
end

Remotes.ToClient.OnClientEvent:Connect(function(signal,par1)
	print("Client Side")
	if signal == "BindActionRewardBanana" then
		print("Signal is right")
		ContextActionService:BindAction(ACTION_BANANA_REWARD,Unbinder(signal),false,Enum.KeyCode.E)
	end
end)
3 Likes

The signal is a string from the server by the way. Was that the problem to my issue? Should I just have used a string that originated from the client instead of a string that was created from the server?

1 Like

Try storing action-specific functions in a table, like so:


toolActions = {
    Banana = function() end;
    Apple = function() end;
   -- etc.
}

for _,Tool in ipairs(Tools) do

    if not toolActions[Tool.Name] then continue end

    Tool.Equipped:Connect(function()
        CAS:BindAction(Tool.Name, toolActions[tool.Name])
    end)

    Tool.Unequipped:Connect(function()
        CAS:UnbindAction(Tool.Name)
    end)

end
2 Likes

@anon81993163 solution definitely worked I just don’t understand how it did. I also am not thinking of implementing them in tables and rather just trying to understand the general concept.

1 Like

You could still create a more modular function like I displayed, perhaps you could compare the string provided by the server to the actions in the table and bind/unbind directly from it.

Something like

ToolEvent.OnServerEvent:Connect(function(ActionName, bind)
    if not table.find(toolActions, ActionName) then return end

    if bind then
        CAS:BindAction(ActionName, toolActions[ActionName])
    else
        CAS:UnbindAction(ActionName)
    end

end)

Helps reduce the amount of writing pretty much the same line over and over.

2 Likes

ContextActionService doesn’t occur in servers, only clients. They are meant for input controls.

3 Likes

I know.

The ServerEvent is fired to the client. – or did I get the verbage backwards? I’m tired lol

When the client gets the connection, they bind the action with ContextActionService.

I was pretty sure we were all on the same page about that at least

1 Like

You got this backwards. If you fire to the clients, it’s supposed to be OnClientEvent. I suppose you did have it entirely backwards. If that was the case, it should otherwise be correct.

1 Like

Right idea, opposite words is what I meant basically lol

1 Like

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