extends KinematicBody
var direction = Vector3.BACK
var originalOrigin : Transform
var velocity = Vector3.ZERO
var strafe_dir = Vector3.ZERO
var strafe = Vector3.ZERO
onready var collisionShape : CollisionShape = $CollisionShape
onready var stepRayCast : RayCast = $Mesh/StepRayCast
onready var stepMesh : MeshInstance = $Mesh/StepRayCast/MeshInstance
var aim_turn = 0
var vertical_velocity = 0
var gravity = 20
var blendAmount : float = 0.0
var movement_speed = 0
var walk_speed = 1.5
var run_speed = 15
var acceleration = 6
var angular_acceleration = 7
var roll_magnitude = 17
func _ready():
direction = Vector3.BACK.rotated(Vector3.UP, $Camroot/h.global_transform.basis.get_euler().y)
# Sometimes in the level design you might need to rotate the Player object itself
# So changing the direction at the beginning
#Backup Origin
originalOrigin = self.transform
func _input(event):
pass
#if event is InputEventMouseMotion:
# aim_turn = -event.relative.x * 0.015 #animates player with mouse movement while aiming (used in line 104)
#if !$AnimationTree.get("parameters/roll/active"): # The "Tap To Roll" system
# if event.is_action_pressed("roll"):
# if $roll_timer.is_stopped():
# # $roll_window.start()
# velocity = direction * roll_magnitude
# $AnimationTree.set("parameters/roll/active", true)
# $AnimationTree.set("parameters/aim_transition/current", 1)
# $roll_timer.start()
func restorePlayerToOrigin() -> void:
self.transform = originalOrigin
self.velocity = Vector3.ZERO
vertical_velocity = 0
func _physics_process(delta):
# if stepRayCast.is_colliding():
# print("I'm colliding!")
var jumpedThisFrame : bool = false
if Input.is_action_just_pressed("restoreOrigin"):
restorePlayerToOrigin()
return
var snapVector : Vector3 = -get_floor_normal()
if !$roll_timer.is_stopped():
acceleration = 3.5
else:
acceleration = 5
if Input.is_action_pressed("aim"):
if !$AnimationTree.get("parameters/roll/active"):
$AnimationTree.set("parameters/aim_transition/current", 0)
else:
$AnimationTree.set("parameters/aim_transition/current", 1)
var h_rot = $Camroot/h.global_transform.basis.get_euler().y
#if Input.is_action_pressed("skiis"):
if is_on_floor() && Input.is_action_pressed("jump"):
jumpedThisFrame = true
vertical_velocity = -13.0
snapVector = Vector3.ZERO
if Input.is_action_pressed("forward") || Input.is_action_pressed("backward") || Input.is_action_pressed("left") || Input.is_action_pressed("right"):
direction = Vector3(Input.get_action_strength("left") - Input.get_action_strength("right"),
0,
Input.get_action_strength("forward") - Input.get_action_strength("backward"))
strafe_dir = direction
direction = direction.rotated(Vector3.UP, h_rot).normalized()
if !is_on_floor():
movement_speed = 0
acceleration = 0
strafe_dir = Vector3.ZERO
snapVector = Vector3.DOWN
elif Input.is_action_pressed("sprint") && $AnimationTree.get("parameters/aim_transition/current") == 1:
movement_speed = run_speed
# $AnimationTree.set("parameters/iwr_blend/blend_amount", lerp($AnimationTree.get("parameters/iwr_blend/blend_amount"), 1, delta * acceleration))
else:
movement_speed = walk_speed
# $AnimationTree.set("parameters/iwr_blend/blend_amount", lerp($AnimationTree.get("parameters/iwr_blend/blend_amount"), 0, delta * acceleration))
else:
# $AnimationTree.set("parameters/iwr_blend/blend_amount", lerp($AnimationTree.get("parameters/iwr_blend/blend_amount"), -1, delta * acceleration))
movement_speed = 0
strafe_dir = Vector3.ZERO
if $AnimationTree.get("parameters/aim_transition/current") == 0:
direction = $Camroot/h.global_transform.basis.z
# Calculate actual velocity
velocity = lerp(velocity, direction * movement_speed, delta * acceleration)
vertical_velocity += gravity * delta
# move_and_slide(velocity + Vector3.DOWN * vertical_velocity, Vector3.UP)
move_and_slide_with_snap(velocity + Vector3.DOWN * vertical_velocity, snapVector, Vector3.UP)
# Check for Step
stepRayCast.cast_to.z = collisionShape.shape.radius + 0.1 + ( velocity.length() * delta)
stepMesh.translation.z = stepRayCast.cast_to.z
if is_on_wall():
if !stepRayCast.is_colliding():
self.translation.y += stepRayCast.translation.y
if is_on_floor():
vertical_velocity = 0
blendAmount = 0.0
if(vertical_velocity < 0): # Moving Up
#if jumpedThisFrame:
blendAmount = -1
$AnimationTree.set("parameters/air_transition/current", 0)
$AnimationTree.set("parameters/air_blend/blend_amount", blendAmount)
#else:
# blendAmount = max(-1.0, (vertical_velocity * delta) * 10)
# $AnimationTree.set("parameters/air_blend/blend_amount", blendAmount)
elif(vertical_velocity > 0): # Moving Down (falling)
$AnimationTree.set("parameters/air_transition/current", 0)
blendAmount = -1 + min(1.0, (vertical_velocity * delta) * 10)
$AnimationTree.set("parameters/air_blend/blend_amount", blendAmount)
else: # Walking
$AnimationTree.set("parameters/air_transition/current", 1)
if $AnimationTree.get("parameters/aim_transition/current") == 1:
$Mesh.rotation.y = lerp_angle($Mesh.rotation.y, atan2(direction.x, direction.z) - rotation.y, delta * angular_acceleration)
# rotation.y = lerp_angle(rotation.y, atan2(direction.x, direction.z) - rotation.y, delta * angular_acceleration)
# Sometimes in the level design you might need to rotate the Player object itself
# - rotation.y in case you need to rotate the Player object
else:
$Mesh.rotation.y = lerp_angle($Mesh.rotation.y, $Camroot/h.rotation.y, delta * angular_acceleration)
# lerping towards $Camroot/h.rotation.y while aiming, h_rot(as in the video) doesn't work if you rotate Player object
strafe = lerp(strafe, strafe_dir + Vector3.RIGHT * aim_turn, delta * acceleration)
$AnimationTree.set("parameters/strafe/blend_position", Vector2(-strafe.x, strafe.z))
var iw_blend = (velocity.length() - walk_speed) / walk_speed
var wr_blend = (velocity.length() - walk_speed) / (run_speed - walk_speed)
#find the graph here: https://www.desmos.com/calculator/4z9devx1ky
if velocity.length() <= walk_speed:
$AnimationTree.set("parameters/iwr_blend/blend_amount" , iw_blend)
else:
$AnimationTree.set("parameters/iwr_blend/blend_amount" , wr_blend)
aim_turn = 0