Skip to content

Instantly share code, notes, and snippets.

@steezeburger
Last active July 30, 2022 07:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steezeburger/a84e7ffbe9eff567b463d91ea9bd7583 to your computer and use it in GitHub Desktop.
Save steezeburger/a84e7ffbe9eff567b463d91ea9bd7583 to your computer and use it in GitHub Desktop.
extends KinematicBody
"""
This file contains properties and functionality for a 3rd person player character.
Movement and mouse capture copied from:
https://www.youtube.com/watch?v=dcCzKHTxflo&list=PL_sLeUIth9Dp_VymeT0CpScopbg5ktoSk
"""
export var walking_speed = 10
export var running_speed = 30
export var acceleration = 70
export var friction = 60
export var air_friction = 1
export var gravity = -40
export var jump_impulse = 20
# controls how fast the helicopter spins
export var helicopter_rotation_constant = 1
export var mouse_sensitivity = .1
#export var controller_sensitivity = 3
#export var rot_speed = 5
export (int, 0, 10) var push_strength = 1
export(NodePath) var spawn_node
onready var spawn : Spatial = get_node(spawn_node)
#export (NodePath) var joystickRightPath
#onready var joystickRight : VirtualJoystick = get_node(joystickRightPath)
var velocity = Vector3.ZERO
var snap_vector = Vector3.ZERO
var current_speed = walking_speed
onready var robot_node = get_node("robot")
onready var initial_robot_transform = robot_node.transform
onready var spring_arm = $SpringArm
onready var camera = $SpringArm/Camera
onready var aimcast = $SpringArm/Camera/AimCast
func _ready():
pass
# self.global_transform = spawn.transform
# Globalsettings.connect("fov_updated", self, "_on_fov_updated")
# Globalsettings.connect("mouse_sens_updated", self, "_on_mouse_sens_updated")
func _unhandled_input(event):
# move camera w/ mouse
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
rotate_y(deg2rad(-event.relative.x * mouse_sensitivity))
spring_arm.rotate_x(deg2rad(-event.relative.y * mouse_sensitivity))
func _process(delta):
# check for fire input and if the collider is an enemy, do something about it!
if Input.is_action_just_pressed("fire"):
if aimcast.is_colliding():
var target = aimcast.get_collider()
print(target)
if target.is_in_group("destroyable"):
target.queue_free()
if target.is_in_group("enemy"):
if target.has_method('take_damage'):
target.take_damage()
print("hit enemy!")
func _physics_process(delta):
var input_vector = get_input_vector()
var direction = get_direction(input_vector)
run()
apply_movement(direction, delta)
apply_friction(direction, delta)
update_snap_vector()
apply_gravity(delta)
jump()
fly()
boost(direction, delta)
# apply_controller_rotation()
# rotate_player()
spring_arm.rotation.x = clamp(spring_arm.rotation.x, deg2rad(-75), deg2rad(75))
velocity = move_and_slide_with_snap(velocity, snap_vector, Vector3.UP, true, 4, 0.785398, false)
# check for collision against node in "moveable" group, and apply an impulse so the
# player is able to interact with them physically
for idx in get_slide_count():
var collision = get_slide_collision(idx)
if collision.collider.is_in_group("moveable"):
collision.collider.apply_central_impulse(-collision.normal * velocity.length() * push_strength)
#func rotate_player():
# rotate_y(deg2rad(joystickRight.get_output().x * mouse_sensitivity))
# spring_arm.rotate_x(deg2rad(joystickRight.get_output().y * mouse_sensitivity))
func get_input_vector():
"""
Returns vector describing the input from the user.
"""
var input_vector = Vector3.ZERO
input_vector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
input_vector.z = Input.get_action_strength("move_backward") - Input.get_action_strength("move_forward")
return input_vector.normalized() if input_vector.length() > 1 else input_vector
func get_direction(input_vector):
"""
Returns direction from user input.
"""
var direction = (input_vector.x * transform.basis.x) + (input_vector.z * transform.basis.z)
return direction
func apply_movement(direction, delta):
"""
Move character in direction of input vector.
"""
if direction != Vector3.ZERO:
velocity.x = velocity.move_toward(direction * current_speed, acceleration * delta).x
velocity.z = velocity.move_toward(direction * current_speed, acceleration * delta).z
func apply_friction(direction, delta):
"""
Applies ground or air friction when the user stops moving.
This ensures the player stops moving with a nice tiny slide.
"""
if direction == Vector3.ZERO:
if is_on_floor():
velocity = velocity.move_toward(Vector3.ZERO, friction * delta)
else:
velocity.x = velocity.move_toward(Vector3.ZERO, air_friction * delta).x
velocity.z = velocity.move_toward(Vector3.ZERO, air_friction * delta).z
func apply_gravity(delta):
"""
Set y component of velocity according to our game gravity.
"""
velocity.y += gravity * delta
velocity.y = clamp(velocity.y, gravity, jump_impulse)
func update_snap_vector():
snap_vector = -get_floor_normal() if is_on_floor() else Vector3.DOWN
func jump():
jump_impulse = 20
if Input.is_action_just_pressed("jump") and is_on_floor():
# must set snap_vactor to zero to allow the node to come off the floor
snap_vector = Vector3.ZERO
if abs(velocity.x) > 10 or abs(velocity.z) > 10:
# high jump if we're going fast enough
gravity = -20
else:
gravity = -40
velocity.y = jump_impulse
# this decays the jump faster if the button was released, which basically means
# this lets the player jump higher if they hold the jump button down
if Input.is_action_just_released("jump") and velocity.y > jump_impulse / 2:
velocity.y = jump_impulse / 2
func run():
if is_on_floor() and Input.is_action_pressed("run"):
current_speed = running_speed
else:
current_speed = walking_speed
func fly():
if Input.is_action_pressed("fly"):
# set snap_vector to zero so user can jump
snap_vector = Vector3.ZERO
# this will slowly increase y velocity, with an initial "impulse" of 5 because of the clamp
velocity.y = clamp(abs(velocity.y * 1.25), 5, 40)
# this will slowly increase the helicopter rotation speed.
# increase the constant multiplier to increase how fast it ramps up to max speed
# the last value is the max speed
# the second argument is the initial speed
helicopter_rotation_constant = clamp(helicopter_rotation_constant * 1.1, .5, 35)
# only rotate the robot node, so it looks like a helicopter
robot_node.rotate_y(deg2rad(helicopter_rotation_constant))
if Input.is_action_just_released("fly"):
# rotate bot to initial position after flying
robot_node.transform = initial_robot_transform
helicopter_rotation_constant = 0
var can_boost = true
var duration = 1.3
func boost(direction, delta):
duration = duration - delta
if duration <= 0:
can_boost = true
duration = 1
# give player ability to boost
if Input.is_action_pressed("run") and not is_on_floor():
if can_boost:
print("boost")
# TODO - figure out how to boost in direction of camera
# var forward = -camera.get_global_transform().basis.z
# velocity.x = velocity.x + 50
# velocity.y = velocity.y + 50
# velocity.x = velocity.move_toward(direction * 1000, 100 * delta).x
# velocity.z = velocity.move_toward(direction * 1000, 100 * delta).z
current_speed = current_speed + 100
can_boost = false
#func apply_controller_rotation():
# var axis_vector = Vector2.ZERO
# axis_vector.x = Input.get_action_strength("look_right") - Input.get_action_strength("look_left")
# axis_vector.y = Input.get_action_strength("look_down") - Input.get_action_strength("look_up")
#
# if InputEventJoypadMotion:
# rotate_y(deg2rad(-axis_vector.x) * controller_sensitivity)
# spring_arm.rotate_x(deg2rad(-axis_vector.y) * controller_sensitivity)
#
#
#func _on_fov_updated(value):
# camera.fov = value
#
#
#func _on_mouse_sens_updated(value):
# mouse_sensitivity = value
func _on_Grapes_body_entered(body):
print('on grapes body entered')
print(body)
# TODO - player can only pick grapes up after talking to the ShinyHeadTrinket
if body == self:
var grapes_item = preload("res://src/items/Grapes.tres")
InventoryManager.add_item(grapes_item, 1)
var grapes_node = get_node("../Grapes")
grapes_node.queue_free()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment