Comments (15)
Another quick update about my progress!
I've filtered out all of the built-in action names and have also implemented the discussed "friendly" names mapping for action names. If no friendly name is added to the map the label text will fall back to the default name.
I also have a simple rebind menu that pops up when the rebind button is clicked with data for the relevant action piped into the rebind menu. I'm listening for input on that menu and rebinding the associated action to the new input. Currently working through the saving dialog and logic.
Once that's done I'll clean up the button labels based on the detected device. For Joypads I'd really love to dynamically change the button label to an icon for the correct device, but that would require importing icons for each type of Joypad I think? I'd welcome any feedback on this!
When I prepare this PR, should I open that against the new tabbed menu design from #55? For testing my current setup is just a Controls button on the main menu but I can migrate what I have into the tabs redesign if that makes sense.
from cogito.
Wanted to drop a quick update on where I'm at on this issue!
I've setup a placeholder Controls menu option within the existing Options menu and I'm populating that menu with the input map. I've also started hooking up the data for things like the button and key input text. Once that's working remapping the input should be straightforward. I'm hoping to have some free time this week to continue making progress.
from cogito.
I wasn't able to find a simple way to exclude the default inputs, but I haven't dug too deeply yet.
I've done some investigating in the past on this. And as far as I could find, there isn't a method available from GDScript that can tell you whether an Input mapping is built-in or not. There is, tantalisingly, in the Godot source code a function called 'get_builtins' https://github.com/godotengine/godot/blob/a586e860e5fc382dec4ad9a0bec72f7c6684f020/core/input/input_map.cpp#L382 I was completely unable to find any reference to this that's accessible via GDScript. If you're sufficiently motivated, you might be able to use GDNative to hook into that directly.
Personally wasn't willing to go that far, so I came up with this hack-y Resource instead (edited slightly to make more sense in context):
@tool extends Resource class_name RebindableActions @export var inputs : Array[String] static var custom_actions : Array[String] func _init(): inputs = get_actions().duplicate() ProjectSettings.property_list_changed.connect(_refresh) static func _refresh(): custom_actions = [] var was_input = false var loaded_defaults = false for setting in ProjectSettings.get_property_list(): var is_input = setting.name.begins_with('input/') if was_input and not is_input: loaded_defaults = true elif is_input and loaded_defaults: custom_actions.push_back(setting.name.split('/')[-1]) was_input = is_input func get_actions(): if custom_actions: return custom_actions _refresh() return custom_actions func _property_can_revert(property): if property == 'inputs': return get_actions() != inputs func _property_get_revert(property): if property == 'inputs': return get_actions().duplicate()This works because ProjectSettings will provide you the property list in the order it was loaded. So it loads the built-in project settings first, and then loads any user configured project settings. Even if you add/remove inputs from the built-in actions, all built-in actions will stay bunched together. And of course, you can reverse
_refresh()
s behaviour to get all builtin actions.This will work on export as well.
If you would rather just a full list to be updated of the built-in actions manually, you can find them earlier on in that same Godot source code: https://github.com/godotengine/godot/blob/a586e860e5fc382dec4ad9a0bec72f7c6684f020/core/input/input_map.cpp#L292
RebindableActions can then serve as your "whitelist" of inputs. There's nothing stopping a user from adding built-in inputs if that's desireable, or removing custom ones.
You will need to add some behaviour to _refresh() that can detect and add new Inputs on project settings changes to auto-import those, at the very least for any RebindableActions that return false on "can_revert"
When I worked on this I just knew there had to be some way to get those actions from the Godot source code, but being fairly new to Godot myself I thought it would faster to just type them all out manually 😅. This is super helpful info and I'm happy that my hunch was correct! Next time I'll definitely go hunting in the source code for this type of thing.
Currently I'm filtering all of the built-ins with a defined map. I'll probably put a pin in the filtering part for now but I could revisit this before opening the PR if your auto-loading method feels like a better way to handle loading the built-ins.
Thanks for all the help!
from cogito.
Hi! I'd love to take a shot at implementing rebinding keys if this issue is still valid.
from cogito.
Yes, this is still valid. Would be awesome if you could take a shot.
Please make sure you pull from the latest /main/
as I've added another input map action on that one: interact2
.
from cogito.
Good job. Can you also add toggle crouch/sprint?
This is an addition for #55 / Gameplay options. Not for rebindable inputs.
DashNothing did a clever remapping algorythm
I can't confirm how @Jealousmango approaches it, but COGITO comes with Nathan Hoad's InputHelper, which already includes functions for input remapping, so I think it's currently just about implementation.
Yeah, that's how I've approached the remapping. I used the methods mentioned on the InputHelper documentation to successfully rebind a key so now it's mostly working out the UI flow and cleaning up the content.
I have wondered about the default input map names. Populating the menu with actions like ui_accept
feels clunky, but changing that to a more friendly name might be outside the scope of this issue.
from cogito.
Is there a simple way to exclude the godot default inputs? AFAIK they're never explicitly used in the scripts besides the default UI navigation and it's pretty rare that someone would want to rebind these.
Alterantively there might be away to replace the input map action names with readable ones with a simple dictionary or something, with falling back to the default string name if no entry is found. 🤔
from cogito.
Dictionary is how I've seen it - use the translation, or skip the key altogether. Or a dictionary of godot default inputs to skip I suppose?
Although equally you could "translate" by swapping underlines for space and camelcasing the text (having a static dictionary you have to update seperately isn't great, unless you are dynamically adding keybinds as part of dis/enable of chunks of movement code for devs - ie out of scope?)
from cogito.
Is there a simple way to exclude the godot default inputs? AFAIK they're never explicitly used in the scripts besides the default UI navigation and it's pretty rare that someone would want to rebind these.
Alterantively there might be away to replace the input map action names with readable ones with a simple dictionary or something, with falling back to the default string name if no entry is found. 🤔
I wasn't able to find a simple way to exclude the default inputs, but I haven't dug too deeply yet. One possible route would be creating a map of blacklisted actions and including all of the Godot default actions.
I think you're right about defining a dictionary for more readable names and falling back on the default string if one isn't provided. I'll be sure to include that. Thanks for the feedback!
from cogito.
I wasn't able to find a simple way to exclude the default inputs, but I haven't dug too deeply yet.
I've done some investigating in the past on this. And as far as I could find, there isn't a method available from GDScript that can tell you whether an Input mapping is built-in or not. There is, tantalisingly, in the Godot source code a function called 'get_builtins'
https://github.com/godotengine/godot/blob/a586e860e5fc382dec4ad9a0bec72f7c6684f020/core/input/input_map.cpp#L382
I was completely unable to find any reference to this that's accessible via GDScript.
If you're sufficiently motivated, you might be able to use GDNative to hook into that directly.
Personally wasn't willing to go that far, so I came up with this hack-y Resource instead (edited slightly to make more sense in context):
@tool
extends Resource
class_name RebindableActions
@export var inputs : Array[String]
static var custom_actions : Array[String]
func _init():
inputs = get_actions().duplicate()
ProjectSettings.property_list_changed.connect(_refresh)
static func _refresh():
custom_actions = []
var was_input = false
var loaded_defaults = false
for setting in ProjectSettings.get_property_list():
var is_input = setting.name.begins_with('input/')
if was_input and not is_input:
loaded_defaults = true
elif is_input and loaded_defaults:
custom_actions.push_back(setting.name.split('/')[-1])
was_input = is_input
func get_actions():
if custom_actions:
return custom_actions
_refresh()
return custom_actions
func _property_can_revert(property):
if property == 'inputs':
return get_actions() != inputs
func _property_get_revert(property):
if property == 'inputs':
return get_actions().duplicate()
This works because ProjectSettings will provide you the property list in the order it was loaded.
So it loads the built-in project settings first, and then loads any user configured project settings. Even if you add/remove inputs from the built-in actions, all built-in actions will stay bunched together. And of course, you can reverse _refresh()
s behaviour to get all builtin actions.
This will work on export as well.
If you would rather just a full list to be updated of the built-in actions manually, you can find them earlier on in that same Godot source code:
https://github.com/godotengine/godot/blob/a586e860e5fc382dec4ad9a0bec72f7c6684f020/core/input/input_map.cpp#L292
RebindableActions can then serve as your "whitelist" of inputs. There's nothing stopping a user from adding built-in inputs if that's desireable, or removing custom ones.
You will need to add some behaviour to _refresh() that can detect and add new Inputs on project settings changes to auto-import those, at the very least for any RebindableActions that return false on "can_revert"
from cogito.
Should I open that against the new tabbed menu design from #55?
Yes, ideally. I've prepped a tab in it called "Bindings"
For Joypads I'd really love to dynamically change the button label to an icon for the correct device
There's already a script for this called DynamicInputIcon.gd, which depending on which device is detected, switches the icon accordingly. I'm sure you can easily adapt it to your needs, but be careful when editing it directly, as it's currently used for all UI prompts.
It only differentiates between generic gamepad and keyboard/mouse, but it can be extended to do gamepad-type specific icons.
I was planning to add this later using Kenney's new Input UI icons, once the rebinding is in place.
from cogito.
Looks promising! Thanks for the update.
from cogito.
that looks amazing!
Just incase its useful, DashNothing did a clever remapping algorythm, and they used a dictionary to translate the ui_key elements 👍
I've also just proposed tweaking the Options page to have the title and 'back' buttons always visible 😅 just baby changes from me currently
from cogito.
Good job. Can you also add toggle crouch/sprint?
from cogito.
Good job. Can you also add toggle crouch/sprint?
This is an addition for #55 / Gameplay options. Not for rebindable inputs.
DashNothing did a clever remapping algorythm
I can't confirm how @Jealousmango approaches it, but COGITO comes with Nathan Hoad's InputHelper, which already includes functions for input remapping, so I think it's currently just about implementation.
from cogito.
Related Issues (20)
- Missing Parameter in door sync code HOT 3
- [Improvement/Suggestion] Stealth / Brightness Improvements HOT 4
- Invalid get index 'interactive_object_detected' (on base: 'Nil') HOT 6
- Inventory system / grid based: Using item while moving another one can override/delete it. HOT 2
- Quest: Steal the laptop - win condition doesn't get triggered - item checker issue? HOT 2
- Inventory System / Grid based: Item graphic doesn't get position correctly on move (game pad) HOT 1
- Character gets stuck on stairs HOT 4
- A character flies a crate HOT 5
- When opening the inventory, the player is frozen while the world keeps moving. HOT 2
- The platform pushes the player off the map if you stand under it HOT 3
- Flashlight not always turning on/off properly when used while walking/running. HOT 4
- Multiple interactions can occur with a single button press HOT 4
- Unrelated inventory squares are highlighted when squares are selected
- Inventory item tooltip remains visible when mousing off the inventory panel HOT 2
- Game crashes when pressing Esc afther going to the laboratory from the lobby HOT 3
- SubViewport as Root causes errors HOT 6
- Controller support in ui and menus HOT 2
- Readables not able to scroll with mouse - mousing over inventory spaces causes text to scroll HOT 5
- The fire demo table will eventually overload and kill the frames per second HOT 3
- Save system: Temp scene states don't get "reset" on "loading saved game" HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cogito.