Problems with 2D Platformer

  1. What do you want to achieve? Keep it simple and clear!
    I am making a 2d platformer game, and I want to make it so when the player triggers something, it turns their direction.

  2. What is the issue? Include screenshots / videos if possible!

The issue is that if the player is holding down a key while that key’s movement direction is sunk, they keep moving that direction and cannot stop, for example, if I was holding down D while that key got sunk, I would forced to move that direction until it is unsunk

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Yes, but all I found were posts on how to freeze the player

This is a code snippet from the script so you understand the problem a bit better

local FowardMovement = Enum.PlayerActions.CharacterForward
local BackwardMovement = Enum.PlayerActions.CharacterBackward
local LeftMovement = Enum.PlayerActions.CharacterLeft
local RightMovement = Enum.PlayerActions.CharacterRight


local function Sink()
	return Enum.ContextActionResult.Sink
end

local function UnSink()
	return Enum.ContextActionResult.Pass
end

local directions = {
	[1] = {"SinkForwardMovement", FowardMovement, "SinkBackwardMovement", BackwardMovement},
	[2] = {"SinkLeftMovement", LeftMovement, "SinkRightMovement", RightMovement}
}

local function SetDirection(directionnum)
	for key, direction in pairs(directions) do
		if directionnum == key then
			ContextActionService:BindAction(direction[1], Sink, false, direction[2])
			ContextActionService:BindAction(direction[3], Sink, false, direction[4])
		else
			ContextActionService:BindAction(direction[1], UnSink, false, direction[2])
			ContextActionService:BindAction(direction[3], UnSink, false, direction[4])
		end
	end
end

I’m wondering how this could be fixed, or if there is some sort of feature to help with this?

2 Likes

I’m not super duper familiar with ContextActionService, so I don’t have any concrete comments I could make about its functionality at the moment, however, one thing I noticed that could be causing an issue is this:

The :BindAction() calls are referring to indexes 3 and 4 in the direction table, yet only indexes 1 and 2 are defined.

Was the direction table meant to have 4 separate indexes (one for each direction), or do the arguments within the :BindAction() calls that refer to direction[3] and direction[4] just need to be updated to reference different parts of the two tables that were defined within direction?

2 Likes

you’ll need to integrate this with your existing game logic and possibly adjust it for your specific needs.

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

local keyPressed = {
    [Enum.KeyCode.W] = false,
    [Enum.KeyCode.A] = false,
    [Enum.KeyCode.S] = false,
    [Enum.KeyCode.D] = false,
}

-- Example of tracking key press and release
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
    if not gameProcessedEvent and keyPressed[input.KeyCode] ~= nil then
        keyPressed[input.KeyCode] = true
    end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessedEvent)
    if keyPressed[input.KeyCode] ~= nil then
        keyPressed[input.KeyCode] = false
    end
end)

-- Your existing function, slightly modified to check the keyPressed table
local function SetDirection(directionnum)
    for key, direction in pairs(directions) do
        if directionnum == key then
            -- Bind actions with an additional check for the key's pressed state
            ContextActionService:BindAction(direction[1], function()
                if keyPressed[direction[2]] then
                    return Enum.ContextActionResult.Sink
                else
                    return Enum.ContextActionResult.Pass
                end
            end, false, direction[2])
            ContextActionService:BindAction(direction[3], function()
                if keyPressed[direction[4]] then
                    return Enum.ContextActionResult.Sink
                else
                    return Enum.ContextActionResult.Pass
                end
            end, false, direction[4])
        else
            ContextActionService:BindAction(direction[1], UnSink, false, direction[2])
            ContextActionService:BindAction(direction[3], UnSink, false, direction[4])
        end
    end
end

Next Steps

  • Integrate and Test: Integrate this logic with your game, replacing or adjusting your existing SetDirection function as necessary.
  • Debugging: Test thoroughly for any edge cases, especially around rapidly changing directions or pressing/releasing keys quickly.
2 Likes

Yes, the direction[3] and direction[4] in the :BindAction() refer to the 3rd and 4th item of the current table
in the for loop.

for key, direction in pairs(directions) do
		if directionnum == key then
			ContextActionService:BindAction(direction[1], Sink, false, direction[2])
			ContextActionService:BindAction(direction[3], Sink, false, direction[4])
		else
			ContextActionService:BindAction(direction[1], UnSink, false, direction[2])
			ContextActionService:BindAction(direction[3], UnSink, false, direction[4])
		end
	end
2 Likes

Thanks! I will try integrating this into my script, and I’ll get back to you when I’m finished.

1 Like

Ohhh, that’s my bad; I completely missed that it was in a loop there and I thought it was directly referencing the indexes of the directions table.

2 Likes

I tried it a bit, and no matter how many edits I made I couldn’t get it to work as intended. But, I have found a way to make it work which is surprisingly simple!

local function SetDirection(directionnum)
	for key, direction in pairs(directions) do
		if directionnum == key then
			ContextActionService:BindAction(direction[1], Sink, false, direction[2])
			ContextActionService:BindAction(direction[3], Sink, false, direction[4])
		else
			ContextActionService:BindAction(direction[1], UnSink, false, direction[2])
			ContextActionService:BindAction(direction[3], UnSink, false, direction[4])
			ContextActionService:UnbindAction(direction[1])
			ContextActionService:UnbindAction(direction[3])
		end
	end
end

It turns I just needed to unbind the actions! :sweat_smile:
Thanks for the help, anyway!

4 Likes

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