Last active
July 30, 2022 07:20
-
-
Save steezeburger/a84e7ffbe9eff567b463d91ea9bd7583 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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