Created
January 29, 2020 16:16
-
-
Save untodesu/7eb1e1625e45aadc8cc8b709e3e380aa to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
| # the user command structure | |
| # this contains wish directions for player | |
| var cmd = { | |
| move_forward = 0.0, | |
| move_right = 0.0, | |
| move_up = 0.0, # is this actually needed here? Carmack, why? | |
| }; | |
| # Export variables | |
| export var mouse_sensitivity = 0.1; | |
| export var gravity = 800; | |
| export var friction = 6.0; | |
| export var move_speed = 15.0; | |
| export var run_accel = 25.0; | |
| export var run_deaccel = 20.0; | |
| export var air_accel = 2.0; | |
| export var air_deaccel = 2.0; | |
| export var air_control_value = 0.1; | |
| export var side_strafe_accel = 25.0; | |
| export var side_strafe_speed = 1.0; | |
| export var jump_speed = 8.0; | |
| export var move_scale = 1.0; | |
| export var auto_jump = false; | |
| var m_wish_jump = false; | |
| var m_direction = Vector3(); | |
| var m_velocity = Vector3(); | |
| var m_vecUp = Vector3(0, 1, 0); | |
| var m_camera; | |
| var m_jump_sound; | |
| # Check for jump needance | |
| func queue_jump(): | |
| if(Input.is_action_just_pressed("in_jump") && !m_wish_jump): | |
| m_wish_jump = true; | |
| if(Input.is_action_just_released("in_jump")): | |
| m_wish_jump = false; | |
| # Process input (Moving, not jumping) | |
| func process_input(): | |
| cmd.move_forward = 0.0; | |
| cmd.move_right = 0.0; | |
| cmd.move_forward += int(Input.is_action_pressed("in_forward")); | |
| cmd.move_forward -= int(Input.is_action_pressed("in_backward")); | |
| cmd.move_right += int(Input.is_action_pressed("in_right")); | |
| cmd.move_right -= int(Input.is_action_pressed("in_left")); | |
| # Calculate total commands scale | |
| func cmd_scale(): | |
| var abs_fwd = abs(cmd.move_forward); | |
| var abs_rgt = abs(cmd.move_right); | |
| # Calculate maximum value | |
| var var_max = abs_fwd; | |
| if(abs_rgt > var_max): | |
| var_max = abs_rgt; | |
| if(var_max <= 0): | |
| return 0; | |
| # Final scale | |
| var total = sqrt(cmd.move_forward * cmd.move_forward + cmd.move_right * cmd.move_right); | |
| return (move_speed * var_max / (move_scale * total)); | |
| # Apply acceleration | |
| func accelerate(wish_dir : Vector3, wish_speed : float, accel : float, delta : float): | |
| # See if we are changing direction a bit | |
| var current_speed = m_velocity.dot(wish_dir); | |
| # Reduce wishspeed by the amount of veer. | |
| var add_speed = (wish_speed - current_speed); | |
| # If not going to add any speed, done. | |
| if(add_speed <= 0): | |
| return; | |
| # Determine amount of accleration. | |
| var accel_speed = (accel * wish_speed * delta); | |
| # Cap at addspeed | |
| if(accel_speed > add_speed): | |
| accel_speed = add_speed; | |
| # Adjust velocity. | |
| m_velocity += (accel_speed * wish_dir); | |
| # Apply friction to the player | |
| func apply_friction(fct : float, delta : float): | |
| var vec = m_velocity; | |
| var speed = 0.0; | |
| var new_speed = 0.0; | |
| var control = 0.0; | |
| var drop = 0.0; | |
| # We 'braking' the player only on ground! | |
| # so we calculate speed without the Y axis | |
| vec.y = 0.0; | |
| speed = vec.length(); | |
| # Calculate the speed drop | |
| if(is_on_floor()): | |
| if(speed < run_deaccel): | |
| control = run_deaccel; | |
| else: | |
| control = speed; | |
| drop = (control * friction * delta * fct); | |
| # Calculate resulting speed factor | |
| new_speed = (speed - drop); | |
| if(new_speed < 0): | |
| new_speed = 0; | |
| if(new_speed > 0): | |
| new_speed /= speed; | |
| # Apply it to velocity | |
| m_velocity.x *= new_speed; | |
| m_velocity.z *= new_speed; | |
| # Process movement on ground | |
| func move_on_ground(delta : float): | |
| var wish_dir = Vector3(); | |
| # Apply friction | |
| if(!m_wish_jump): | |
| apply_friction(1.0, delta); | |
| else: | |
| apply_friction(0.0, delta); | |
| # Process cmd input | |
| cmd_scale(); | |
| process_input(); | |
| # Calculate direction | |
| wish_dir += transform.basis.x * cmd.move_right; | |
| wish_dir -= transform.basis.z * cmd.move_forward; | |
| # set the direction | |
| wish_dir = wish_dir.normalized(); | |
| m_direction = wish_dir; | |
| # Accelerate | |
| var wish_speed = wish_dir.length(); | |
| wish_speed *= move_speed; | |
| accelerate(wish_dir, wish_speed, run_accel, delta); | |
| # Jump if needed | |
| # Override Y | |
| m_velocity.y = 0.0; | |
| if(m_wish_jump): | |
| m_velocity.y = jump_speed; | |
| m_wish_jump = auto_jump; | |
| m_jump_sound.play(); | |
| # Air movement helper | |
| func air_control(wish_dir : Vector3, wish_speed : float, delta : float): | |
| # If our speeds are so small, just ignore em | |
| if(((abs(cmd.move_forward)) < 0.001) || (abs(wish_speed) < 0.001)): | |
| return | |
| # Save and discard the vertical speed | |
| var y_speed = m_velocity.y; | |
| m_velocity.y = 0.0; | |
| # calculate horizontal speed and and prepare velocity vector | |
| var speed = m_velocity.length(); | |
| m_velocity = m_velocity.normalized(); | |
| var dot_val = m_velocity.dot(wish_dir); | |
| var k = 32.0 * (air_control_value * pow(dot_val, 2) * delta); | |
| if(dot_val > 0): | |
| m_velocity.x = (m_velocity.x * speed) + (wish_dir.x * k); | |
| m_velocity.y = (m_velocity.y * speed) + (wish_dir.y * k); | |
| m_velocity.z = (m_velocity.z * speed) + (wish_dir.z * k); | |
| m_velocity = m_velocity.normalized(); | |
| m_direction = m_velocity; | |
| m_velocity.x *= speed; | |
| m_velocity.y = y_speed; | |
| m_velocity.z *= speed; | |
| # Process movement in the air | |
| func move_in_air(delta : float): | |
| var wish_dir = Vector3(); | |
| var accel = 0.0; | |
| # Process input | |
| cmd_scale(); | |
| process_input(); | |
| # Calculate the direction | |
| wish_dir += transform.basis.x * cmd.move_right; | |
| wish_dir -= transform.basis.z * cmd.move_forward; | |
| # Calculate the speed | |
| var wish_speed = wish_dir.length(); | |
| wish_speed *= move_speed; | |
| wish_dir = wish_dir.normalized(); | |
| m_direction = wish_dir; | |
| # air control (acceleration and stuff) | |
| var wish_speed2 = wish_speed; | |
| if(m_velocity.dot(wish_dir) < 0): | |
| accel = air_deaccel; | |
| else: | |
| accel = air_accel; | |
| # If strafing only, use different values | |
| if((cmd.move_forward == 0) && (cmd.move_right != 0)): | |
| if(wish_speed > side_strafe_speed): | |
| wish_speed = side_strafe_speed; | |
| accel = side_strafe_accel; | |
| # Apply the air accel | |
| accelerate(wish_dir, wish_speed, accel, delta); | |
| if(air_control_value > 0): | |
| air_control(wish_dir, wish_speed2, delta); | |
| m_velocity.y -= (gravity * delta * 0.03125); # make it quake-like | |
| # Setup | |
| func _ready(): | |
| m_camera = get_node("Camera"); | |
| m_jump_sound = get_node("JumpSound"); | |
| Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED); | |
| pass | |
| # Loop | |
| func _physics_process(delta : float): | |
| queue_jump(); | |
| if(is_on_floor()): | |
| move_on_ground(delta); | |
| else: | |
| move_in_air(delta); | |
| m_velocity = move_and_slide(m_velocity, m_vecUp); | |
| # Process mouse input | |
| func _input(ev): | |
| if(ev is InputEventMouseMotion): | |
| rotate_y(-deg2rad(ev.relative.x) * mouse_sensitivity); | |
| m_camera.rotate_x(-deg2rad(ev.relative.y) * mouse_sensitivity); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment