player.gd 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. extends KinematicBody
  2. const ANIM_FLOOR = 0
  3. const ANIM_AIR_UP = 1
  4. const ANIM_AIR_DOWN = 2
  5. const SHOOT_TIME = 1.5
  6. const SHOOT_SCALE = 2
  7. const CHAR_SCALE = Vector3(0.3, 0.3, 0.3)
  8. const TURN_SPEED = 40
  9. var facing_dir = Vector3.RIGHT
  10. var movement_dir = Vector3()
  11. var linear_velocity = Vector3()
  12. var jumping = false
  13. var air_idle_deaccel = false
  14. var accel = 19.0
  15. var deaccel = 14.0
  16. var sharp_turn_threshold = 140
  17. var max_speed = 3.1
  18. var prev_shoot = false
  19. var shoot_blend = 0
  20. onready var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") * ProjectSettings.get_setting("physics/3d/default_gravity_vector")
  21. func _ready():
  22. get_node("AnimationTreePlayer").set_active(true)
  23. func _physics_process(delta):
  24. linear_velocity += gravity * delta
  25. var anim = ANIM_FLOOR
  26. var vv = linear_velocity.y # Vertical velocity.
  27. var hv = Vector3(linear_velocity.x, 0, linear_velocity.z) # Horizontal velocity.
  28. var hdir = hv.normalized() # Horizontal direction.
  29. var hspeed = hv.length() # Horizontal speed.
  30. # Player input
  31. var cam_basis = get_node("Target/Camera").get_global_transform().basis
  32. var dir = Vector3() # Where does the player intend to walk to.
  33. dir = Input.get_action_strength("move_right") * cam_basis[0]
  34. dir -= Input.get_action_strength("move_left") * cam_basis[0]
  35. dir += Input.get_action_strength("move_backwards") * cam_basis[2]
  36. dir -= Input.get_action_strength("move_forward") * cam_basis[2]
  37. dir.y = 0
  38. dir = dir.normalized()
  39. var jump_attempt = Input.is_action_pressed("jump")
  40. var shoot_attempt = Input.is_action_pressed("shoot")
  41. if is_on_floor():
  42. var sharp_turn = hspeed > 0.1 and rad2deg(acos(dir.dot(hdir))) > sharp_turn_threshold
  43. if dir.length() > 0.1 and !sharp_turn:
  44. if hspeed > 0.001:
  45. hdir = adjust_facing(hdir, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP)
  46. facing_dir = hdir
  47. else:
  48. hdir = dir
  49. if hspeed < max_speed:
  50. hspeed += accel * delta
  51. else:
  52. hspeed -= deaccel * delta
  53. if hspeed < 0:
  54. hspeed = 0
  55. hv = hdir * hspeed
  56. var mesh_xform = get_node("Armature").get_transform()
  57. var facing_mesh = -mesh_xform.basis[0].normalized()
  58. facing_mesh = (facing_mesh - Vector3.UP * facing_mesh.dot(Vector3.UP)).normalized()
  59. if hspeed > 0:
  60. facing_mesh = adjust_facing(facing_mesh, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP)
  61. var m3 = Basis(-facing_mesh, Vector3.UP, -facing_mesh.cross(Vector3.UP).normalized()).scaled(CHAR_SCALE)
  62. get_node("Armature").set_transform(Transform(m3, mesh_xform.origin))
  63. if not jumping and jump_attempt:
  64. vv = 7.0
  65. jumping = true
  66. get_node("SoundJump").play()
  67. else:
  68. if vv > 0:
  69. anim = ANIM_AIR_UP
  70. else:
  71. anim = ANIM_AIR_DOWN
  72. if dir.length() > 0.1:
  73. hv += dir * (accel * 0.2 * delta)
  74. if hv.length() > max_speed:
  75. hv = hv.normalized() * max_speed
  76. else:
  77. if air_idle_deaccel:
  78. hspeed = hspeed - (deaccel * 0.2 * delta)
  79. if hspeed < 0:
  80. hspeed = 0
  81. hv = hdir * hspeed
  82. if jumping and vv < 0:
  83. jumping = false
  84. linear_velocity = hv + Vector3.UP * vv
  85. if is_on_floor():
  86. movement_dir = linear_velocity
  87. linear_velocity = move_and_slide(linear_velocity, -gravity.normalized())
  88. if shoot_blend > 0:
  89. shoot_blend -= delta * SHOOT_SCALE
  90. if (shoot_blend < 0):
  91. shoot_blend = 0
  92. if shoot_attempt and not prev_shoot:
  93. shoot_blend = SHOOT_TIME
  94. var bullet = preload("res://bullet.tscn").instance()
  95. bullet.set_transform(get_node("Armature/Bullet").get_global_transform().orthonormalized())
  96. get_parent().add_child(bullet)
  97. bullet.set_linear_velocity(get_node("Armature/Bullet").get_global_transform().basis[2].normalized() * 20)
  98. bullet.add_collision_exception_with(self) # Add it to bullet.
  99. get_node("SoundShoot").play()
  100. prev_shoot = shoot_attempt
  101. if is_on_floor():
  102. get_node("AnimationTreePlayer").blend2_node_set_amount("walk", hspeed / max_speed)
  103. get_node("AnimationTreePlayer").transition_node_set_current("state", anim)
  104. get_node("AnimationTreePlayer").blend2_node_set_amount("gun", min(shoot_blend, 1.0))
  105. func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn):
  106. var n = p_target # Normal.
  107. var t = n.cross(current_gn).normalized()
  108. var x = n.dot(p_facing)
  109. var y = t.dot(p_facing)
  110. var ang = atan2(y,x)
  111. if abs(ang) < 0.001: # Too small.
  112. return p_facing
  113. var s = sign(ang)
  114. ang = ang * s
  115. var turn = ang * p_adjust_rate * p_step
  116. var a
  117. if ang < turn:
  118. a = ang
  119. else:
  120. a = turn
  121. ang = (ang - a) * s
  122. return (n * cos(ang) + t * sin(ang)) * p_facing.length()