rsubtil / controller_icons Goto Github PK
View Code? Open in Web Editor NEWAutomatic keyboard/mouse/controller icons and remapper for Godot.
Home Page: https://godotengine.org/asset-library/asset/1429
License: MIT License
Automatic keyboard/mouse/controller icons and remapper for Godot.
Home Page: https://godotengine.org/asset-library/asset/1429
License: MIT License
Thanks for the amazing plug-in!
4.3 stable
Issue description
I'm implementing a pause menu where you can change the user keybingings, and I can't make the icons change when the game is paused, everything works fine when the game is not paused, every relevant node process mode is "ALWAYS", but the plugin dosen't seem to detect device changes when the game is paused.
Instead of offering core nodes that automatically load a controller icon based on a path, it might be possible to, instead, offer a new Resource type, inheriting from Texture2D
, that can handle all the current functionality. This is a pretty cool idea because:
XXY - Combo Attack
), and embedded in other nodes such as RichTextLabel (e.g. Press F to pay respects
)Even with this system, there are some restrictions about usability that cannot change:
Plus, this will result in a new breaking change, and a very substantial one, requiring either automated or manual refactoring.
Icons don't automatically update when InputMap is changed at runtime. There should be a manual refresh method for developers to call when inputs have changed.
With the new texture resource refactor, it's now possible to accurately represent "simple multi-key promps", which are any keyboard actions that require an extra modifier key, such as Ctrl + C
, Shift + D
, etc...
This will involve some basic text rendering, so a system to customize the used font and it's properties (size, color, alignment, outline, etc...) should be implemented for this.
In theory this implementation would support arbitrary keyboard shortcuts (Ctrl + Shift + D), but those will not be supported for now, as more research needs to be done on how they work actually.
Currently, the addon checks for inputs for the first controller. There should be an option to specify controller index for multiplayer games.
Sprite.gd
references a variable named force_type
, but it's not declared anywhere. This causes the plugin to crash the moment it starts up. This variable does exist in the 4.0 branch, so it was most likely lost in translation.
When grabbing the current version of controller icons from asset lib in godot 4.0.stable, I get the error "Error at (195, 19): Identifier "KEY_SUPER_L" not declared in the current scope." as well as a similar error message for KEY_SUPER_R. When I delete this code that seems to fix the problem.
I was confused when I saw the name, and had to look it up. Apparently this console was only sold in 2013-15, and only 200k units. Support was added April of this year, so I'm curious if there is a story that you wouldn't mind sharing?
It would be nice if you could add an option to settings to specify a custom file extension. This would allow for a texture atlas to be used for example since I can then pass .tres
as the extension, rather than using the default .png
.
## Custom generic joystick mapper script
@export var custom_mapper : Script
## Icons image file extension
@export var file_extension : String = "png"
I did a quick hack by adding the setting and updating two spots in ControllerIcons.gd where it points to .png to make use of the setting and it seems to work at runtime so far.
SpecificPathSelector.gd
func handle_files(category: String, base_path: String):
for file in DirAccess.get_files_at(base_path):
if file.get_extension() == ControllerIcons._settings.file_extension: #if file.get_extension() == "png":
create_icon(category, base_path.path_join(file))
ControllerIcons.gd
204: base_path += path + "." + _settings.file_extension #base_path += path + ".png"
246: paths.push_back(base_path + "." + _settings.file_extension) #paths.push_back(base_path + ".png")
See title. I've installed and uninstalled this plugin many times (Using Godot 3.5.1 Mono). The script seems to be working and no errors appear in the console window, but no matter how hard I try, I am unable to get the gamepad icons to show up.
What's strange is that the icons will update fine when I'm in the editor. But when running the game:
Steam Deck would be awesome to support, and the icons for it are already shipped.
As I don't own one, I don't know how to properly detect and test it, as it doesn't show on the SDL controller database.
godotengine/godot#78539 added a way to get more "raw" information about a controller. In particular, it gives access to vendor/product ID on Linux.
Since there are public databases (such as https://devicehunt.com) documenting this information, controller model detection on Linux can be made much more reliable.
In my game, players can press ,
(Comma) to perform a certain action. Trying to show this as a key hint using this plugin simply results in the game crashing.
Here's a list of symbols I've been able to replicate this crash with:
,
Comma.
Period/
Forward Slash'
Apostrophe=
EqualsUsing any of these symbols results in the following error:
E 0:00:00:0454 ControllerIconTexture.gd:367 @ _stitch_texture(): Invalid image: null
<C++ Error> Condition "p_image.is_null()" is true. Returning: Ref<ImageTexture>()
<C++ Source> scene/resources/image_texture.cpp:76 @ create_from_image()
<Stack Trace> ControllerIconTexture.gd:367 @ _stitch_texture()
ControllerIconTexture.gd:379 @ _get_rid()
Reading the error message, it just looks like the icons are missing from the keyboard icon set. I can probably learn how the icons were made and contribute some icons to the pack, if necessary.
Interestingly, this error happens even if the shown key is not one of these symbols. For example, I use a Dvorak keyboard, and where ,
is on QWERTY, it should show W
. However, it instead throws the error above. It does display the correct key if I use other keys, though, so I'm not sure what could cause this since it shouldn't be looking for ,
when displaying W
.
The addon will cause Godot 4.3rc2 to crash on startup of the editor when there are ControllerIconTexture
resources.
I've tracked it down to ControllerIconTexture._load_texture_path()
. Commenting out the deferred call seems to "resolve" the issue. I do not know enough about the intention here though so the problem might be somewhere else?
Anyway, this is what I did to get rid of the crash in case it helps identify the real cause.
func _load_texture_path():
# Ensure loading only occurs on the main thread
#if OS.get_thread_caller_id() != OS.get_main_thread_id():
# _load_texture_path_main_thread.call_deferred()
#else:
# _load_texture_path_main_thread()
_load_texture_path_main_thread()
[edit] oh I think it is being looked at here? #96
When trying to integrate this plugin into my project, I noticed errors regarding Item
subclass hiding an existing global class from my project. Given that Item
class name is pretty much guaranteed to conflict in many projects, as a lot of games will have some kind of model to store item data, I propose to rename it to something like InputItem
or find a better solution to this problem.
The plugin uses Xelu's Icon Prompts since the beginning. However, a decision was made to ship only the dark variant of such assets, to avoid shipping plenty of likely unnecessary assets by default.
But this created the problem of not offering the choice to the user of using the light variant instead. And, as time moved on, Kenney designed a new set of icons which are also of high quality and good candidates to include as well.
The idea is to provide some system for users to choose an "icon pack", giving them the choice of which icons to use for their projects.
Script broken in godot 4.1.2
Hi, I'm trying out your plugin and I seem unable to change the path property with code. Is there a method for this? The docs don't seem to mention anything.
Version : 1.1.4
Godot version : 4.0.2
I'm using the ControllerTextureRect node with a path set to my action name "test".
In the godot input mapping settings, i have bind the Select button on my PS5 controller to the action "test". Name of the input event: "Joypad Button 4 (Back, Sony Select, Xbox Back, Nintendo -)".
When running the game, the icon shown is the L2 button and not the select button.
I think I have found the source of my problem which is the following method:
controller_icons/addons/controller_icons/ControllerIcons.gd
Lines 413 to 452 in f57beb4
In my case, the select button have a button_index of 4 and it can matches two times :
The problem is that the match pattern is using both JoyButton enum and JoyAxis enum. Therefore, the index of the enum is not unique.
Hi!
This is more a heads-up on an issue I found in Godot 4.3-dev4, and offer to fix where I can once this release is in stable.
I noticed that in Godot 4.3-dev4 the macOS backend for input changed to use GCController instead of the IOHIDDeviceRef. What this does is change the name of the controller being returned: eg. "PS5 Controller" now becomes "DualSense Wireless Controller" (on Mac only!). Once 4.3 is released as stable I'm more than happy to add the alternatives that I can if you like for this.
The current version seems not support Godot mono versions with the error info of "isn't declared in the current scope".
The meta
key is being displayed on macOS systems instead of the command
key. This is because Godot 4 changed the OS.get_name
from OSX
to macOS
, and this code wasn't changed accordingly during porting:
controller_icons/addons/controller_icons/ControllerIcons.gd
Lines 241 to 246 in 5d699bf
godotengine/godot#80432 was the root cause for a deadlock in _joy_connection_changed
. As it has been cherry-picked for 4.1.2 which is now the minimum addon version, this hack can now be deleted:
controller_icons/addons/controller_icons/ControllerIcons.gd
Lines 108 to 117 in b20c168
Because the scripts run in tool
mode, when controllers are plugged, the icons change automatically. This changes scene file assets constantly and is a pain, so this should be disabled.
Context: I'm running Godot 4.3 (official build, also tried on a build with debug symbols) on M1 Pro (macOS 14.5) with two keyboard layouts installed.
I've tried migrating my existing project to 4.3 and encountered an editor crash, which I've pinpointed to a single ControllerIconTexture
saved as .tres
file (which I use in a RichTextLabel). The editor starts to load, produces some Generated 'res://%resourcename%' preview in N usec
entries, and then crashes.
I have many instances of ControllerIconTexture
used as built-in scene resources, and the crash only happens with the external resource.
Here's the resource file:
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://ckkmayetgcbwl"]
[ext_resource type="Script" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_kjf73"]
[resource]
resource_local_to_scene = false
resource_name = ""
script = ExtResource("1_kjf73")
path = "special"
show_mode = 0
force_type = 0
The special
action is currently mapped to physical Shift
, but the particular key doesn't seem to matter much.
If I delete either this single resource file or the special
keyboard key from the Input Map (and leave the controller key, for example), everything works fine.
After looking at the backtrace, I've found that the problem happens on this line in the call to DisplayServer.keyboard_get_keycode_from_physical()
:
return _convert_key_to_path(event.physical_keycode)
, the crash disappears.
I'm unable to reproduce this crash on a smaller scale yet. Since the crash started happening after migration to 4.3, it's probably best to also report it to the engine maintainers, but I'm lacking the needed context right now. @rsubtil maybe you would have an idea about the root cause?
Here's the crash log from the editor:
================================================================
handle_crash: Program crashed with signal 5
Engine version: Godot Engine v4.3.stable.official (77dcf97d82cbfe4e4615475fa52ca03da645dbd8)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] 1 libsystem_platform.dylib 0x000000018d71b584 _sigtramp + 56
[2] 2 ??? 0xffff80018d53c820 0x0 + 18446603342887241760
[3] 3 libdispatch.dylib 0x000000018d53c7b0 _dispatch_assert_queue_fail + 0
[4] 4 HIToolbox 0x0000000197f6e860 islGetInputSourceListWithAdditions + 160
[5] 5 HIToolbox 0x0000000197f70e9c isValidateInputSourceRef + 92
[6] 6 HIToolbox 0x0000000197f70d5c TSMGetInputSourceProperty + 44
[7] KeyMappingMacOS::remap_key(unsigned int, unsigned int, bool) (in Godot) + 108
[8] DisplayServerMacOS::keyboard_get_keycode_from_physical(Key) const (in Godot) + 64
[9] DisplayServerHeadless::_dispatch_input_events(Ref<InputEvent> const&)
[10] DisplayServerHeadless::_dispatch_input_events(Ref<InputEvent> const&)
[11] DisplayServerHeadless::_dispatch_input_events(Ref<InputEvent> const&)
[12] GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) (in Godot) + 50624
[13] Object::callp(StringName const&, Variant const**, int, Callable::CallError&) (in Godot) + 176
[14] Variant::callp(StringName const&, Variant const**, int, Variant&, Callable::CallError&) (in Godot) + 260
[15] GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) (in Godot) + 44504
[16] Object::callp(StringName const&, Variant const**, int, Callable::CallError&) (in Godot) + 176
[17] Variant::callp(StringName const&, Variant const**, int, Variant&, Callable::CallError&) (in Godot) + 260
[18] GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) (in Godot) + 44504
[19] Object::callp(StringName const&, Variant const**, int, Callable::CallError&) (in Godot) + 176
[20] Variant::callp(StringName const&, Variant const**, int, Variant&, Callable::CallError&) (in Godot) + 260
[21] GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) (in Godot) + 44504
[22] Object::callp(StringName const&, Variant const**, int, Callable::CallError&) (in Godot) + 176
[23] Variant::callp(StringName const&, Variant const**, int, Variant&, Callable::CallError&) (in Godot) + 260
[24] GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) (in Godot) + 44504
[25] Object::callp(StringName const&, Variant const**, int, Callable::CallError&) (in Godot) + 176
[26] Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (in Godot) + 228
[27] CallQueue::_call_function(Callable const&, Variant const*, int, bool) (in Godot) + 296
[28] CallQueue::flush() (in Godot) + 352
[29] ResourceLoader::_thread_load_function(void*) (in Godot) + 700
[30] ResourceLoader::_load_start(String const&, String const&, ResourceLoader::LoadThreadMode, ResourceFormatLoader::CacheMode) (in Godot) + 1608
[31] ResourceLoader::load(String const&, String const&, ResourceFormatLoader::CacheMode, Error*) (in Godot) + 84
[32] EditorResourcePreviewGenerator::generate_from_path(String const&, Vector2 const&, Dictionary&) const (in Godot) + 1292
[33] EditorResourcePreview::_generate_preview(Ref<ImageTexture>&, Ref<ImageTexture>&, EditorResourcePreview::QueueItem const&, String const&, Dictionary&) (in Godot) + 1688
[34] EditorResourcePreview::_iterate() (in Godot) + 1580
[35] EditorResourcePreview::_thread() (in Godot) + 92
[36] Thread::callback(unsigned long long, Thread::Settings const&, void (*)(void*), void*) (in Godot) + 120
[37] Thread::~Thread()
[38] 38 libsystem_pthread.dylib 0x000000018d6eaf94 _pthread_start + 136
[39] 39 libsystem_pthread.dylib 0x000000018d6e5d34 thread_start + 8
-- END OF BACKTRACE --
================================================================
There's no way to show the icon for a specific input type (keyboard or controller). This is useful for input remapping screens, to remap controller inputs using a keyboard.
When an input action has multiple alternative keys/buttons, only the first mapping is shown:
There should be a way for developers to:
my_action{2}
to show the second mapping if it exists)The new refactor easily allows for a more advanced use-case: multi-icon prompts. This is useful, for example, in fighting games which typically feature button combos.
Tried it in Godot v4 beta 13 and icons are empty on Steam Deck.
input_type_changed
is only emitted when an input type changed, so it doesn't get called for the initial input method. So even if there's a controller connected, the app will initially show keyboard icons until any controller input is detected.
Currently, the addon fetches separate image files for all button prompts. While this makes it easier for users to modify, it is inefficient, since the most popular solution is to have only one large image atlas.
It might be possible, however, to optimize this step on exported projects. The idea is to build the texture atlas and then fetch from there, instead of the individual image files (and don't even pack them on export).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.