If I haven‘t missed anything, the solution is based on creating input map entries for each player (e.g. run_player_1 and run_player_2).
While that works, it‘s uglier and less scalable than a solution I‘d hope for.
st_phan | 2023-06-22 19:50
How do you expect a solution to be prettier and more scalable?
I think this is as good as it gets. There is a finite number of players that can be handled on a local machine anyway.
zhyrin | 2023-06-23 10:32
In the issue I linked to above there is quite an extensive discussion on how the input system could be majorly enhanced (if Godot’s core would be expanded) – check it out, it’s interesting, especially this comment.
I posted my question to see if I had missed an obvious approach that is fairly flexible (like the proposed stuff in the issue).
I have solved this before and will help by providing a coding example immediatly below and will then explain the logic aftewards
const BTN_A = 1 #(BIT SHIFT 0) 0001 in binary, 1 decimal
const BTN_B = 1 << 1 # 0010 in binary, 2 deciaml
const BTN_X = 1 << 2 # 0100 in binary, 4 decimal
const BTN_A_KEY = "A"
const BTN_B_KEY = "B"
const BTN_X_KEY = "X"
var btnMap = {}
var pInRemap = {}
func _ready():
#initialize button map
btnMap[BTN_A_KEY] = BTN_A
btnMap[BTN_B_KEY] = BTN_B
btnMap[BTN_X_KEY] = BTN_X
#no remapping by default
for k in btnMap.keys():
pInRemap[k]=btnMap[k]
#targetBtn is a string representing button (will be used as key to access the button maps)
#newBtns is an array of strings, representing the buttons to map to when pressing target button
func remapButton(targetBtn, newBtns):
if (targetBtn == null):
return
var btnCode =null
#only compute the button bit maps for none empty remapping
if newBtns != null and newBtns.size() > 0:
btnCode=0
#go set all bits of btnCode, for each new button
for b in newBtns:
btnCode = btnCode | btnMap[b]
#remap
pInRemap[targetBtn] = btnCode
#example of remapping the A button to be a macro of 'B+X'
remapButton(BTN_A_KEY,[BTN_B,BTN_X])
func processInput():
#suppose the way you mapped your buttons is a 2 player game as follows:
#"P1_A": the "A" button for player 1
#"P2_A": the "A" button for player 2
#"P1_X": the "X" button for player 1
#"P2_X": the "X" button for player 2
#etc.
var inputDeviceIds = ["P1","P2"]
for inputDeviceId in inputDeviceIdS:
var inputJustPressedBitMap = 0
var btnKeys = pInRemap.keys()
#iterate all buttons to create bit map
for k in btnKeys:
#remapping of buttons made it so a button maps to no input?
if pInRemap[k] == null:
continue
#tranlate button id to device button (2 different devices have same button)
#differentiate devices via inputDevice id. Needd to map this in input seetings
var inputId = inputDeviceId+"_"+k
#check if player just pressed it
if Input.is_action_just_pressed(inputId):
inputJustPressedBitMap = inputJustPressedBitMap | pInRemap[k]
#take bit-wise-and operator to determine whether button was pressed
if (inputJustPressedBitMap & BTN_A) ==BTN_A:
#player <inputDeviceId> pressed a button that maps to button A
pass
if (inputJustPressedBitMap & BTN_B) ==BTN_B:
#player <inputDeviceId> pressed a button that maps to button B
pass
if (inputJustPressedBitMap & BTN_X) ==BTN_X:
#player <inputDeviceId> pressed a button that maps to button X
pass
The idea is that a dictionary maps action input names to button bitmap codes (each button has its own unique bit set to 1). This way, you can represent a series of button presses with a single integer variable. For example, in the above code
001 = would be treated as button A was pressed
101 = would be treated as button A and X were pressed together
This then allows to you create a dictionary that remaps a raw button press to null input, another input, or a macro of inputs
Thanks for sharing, this is quite a unique an interesting approach!
st_phan | 2023-06-23 10:53
Oops, just realize there is a small bug in the code I provided. Each player should have their own script with a inputDeviceId, so that each player would have a button remaps dictionaries (so the for loop that iterates the input device names would be unecessary in the processInput fucntion)