Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement 3D focusing for keyboard/joystick-based GUI #385

Open
Shadowblitz16 opened this issue Jan 16, 2020 · 3 comments
Open

Implement 3D focusing for keyboard/joystick-based GUI #385

Shadowblitz16 opened this issue Jan 16, 2020 · 3 comments

Comments

@Shadowblitz16
Copy link

Shadowblitz16 commented Jan 16, 2020

Describe the project you are working on:
Space ship game

Describe the problem or limitation you are having in your project:
I keep having problems with keyboard and gamepad based gui because as you may have noticed controls games have nested focus based controls.

for example say you have a button that when pressed goes to a different part of the ui and when you press back you might go back to the previous parts of the ui.

you may also have a control that when selected automatically focuses onto a part of the gui.

Describe how this feature / enhancement will help you overcome this problem or limitation:
basically it would add 3 new focus neighbors to controls.

  • auto (when the control is selected).
  • enter (when you press ui_accept)
  • escape (when you press ui_cancel)

and 4 flags to controls

  • auto press flag (instead of focusing when you use keyboard or joystick input it tries to simulates a press)
  • auto focus flag (if disabled it doesn't focus on anything unless specified as a focus neighbor )
  • visible on focus flag (automatically makes your control visible when it or its children have focus)
  • invisible on unfocus flag (automaticly makes your control invisible when it or its children don't have focus)

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:
image

Describe implementation detail for your proposal (in code), if possible:
just pseudo code but here is a example

extends Control


export(bool) var auto_press
export(bool) var auto_focus
export(bool) var visible_on_focus
export(bool) var invisible_on_unfocus

export(NodePath) var focus_neighbour_auto
export(NodePath) var focus_neighbour_enter
export(NodePath) var focus_neighbour_escape

# Called when the node enters the scene tree for the first time.
func _ready():
	connect("focus_entered", self, "_on_focus_enter");
	connect("focus_exited",  self, "_on_focus_leave");
	
func _gui_input(event):
	
	if(event.is_action_pressed("ui_accept")):
		if(focus_neighbour_enter != ""):
			get_node(focus_neighbour_enter).grab_focus()
			
	if(event.is_action_pressed("ui_cancel")):
		if(focus_neighbour_enter != ""):
			get_node(focus_neighbour_escape).grab_focus()	


func _on_focus_enter():
	
	if(auto_press):
		#simulate press
		#grab previus nodes focus
	
	if(check_all_children_and_me_focus(self, true)):
		visible = true;
		
	if(focus_neighbour_auto != ""):
		get_node(focus_neighbour_auto).grab_focus()
		
func _on_focus_leave():
	var was_keyboard_or_gamepad_input = #get weather or not the focus lost was keyboard or gamepad
	var was_a_focus_neighbour         = #get weather ot not focus was lost to a focus neighbour
	if(!auto_focus && was_keyboard_or_gamepad_input && !was_a_focus_neighbour):
		grab_focus();
	
	if(check_all_children_and_me_focus(self, false)):
		visible = false;
		
func check_all_children_and_me_focus(node, value):

	
	for n in node.get_children():
		if (!check_all_children_and_me_focus(n,value)):
			return false;
			
	return node.has_focus();

If this enhancement will not be used often, can it be worked around with a few lines of script?:
this would probably be used alot for console games and might be doable with a script but it probably would require more then a few lines.

but again, it would be a really nice feature to have and would be used alot for things like menus.
(EDIT) I don't know if this is doable actually since there is no real way to simulate something like a button press

Is there a reason why this should be core and not an add-on in the asset library?:
easability with console games

@Shadowblitz16
Copy link
Author

so I am trying to implement this and have seemingly did the 3 new focus neighbors (although I haven't tested it yet)

anyways I have come across problems when trying to implement the click_instead_of_focus.

basically I have realized that controls themselves don't have pressed logic and I need a universal way of reverting to the previous focus after the press is done or I guess ui_accept is released?

I'm not quite sure how to go about this without having to implement it in every control that can be pressed.

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Jan 19, 2020

https://github.com/Shadowblitz16/godot
here is my godot fork if anyone is interested in helping.
there are alot of things that need to be implimented before this can be added.

  • auto selection for 3d controls if nodepath is not specified.
  • mouse support for 3d focusing
  • click instead of focus functionality (this might require the pressed state to be processed from control)
  • show_on_focus_enter doesn't work all the way with invisible controls.

here is a project to test with the latest version
Debug.zip

I kinda need someone that knows the gui source better then me.

@follower
Copy link

FWIW, I noticed while researching something else that there is some existing support for remembering the previous focus item, implemented for modal dialogs: https://github.com/godotengine/godot/blob/cf8c679a23b21d6c6f29cba6a54eaa2eed88bf92/scene/main/viewport.cpp#L2716-L2730

Perhaps that might be a starting point for you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants