Nullifying inputs with ContextActionService

Introduction

Note: This tutorial requires some genuine knowledge of ContextActionService

Quite a lot, especially recently, I’ve seen people trying to nullify inputs via hacky or over-complicated methods however ContextActionService can make that really simplistic through using the Sink ContextActionResult.

ContextActionResult

What is a ContextActionResult though? The api-reference states that:

ContextActionResult controls the behavior of multiple bound actions. It gives the option of controlling whether or not a bound action should sink or pass the input event, meaning other things (including other bound actions) can process it.

This means that you can return a ContextActionResult of Sink and the other bound actions will be nullified.

ContextActionPriority

At points you will need to use BindActionAtPriority, this enumeration’s items’ values to ensure that you’re binding at a higher importance than the Core bindings, you can read more on the api-reference.
Usually ContextActionPriority.High.Value is required.

UserInputType, KeyCode and PlayerActions

Each of these enumerations respectively have the different input methods which make up the whole Roblox interface;

  • UserInputType contains the different types of hardware and their explicit type of input
  • KeyCode includes every key you’d find on a Keyboard & buttons you’d find on a controller
  • PlayerActions holds every type of Character movement there is

Putting this into action

Now that you’ve understood ContextActionResult & ContextActionPriority yet also the different input methods you can use this in multiple ways.

Here’s an example of stopping right clickment:

--// Dependency
local ContextActionService = game:GetService("ContextActionService")

--// Function
local function bind()
    return Enum.ContextActionResult.Sink --// Return that the result is to Sink
end

--// Bind
ContextActionService:BindAction(
    "CameraSink", --// Bind name 
    bind, --// Bind function
    false, --// Should it create a gui button for phones?
    Enum.UserInputType.MouseButton2 --// Our input, MouseButton2 is right click
)

Now this is very similar in other cases however as I’ve stated before some will need a priority (usually PlayerActions), this means that you will have to use BindActionAtPriority.

Here’s an example for nullifying left and right character movement:

ContextActionService:BindActionAtPriority(
    "MovementSink", --// Bind name
    bind, --// Bind function
    false, --// Should it create a gui button for phones?
    Enum.ContextActionPriority.High.Value, --// The priority, it most likely needs to be the Value of High
    Enum.PlayerActions.CharacterLeft, --// Left movement of their character
    Enum.PlayersActions.CharacterRight --// Right movement of their character
)

Thanks for reading!

Thanks for reading, this was my 3rd community tutorial!
I hope you did enjoy, as always make sure to reply if you have anything to add or correct.

11 Likes

Good tutorial that essentially accumulates the numerous mentions of sinking input over using bad workarounds for trying to get rid of certain input behaviours, such as right mouse camera dragging.


Anyway, time to butcher the thread.

Under the ContextActionResult section, there is a very important thing that wasn’t covered and it’s the priority levels themselves. Returning Sink does not nullify other bound actions, it will only prevent those with a lower priority from being run. Think of it like this: when you send input, all bound actions to that input are collected, sorted from highest to lowest and then ran until a Sink is met.

In the ContextActionPriority section, you mention that the use of BindActionAtPriority is required to bind at a higher importance than Core (improperly marked as Developer) bindings. For security reasons, you cannot bind over Core bindings, regardless of what priority level you use. You may only bind over Developer (improperly marked as Core) bindings.

A common misconception is that UserInputType is representative of hardware. Roblox does not provide a native way for you to check the hardware or device that a player is using, only the type of input they are sending. Different devices are capable of sending output you may not expect (e.g. a touch screen laptop can send touch input).

Movement inputs in the PlayerModule are bound to Default priority, which has a value of 2000. Passing in a value of Enum.ContextActionPriority.Default.Value + 1 is sufficient enough to sink the input. You probably don’t want to use high because again, you’ll sink anything that has a priority <3000.


's all.

5 Likes