OverviewFilesCommitsIssuesDocsReleasesPeers

godot-tumble_player_demo / player / player_state_local.gd

174 lines · gd ref:
extends KinematicBody

var direction = Vector3.BACK
var originalOrigin : Transform
var velocity = Vector3.ZERO
var strafe_dir = Vector3.ZERO
var strafe = Vector3.ZERO

onready var animationTree : AnimationTree = $AnimationTree
onready var mesh : Spatial = $Mesh

onready var collisionShape : CollisionShape = $CollisionShape
onready var stepRayCast : RayCast = $Mesh/StepRayCast
onready var stepMesh : MeshInstance = $Mesh/StepRayCast/MeshInstance

onready var camRoot : Spatial = $Mesh/Camroot
onready var camRootH : Spatial = $Mesh/Camroot/h
onready var camRootHV : Spatial = $Mesh/Camroot/h/v

onready var rollWindow : Timer = $roll_window
onready var rollTimer : Timer = $roll_window/roll_timer


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, camRootH.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 _on_LocalInput_player_mousemotion_event(event : InputEventMouseMotion) -> void:
	pass
	# aim_turn = -event.relative.x * 0.015 #animates player with mouse movement while aiming (used in line 104)
		
func _on_LocalInput_player_action_roll(event) -> void:
	if !animationTree.get("parameters/roll/active"): # The "Tap To Roll" system
		if rollTimer.is_stopped():
			# $roll_window.start()
			velocity = direction * roll_magnitude
			animationTree.set("parameters/roll/active", true)
			animationTree.set("parameters/aim_transition/current", 1)
			rollTimer.start()
			
func _on_LocalInput_player_restore_origin() -> void:
	self.transform = originalOrigin
	self.velocity = Vector3.ZERO
	vertical_velocity = 0
	
func _on_LocalInput_player_move(_direction):
	pass
	# direction = _direction

func _physics_process(delta):
	var jumpedThisFrame : bool = false
		
	var snapVector : Vector3 = -get_floor_normal()
	
	if !rollTimer.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 = camRootH.global_transform.basis.get_euler().y
	
	if is_on_floor() && Input.is_action_pressed("jump"):
		jumpedThisFrame = true
		vertical_velocity = -13.0
		snapVector = Vector3.ZERO
		
	if direction != Vector3.ZERO:
		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 = camRootH.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, camRootH.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