Advertisement
Guest User

Untitled

a guest
Apr 25th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.66 KB | None | 0 0
  1. extends Spatial
  2.  
  3. export var keep_input_true = true
  4.  
  5. var velocity = Vector3()
  6. var direction = Vector3()
  7.  
  8. export var character_height = 1.7
  9.  
  10. # Walk
  11. export var MAX_SPEED = 2.5
  12. export var MAX_RUNNING_SPEED = 5.0
  13. export var MAX_WALK_SPEED = 1.0
  14. export var CROUCH_MULT = 0.5
  15. var ACCEL = 20
  16. var DEACCEL = 20
  17. var air_control = 0.3
  18.  
  19. # Jump
  20. var jump_height = 3.5
  21.  
  22. # Fly
  23. const FLY_SPEED = 40
  24. const FLY_ACCEL = 4
  25.  
  26. # Crouch
  27. var crouching = false
  28. var crouch_height_diff = 0.8
  29.  
  30. # Stair
  31. var stair_detection = true
  32. export var stair_speed_mult = 1.0
  33. var stair_detect_static = true
  34. var stair_detect_rigid = false
  35. var stair_step_max_height = 0.25
  36. var stair_check_extent = 0.7
  37. var stair_smoothen_duration = 0.0
  38.  
  39. var stair_nodes = []
  40. var known_stair_nodes = []
  41. var stair_check_query = PhysicsShapeQueryParameters.new()
  42. var stair_check_shape = BoxShape.new()
  43. var is_on_stair = false
  44. var on_stair_duration = 1.0
  45. var on_stair_timer = 0.0
  46.  
  47. # Ledge grabbing
  48. var ledge_grab_distance = 0.45
  49. var ledge_grab_max_height = 2.0 #From feet
  50. var ledge_grab_min_height = 0.5
  51. var ledge_grab_horizontal = 0.5
  52. var ledge_angle_max = PI/2
  53.  
  54. var ledge_hold_duration = 0.4
  55. var ledge_up_force = 3
  56.  
  57. var ledge_grabbing = false
  58. var ledge_hold_time = 0
  59.  
  60. var ledge_grab_query = PhysicsShapeQueryParameters.new()
  61. var ledge_grab_shape = BoxShape.new()
  62.  
  63. # Input
  64. var move_forward = false
  65. var move_backward = false
  66. var move_left = false
  67. var move_right = false
  68. var move_jump = false
  69. var move_sprint = false
  70. var move_walk = false
  71. var move_crouch_toggle = false
  72. var move_ledge_grab = false
  73.  
  74. func _ready():
  75. ledge_grab_query.set_shape(ledge_grab_shape)
  76. ledge_grab_query.exclude = [get_parent()]
  77.  
  78. stair_check_query.set_shape(stair_check_shape)
  79. stair_check_query.exclude = [get_parent()]
  80.  
  81. func input(property, val):
  82. if get(property) != null:
  83. set(property, val)
  84.  
  85. func move_walk(delta):
  86. #if move_forward: Debug.msg(move_forward, "move_forward", "%s's movement" % get_parent().name, 0.06)
  87. #if move_backward: Debug.msg(move_backward, "move_backward", "%s's movement" % get_parent().name, 0.06)
  88. #if move_left: Debug.msg(move_left, "move_left", "%s's movement" % get_parent().name, 0.06)
  89. #if move_right: Debug.msg(move_right, "move_right", "%s's movement" % get_parent().name, 0.06)
  90. #if move_jump: Debug.msg(move_jump, "move_jump", "%s's movement" % get_parent().name, 0.06)
  91. #if move_sprint: Debug.msg(move_sprint, "move_sprint", "%s's movement" % get_parent().name, 0.06)
  92. #if move_walk: Debug.msg(move_walk, "move_walk", "%s's movement" % get_parent().name, 0.06)
  93. #if move_crouch_toggle: Debug.msg(move_crouch_toggle, "move_crouch_toggle", "%s's movement" % get_parent().name, 0.06)
  94. #if move_ledge_grab: Debug.msg(move_ledge_grab, "move_ledge_grab", "%s's movement" % get_parent().name, 0.06)
  95.  
  96. direction = Vector3()
  97.  
  98. var aim = get_parent().get_global_transform().basis
  99. aim.z.y = 0
  100.  
  101. if !ledge_grabbing:
  102. if move_forward:
  103. direction -= aim.z
  104. if move_backward:
  105. direction += aim.z
  106. if move_left:
  107. direction -= aim.x
  108. if move_right:
  109. direction += aim.x
  110. if move_jump and get_parent().is_on_floor():
  111. move_jump = false
  112. if !hitting_head():
  113. velocity.y = jump_height
  114. #Debug.msg("Jumped!", "", "%s's movement" % get_parent().name)
  115.  
  116. if move_ledge_grab:
  117. ledge_grabbing = check_ledge()
  118. else:
  119. if move_ledge_grab:
  120. if check_ledge(true):
  121. ledge_hold_time += delta
  122. #Debug.msg(ledge_hold_duration - ledge_hold_time, "Hold timer: ", "%s's movement" % get_parent().name)
  123. else:
  124. ledge_grabbing = false
  125. ledge_hold_time = 0
  126. else:
  127. ledge_grabbing = false
  128. ledge_hold_time = 0
  129.  
  130. if move_crouch_toggle:
  131. move_crouch_toggle = false
  132. if crouching:
  133. if !hitting_head():
  134. set_crouch(false)
  135. else:
  136. set_crouch(true)
  137.  
  138. #Debug.msg(crouching, "Crouching", "%s's movement" % get_parent().name)
  139.  
  140. direction = direction.normalized()
  141.  
  142. if !ledge_grabbing:
  143. velocity -= Global.gravity * Global.gravity_vector * delta
  144. elif ledge_hold_time >= ledge_hold_duration:
  145. velocity.y = ledge_up_force
  146. else:
  147. velocity.y = 0
  148.  
  149. var temp_velocity = velocity
  150. temp_velocity.y = 0
  151.  
  152. if stair_detection:
  153. check_stair()
  154.  
  155. if on_stair_timer >= 0:
  156. on_stair_timer -= delta
  157. else:
  158. is_on_stair = false
  159.  
  160. #Debug.msg(is_on_stair, "On Stair", "%s's movement" % get_parent().name)
  161.  
  162. var speed
  163. if move_sprint:
  164. speed = MAX_RUNNING_SPEED
  165. elif move_walk:
  166. speed = MAX_WALK_SPEED
  167. else:
  168. speed = MAX_SPEED
  169.  
  170. if crouching:
  171. speed *= CROUCH_MULT
  172.  
  173. if is_on_stair:
  174. speed *= stair_speed_mult
  175.  
  176. var target = direction * speed
  177.  
  178. var acceleration
  179. if direction.dot(temp_velocity) > 0:
  180. acceleration = ACCEL
  181. else:
  182. acceleration = DEACCEL
  183.  
  184. if !get_parent().is_on_floor():
  185. acceleration *= air_control
  186.  
  187. temp_velocity = temp_velocity.linear_interpolate(target, acceleration * delta)
  188.  
  189. velocity.x = temp_velocity.x
  190. velocity.z = temp_velocity.z
  191.  
  192. velocity = get_parent().move_and_slide(velocity, Vector3(0, 1, 0))
  193.  
  194. if stair_detection:
  195. clear_stairs()
  196.  
  197. var slides = get_parent().get_slide_count()
  198.  
  199. for ss in slides:
  200. var col = get_parent().get_slide_collision(ss).collider
  201. if col.get("sleeping") != null:
  202. if col.sleeping:
  203. col.set_sleeping(false)
  204. col.emit_signal("sleeping_state_changed")
  205. #Debug.msg("Woke up!", "", col.name)
  206.  
  207. if !keep_input_true:
  208. move_forward = false
  209. move_backward = false
  210. move_left = false
  211. move_right = false
  212. move_jump = false
  213. move_sprint = false
  214. move_walk = false
  215. move_crouch_toggle = false
  216. move_ledge_grab = false
  217.  
  218. func hitting_head():
  219. var ray = get_parent().get_world().direct_space_state.intersect_ray(get_parent().global_transform.origin, get_parent().global_transform.origin + Vector3(0, crouch_height_diff + 0.05, 0), [get_parent()])
  220. Debug.msg(!ray.empty(), "Hitting Head", "%s's movement" % get_parent().name)
  221. return !ray.empty()
  222.  
  223. func set_crouch(val):
  224. crouching = val
  225.  
  226. if val:
  227. character_height -= crouch_height_diff
  228.  
  229. get_node("../BodyShape").shape.height -= crouch_height_diff
  230. #get_node("../BodyShape").translation.y -= crouch_height_diff / 2
  231. get_node("../Head").translation.y -= crouch_height_diff / 2
  232.  
  233. get_node("../BodyMesh").mesh.mid_height -= crouch_height_diff
  234. #get_node("../BodyMesh").translation.y -= crouch_height_diff / 2
  235. get_node("../HeadMesh").translation.y -= crouch_height_diff / 2
  236. else:
  237. character_height += crouch_height_diff
  238.  
  239. get_node("../BodyShape").shape.height += crouch_height_diff
  240. #get_node("../BodyShape").translation.y += crouch_height_diff / 2
  241. get_node("../Head").translation.y += crouch_height_diff / 2
  242.  
  243. get_node("../BodyMesh").mesh.mid_height += crouch_height_diff
  244. #get_node("../BodyMesh").translation.y += crouch_height_diff / 2
  245. get_node("../HeadMesh").translation.y += crouch_height_diff / 2
  246.  
  247. func check_ledge(check_only = false):
  248. var space = get_parent().get_world().direct_space_state
  249. var feetpos = get_parent().global_transform
  250. feetpos.origin -= Vector3(0, character_height / 2, 0)
  251.  
  252. var min_height = ledge_grab_min_height
  253. if check_only:
  254. min_height = 0.0
  255.  
  256. var heading = Vector2(get_parent().global_transform.basis.z.x, get_parent().global_transform.basis.z.z).angle_to(Vector2(-1, 0))
  257.  
  258. #Check if there's actually a ledge to grab first, return false if there isn't
  259. var extents = Vector3(ledge_grab_horizontal, ledge_grab_max_height - min_height, ledge_grab_distance) / 2 #(hor, vert, depth)
  260. var shape_transform = feetpos
  261. shape_transform.origin += Vector3(ledge_grab_distance / 2, extents.y + min_height, 0).rotated(Vector3(0, 1, 0), heading)
  262.  
  263. ledge_grab_query.transform = shape_transform
  264. ledge_grab_shape.extents = extents
  265.  
  266. var intersect = space.intersect_shape(ledge_grab_query)
  267.  
  268. if !ledge_grabbing or ledge_hold_time >= ledge_hold_duration:
  269. if check_only:
  270. Debug.draw_cube(shape_transform, extents * 2, "grabbounds", Color(1, 1, 0, 0.15))
  271. else:
  272. Debug.draw_cube(shape_transform, extents * 2, "grabbounds", Color(0, 0, 1, 0.15))
  273.  
  274. var free = true
  275.  
  276. if !intersect.empty():
  277. for ii in intersect:
  278. if ii.collider != self:
  279. free = false
  280. #Debug.msg(true, ii.collider.name, "Ledge", 1.05)
  281. break
  282.  
  283. if free:
  284. return false
  285. elif check_only:
  286. return true
  287.  
  288. shape_transform.origin += Vector3(0, (ledge_grab_max_height - ledge_grab_min_height + 0.2) / 2, 0)
  289. extents.y = 0.1
  290.  
  291. ledge_grab_query.transform = shape_transform
  292. ledge_grab_shape.extents = extents
  293.  
  294. intersect = space.intersect_shape(ledge_grab_query)
  295.  
  296. if intersect.empty():
  297. Debug.draw_cube(shape_transform, extents * 2, "grabbounds", Color(0, 1, 0, 0.25))
  298. else:
  299. Debug.draw_cube(shape_transform, extents * 2, "grabbounds", Color(1, 0, 0, 0.25))
  300. return false
  301.  
  302. var ray_pos = Vector3(get_parent().global_transform.origin.x, shape_transform.origin.y, get_parent().global_transform.origin.z)
  303. var ray = space.intersect_ray(get_parent().global_transform.origin, ray_pos, [self])
  304.  
  305. if ray.empty():
  306. Debug.draw_ray(get_parent().global_transform.origin, ray_pos, "grabray", Color(0,1,0,1))
  307. return true
  308. else:
  309. Debug.draw_ray(get_parent().global_transform.origin, ray_pos, "grabray", Color(1,0,0,1))
  310.  
  311. return false
  312.  
  313. func check_stair():
  314. var shape_safezone = 0.05
  315. var space = get_parent().get_world().direct_space_state
  316. var feetpos = get_parent().global_transform
  317. feetpos.origin -= Vector3(0, character_height / 2 - shape_safezone, 0)
  318.  
  319. var feetray = space.intersect_ray(feetpos.origin + Vector3(0, 0.5, 0), feetpos.origin + Vector3(0, -1, 0), [get_parent()])
  320. Debug.draw_ray(feetpos.origin + Vector3(0, shape_safezone, 0), feetpos.origin + Vector3(0, -1, 0), "stairray", Color(1,0,1))
  321.  
  322. var feetcollider
  323. if !feetray.empty():
  324. feetcollider = feetray.collider
  325.  
  326. #print("%s Feet: %s" % [get_parent().name, feetray.collider.name])
  327.  
  328. #First see if there's anything to check
  329. var extents = Vector3(stair_check_extent, stair_step_max_height - shape_safezone, stair_check_extent) / 2 #(hor, vert, depth)
  330. var shape_transform = feetpos
  331. shape_transform.origin += Vector3(0, stair_step_max_height / 2, 0)
  332.  
  333. stair_check_query.transform = shape_transform
  334. stair_check_shape.extents = extents
  335.  
  336. var intersect = space.intersect_shape(stair_check_query)
  337.  
  338. if intersect.empty():
  339. Debug.draw_cube(shape_transform, extents * 2, "%sstairbounds1" % self, Color(1, 1, 1, 0.15))
  340. #print("%s No steps to check" % get_parent().name)
  341. return false
  342.  
  343. var bodiestocheck = []
  344. for ii in intersect:
  345. bodiestocheck.append(ii.collider)
  346.  
  347. #If there is, check if it's short enough
  348. extents = Vector3(stair_check_extent, character_height - stair_step_max_height - shape_safezone, stair_check_extent) / 2
  349. shape_transform.origin += Vector3(0, character_height / 2, 0)
  350.  
  351. stair_check_query.transform = shape_transform
  352. stair_check_shape.extents = extents
  353.  
  354. Debug.draw_cube(shape_transform, extents * 2, "%sstairbounds2" % self, Color(0, 1, 0, 0.15))
  355.  
  356. var intersect2 = space.intersect_shape(stair_check_query)
  357.  
  358. if !intersect2.empty():
  359. for ii2 in intersect2:
  360. while bodiestocheck.has(ii2.collider):
  361. bodiestocheck.erase(ii2.collider)
  362.  
  363. if bodiestocheck.empty():
  364. Debug.draw_cube(shape_transform, extents * 2, "%sstairbounds3" % self, Color(1, 0, 0, 0.15))
  365. return false
  366.  
  367. for bb in bodiestocheck:
  368. #print("Checking %s" % bb.name)
  369. if bb != feetcollider:
  370. if !stair_nodes.has(bb):
  371. var add = false
  372. if stair_detect_static and bb is StaticBody:
  373. add = true
  374. elif stair_detect_rigid and bb is RigidBody:
  375. add = true
  376.  
  377. if add:
  378. get_parent().add_collision_exception_with(bb)
  379. stair_nodes.append(bb)
  380.  
  381. if !known_stair_nodes.has(bb):
  382. known_stair_nodes.append(bb)
  383.  
  384. if known_stair_nodes.has(feetcollider):
  385. is_on_stair = true
  386. on_stair_timer = on_stair_duration
  387.  
  388. #Debug.msg(bb.name, "Added exception with", "%s's movement" % get_parent().name)
  389.  
  390. return true
  391.  
  392. func clear_stairs():
  393. for ss in stair_nodes:
  394. get_parent().remove_collision_exception_with(ss)
  395.  
  396. stair_nodes.clear()
  397.  
  398. func move_fly(delta):
  399. direction = Vector3()
  400.  
  401. var aim = $Head.get_global_transform().basis
  402.  
  403. if Input.is_action_pressed("move_forward"):
  404. direction -= aim.z
  405. if Input.is_action_pressed("move_backward"):
  406. direction += aim.z
  407. if Input.is_action_pressed("move_left"):
  408. direction -= aim.x
  409. if Input.is_action_pressed("move_right"):
  410. direction += aim.x
  411. if Input.is_action_pressed("move_jump"):
  412. direction += Vector3(0, 1, 0)
  413.  
  414. direction = direction.normalized()
  415.  
  416. var target = direction * FLY_SPEED
  417.  
  418. velocity = velocity.linear_interpolate(target, FLY_ACCEL * delta)
  419.  
  420. move_and_slide(velocity, Vector3(0, 1, 0))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement