pickup_able_body.gd 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. extends RigidBody3D
  2. class_name PickupAbleBody3D
  3. var highlight_material : Material = preload("res://shaders/highlight_material.tres")
  4. var picked_up_by : Area3D
  5. var closest_areas : Array
  6. var original_parent : Node3D
  7. var tween : Tween
  8. # Called when this object becomes the closest body in an area
  9. func add_is_closest(area : Area3D) -> void:
  10. if not closest_areas.has(area):
  11. closest_areas.push_back(area)
  12. _update_highlight()
  13. # Called when this object becomes the closest body in an area
  14. func remove_is_closest(area : Area3D) -> void:
  15. if closest_areas.has(area):
  16. closest_areas.erase(area)
  17. _update_highlight()
  18. # Returns whether we have been picked up.
  19. func is_picked_up() -> bool:
  20. # If we have a valid picked up by object,
  21. # we've been picked up
  22. if picked_up_by:
  23. return true
  24. return false
  25. # Pick this object up.
  26. func pick_up(pick_up_by) -> void:
  27. # Already picked up? Can't pick up twice.
  28. if picked_up_by:
  29. if picked_up_by == pick_up_by:
  30. return
  31. let_go()
  32. # Remember some state we want to reapply on release.
  33. original_parent = get_parent()
  34. var current_transform = global_transform
  35. # Remove us from our old parent.
  36. original_parent.remove_child(self)
  37. # Process our pickup.
  38. picked_up_by = pick_up_by
  39. picked_up_by.add_child(self)
  40. global_transform = current_transform
  41. freeze = true
  42. # Kill any existing tween and create a new one.
  43. if tween:
  44. tween.kill()
  45. tween = create_tween()
  46. # Snap the object to this transform.
  47. var snap_to : Transform3D
  48. # Add code here to determine snap position and orientation.
  49. # Now tween
  50. tween.tween_property(self, "transform", snap_to, 0.1)
  51. # Let this object go.
  52. func let_go() -> void:
  53. # Ignore if we haven't been picked up.
  54. if not picked_up_by:
  55. return
  56. # Cancel any ongoing tween
  57. if tween:
  58. tween.kill()
  59. tween = null
  60. # Remember our current transform.
  61. var current_transform = global_transform
  62. # Remove us from what picked us up.
  63. picked_up_by.remove_child(self)
  64. picked_up_by = null
  65. # Reset some state.
  66. original_parent.add_child(self)
  67. global_transform = current_transform
  68. freeze = false
  69. # Update our highlight to show that we can be picked up
  70. func _update_highlight() -> void:
  71. if not picked_up_by and not closest_areas.is_empty():
  72. # add highlight
  73. for child in get_children():
  74. if child is MeshInstance3D:
  75. var mesh_instance : MeshInstance3D = child
  76. mesh_instance.material_overlay = highlight_material
  77. else:
  78. # remove highlight
  79. for child in get_children():
  80. if child is MeshInstance3D:
  81. var mesh_instance : MeshInstance3D = child
  82. mesh_instance.material_overlay = null