movement_hand_walk.gd 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. @tool
  2. class_name XRToolsMovementHandWalk
  3. extends XRToolsMovementProvider
  4. ## Movement provider order
  5. @export var order : int = 15
  6. ## Velocity multiplier when flinging up walls
  7. @export var fling_multiplier : float = 0.5
  8. @export var max_velocity : float = 10.0
  9. @export var grav : float = 9.8
  10. var cur_grav_force : float = 0.0
  11. # Velocity averager
  12. @export var velocity_averages : int = 5
  13. @onready var _averager := XRToolsVelocityAveragerLinear.new(velocity_averages)
  14. @onready var _left_pusher_node := XRToolsHandPusher.find_left(self)
  15. @onready var _right_pusher_node := XRToolsHandPusher.find_right(self)
  16. func is_xr_class(name : String) -> bool:
  17. return name == "XRToolsMovementHandWalk" or super(name)
  18. func _ready():
  19. super()
  20. _left_pusher_node.move_by_offset.connect(update_move_offset_l)
  21. _right_pusher_node.move_by_offset.connect(update_move_offset_r)
  22. var move_offset_l : Vector3
  23. var move_offset_r : Vector3
  24. func update_move_offset_l(_move_offset: Vector3):
  25. move_offset_l = _move_offset
  26. func update_move_offset_r(_move_offset: Vector3):
  27. move_offset_r = _move_offset
  28. ## Perform player physics movement
  29. var _was_touching_floor = false
  30. const MAX_MOVE_OFFSET = 0.1
  31. func physics_movement(delta: float, player_body: XRToolsPlayerBody, disabled: bool):
  32. if disabled or !enabled:
  33. return
  34. var left_collided = _left_pusher_node.get_slide_collision_count() != 0
  35. var right_collided = _right_pusher_node.get_slide_collision_count() != 0
  36. var touching_floor = _left_pusher_node.is_on_floor() or _right_pusher_node.is_on_floor() or player_body.is_on_floor()
  37. var touching_anything = left_collided or right_collided or player_body.get_slide_collision_count() != 0
  38. var total_move_offset = move_offset_l + move_offset_r
  39. var move_offset_len = total_move_offset.length()
  40. if move_offset_len > MAX_MOVE_OFFSET:
  41. total_move_offset = total_move_offset / move_offset_len * MAX_MOVE_OFFSET
  42. total_move_offset /= delta
  43. move_offset_l = Vector3.ZERO
  44. move_offset_r = Vector3.ZERO
  45. if touching_floor or total_move_offset.y > 0.0:
  46. cur_grav_force = 0.1
  47. else:
  48. cur_grav_force += grav * delta
  49. if touching_anything:
  50. _averager.add_distance(delta, total_move_offset)
  51. if touching_floor:
  52. if !_was_touching_floor:
  53. _averager.clear()
  54. player_body.velocity = total_move_offset
  55. else:
  56. player_body.velocity = _averager.velocity() * delta * fling_multiplier
  57. var v = player_body.velocity.length()
  58. if v > max_velocity:
  59. player_body.velocity = player_body.velocity / v * max_velocity
  60. player_body.velocity += total_move_offset
  61. player_body.velocity += Vector3.DOWN * cur_grav_force
  62. player_body.move_and_slide()
  63. _was_touching_floor = touching_floor
  64. return true
  65. # This method verifies the movement provider has a valid configuration.
  66. func _get_configuration_warnings() -> PackedStringArray:
  67. var warnings := super()
  68. # Verify the left controller pickup
  69. if !XRToolsHandPusher.find_left(self):
  70. warnings.append("Unable to find left XRToolsHandPusher node")
  71. # Verify the right controller pickup
  72. if !XRToolsHandPusher.find_right(self):
  73. warnings.append("Unable to find right XRToolsHandPusher node")
  74. # Verify velocity averages
  75. if velocity_averages < 2:
  76. warnings.append("Minimum of 2 velocity averages needed")
  77. # Return warnings
  78. return warnings