gui_3d.gd 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. extends Spatial
  2. # Member variables
  3. var prev_pos = null
  4. var last_click_pos = null
  5. var viewport = null
  6. func _input(event):
  7. # Check if the event is a non-mouse event
  8. var is_mouse_event = false
  9. var mouse_events = [InputEventMouseButton, InputEventMouseMotion, InputEventScreenDrag, InputEventScreenTouch]
  10. for mouse_event in mouse_events:
  11. if event is mouse_event:
  12. is_mouse_event = true
  13. break
  14. # If it is, then pass the event to the viewport
  15. if is_mouse_event == false:
  16. viewport.input(event)
  17. # Mouse events for Area
  18. func _on_area_input_event(camera, event, click_pos, click_normal, shape_idx):
  19. # Use click pos (click in 3d space, convert to area space)
  20. var pos = get_node("Area").get_global_transform().affine_inverse()
  21. # the click pos is not zero, then use it to convert from 3D space to area space
  22. if click_pos.x != 0 or click_pos.y != 0 or click_pos.z != 0:
  23. pos *= click_pos
  24. last_click_pos = click_pos
  25. else:
  26. # Otherwise, we have a motion event and need to use our last click pos
  27. # and move it according to the relative position of the event.
  28. # NOTE: this is not an exact 1-1 conversion, but it's pretty close
  29. pos *= last_click_pos
  30. if event is InputEventMouseMotion or event is InputEventScreenDrag:
  31. pos.x += event.relative.x / viewport.size.x
  32. pos.y += event.relative.y / viewport.size.y
  33. last_click_pos = pos
  34. # Convert to 2D
  35. pos = Vector2(pos.x, pos.y)
  36. # Convert to viewport coordinate system
  37. # Convert pos to a range from (0 - 1)
  38. pos.y *= -1
  39. pos += Vector2(1, 1)
  40. pos = pos / 2
  41. # Convert pos to be in range of the viewport
  42. pos.x *= viewport.size.x
  43. pos.y *= viewport.size.y
  44. # Set the position in event
  45. event.position = pos
  46. event.global_position = pos
  47. if not prev_pos:
  48. prev_pos = pos
  49. if event is InputEventMouseMotion:
  50. event.relative = pos - prev_pos
  51. prev_pos = pos
  52. # Send the event to the viewport
  53. viewport.input(event)
  54. func _ready():
  55. viewport = get_node("Viewport")
  56. get_node("Area").connect("input_event", self, "_on_area_input_event")