Yo,
So, I really like this feature of blender that lets you navigate in 3D space. When you press KEY_QUOTELEFT it shows a radial(pie) menu that lets you view 3D space from different angles. So, I decided to create this feature for godot.
Turns out godot’s “EditorPlugin” is a really awesome feature.
Demonstration gif :
Code:
@tool
extends EditorPlugin
var viewport3d: SubViewport
var is_pie_menu_key_pressed: bool
var is_skip_input: bool = false
var mouse_pressed_pos: Vector2
var active_main_screen: String
var pie_ui: Sprite2D
func _enter_tree() -> void:
self.main_screen_changed.connect(on_change_test)
viewport3d = get_editor_interface().get_editor_viewport_3d()
is_pie_menu_key_pressed = false
pie_ui = load("res://pie_ui.tscn").instantiate()
pie_ui.visible = false
viewport3d.get_parent().add_child(pie_ui)
func _unhandled_input(event: InputEvent) -> void:
if !(event is InputEventKey):
return
if event.keycode != KEY_QUOTELEFT:
return
if event.is_pressed():
if !is_pie_menu_key_pressed:
is_pie_menu_key_pressed = true
mouse_pressed_pos = viewport3d.get_mouse_position()
if (
mouse_pressed_pos.x > 0 and mouse_pressed_pos.y > 0 and
mouse_pressed_pos.x < viewport3d.size.x and mouse_pressed_pos.y < viewport3d.size.y and
active_main_screen == "3D"
):
pie_ui.visible = true
pie_ui.position.x = clamp(viewport3d.get_mouse_position().x, 200, viewport3d.size.x - 200)
pie_ui.position.y = clamp(viewport3d.get_mouse_position().y, 200, viewport3d.size.y - 200)
is_skip_input = false
else:
is_skip_input = true
return
elif event.is_released():
if is_skip_input:
is_pie_menu_key_pressed = false
return
pie_ui.visible = false
var mouse_released_pos = viewport3d.get_mouse_position()
var diff_angle_deg = rad_to_deg((mouse_released_pos - pie_ui.position).angle())
diff_angle_deg += 180
diff_angle_deg += 22.5
if diff_angle_deg > 360:
diff_angle_deg -= 360
var angle_start = floor(diff_angle_deg / 45)
var test_event = InputEventKey.new()
test_event.pressed = true
match int(angle_start):
0:
test_event.keycode = KEY_KP_3
test_event.alt_pressed = true
Input.parse_input_event(test_event)
#print("LEFT VIEW")
1:
test_event.keycode = KEY_KP_1
Input.parse_input_event(test_event)
#print("FRONT VIEW")
2:
test_event.keycode = KEY_KP_7
Input.parse_input_event(test_event)
#print("TOP VIEW")
3:
test_event.keycode = KEY_KP_1
test_event.alt_pressed = true
Input.parse_input_event(test_event)
#print("BACK VIEW")
4:
test_event.keycode = KEY_KP_3
Input.parse_input_event(test_event)
#print("RIGHT VIEW")
5:
test_event.keycode = KEY_F
Input.parse_input_event(test_event)
#print("VIEW SELECTED")
6:
test_event.keycode = KEY_KP_7
test_event.alt_pressed = true
Input.parse_input_event(test_event)
#print("BOTTOM VIEW")
7:
test_event.keycode = KEY_P
test_event.ctrl_pressed = true
Input.parse_input_event(test_event)
#print("CAMERA VIEW")
_:
print(angle_start)
printerr("BAD MATCH CASE")
is_pie_menu_key_pressed = false
func _exit_tree() -> void:
pass
func on_change_test(screen_name : String):
active_main_screen = screen_name
Image overlay that I used for UI