Add Sway and Bob

This commit is contained in:
2022-12-06 00:48:50 +01:00
parent 04a4ebc899
commit 825d86f271
26 changed files with 1513 additions and 116 deletions

110
scripts/player/PlayerQ3.gd Normal file
View File

@@ -0,0 +1,110 @@
extends CharacterBody3D
const DIST_FLOOR_SNAP := Vector3.DOWN * 0.2
@onready var body : Node3D = $Body
@onready var head : Node3D = $Body/Head
@onready var cam : Camera3D = $Body/Head/Camera3D
@export var mouse_sensitivity = 5.0
@export var stop_speed = 4.0
@export var move_speed = 20.0
@export var max_slope_angle = 50.0
@export var gravity = 60.0
@export var max_fall_speed = 50.0
@export var jump_height = 2.5
@export var accel_ground = 10.0
@export var accel_air = 1.0
#export var accel_water: float := 4.0
@export var friction_ground = 6.0
#export var friction_water: float := 1.0
var floor_snap := Vector3.ZERO
func get_move_direction() -> Vector3:
var input_dir := Vector2(
Input.get_action_strength("move_backward") - Input.get_action_strength("move_forward"),
Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
).normalized();
return input_dir.x * body.global_transform.basis.z + input_dir.y * body.global_transform.basis.x
func _input(event):
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED and event is InputEventMouseMotion:
rotate_look(event.relative * 0.001 * mouse_sensitivity)
func rotate_look(amount : Vector2) -> void:
body.rotation.y -= amount.x
head.rotation.x = clamp(head.rotation.x - amount.y, -PI * 0.5, PI * 0.5)
func _physics_process(delta):
var was_on_floor : bool = is_on_floor()
var h_target_dir : Vector3 = get_move_direction()
if is_on_floor():
apply_friction(delta)
accelerate(delta, h_target_dir, move_speed, accel_ground)
if Input.is_action_pressed("jump"):
velocity.y = sqrt(2 * jump_height * abs(gravity))
floor_snap = Vector3.ZERO
else:
# hack: only add gravity not checked ground, to prevent sliding checked slopes
# This works because move_and_slide_with_snap warps the player to the ground in other cases
velocity.y = max(-max_fall_speed, velocity.y - gravity * delta)
accelerate(delta, h_target_dir, move_speed, accel_air)
set_velocity(velocity)
# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `floor_snap`
set_up_direction(Vector3.UP)
set_floor_stop_on_slope_enabled(true)
set_max_slides(4)
set_floor_max_angle(deg_to_rad(max_slope_angle))
# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `false`
move_and_slide()
velocity = velocity
if !was_on_floor and is_on_floor():
floor_snap = DIST_FLOOR_SNAP
elif was_on_floor and !is_on_floor():
floor_snap = Vector3.ZERO
func accelerate(delta : float, p_target_dir : Vector3, p_target_speed : float, p_accel : float):
var current_speed : float = velocity.dot(p_target_dir)
var add_speed : float = p_target_speed - current_speed
if add_speed > 0:
var accel_speed : float = min(add_speed, p_accel * delta * p_target_speed)
velocity += p_target_dir * accel_speed
func apply_friction(delta : float):
var vec : Vector3 = velocity
var speed : float = velocity.length()
if is_zero_approx(speed):
velocity = Vector3.ZERO
return
var drop : float = 0.0
var control : float = max(speed, stop_speed)
# ground friction
if is_on_floor():
drop += control * friction_ground * delta
# water friction not implemented
var new_speed : float = max(0.0, speed - drop)
new_speed /= speed
velocity *= new_speed

81
scripts/player/Weapon.gd Normal file
View File

@@ -0,0 +1,81 @@
extends Node3D
class_name Weapon
const DEFAULT = 0
const INITIAL = 1
const SHOOT = 2
const RELOAD = 3
const DRAW_TIME = 0.35
#TODO: Load gun config from file
var MAX_CLIP : int
var DAMAGE : float
var MOMENTUM : Vector2
var ANGULAR_MOMENTUM : Vector3
var RECOIL_COOLDOWN : float
var RPM: float
var DRAW_POS : Vector3
var DRAW_ROT : Vector3
var MODEL : Node3D
var FIREMODE : int
var SHOOTING_SPEED: float
var can_shoot : bool
var clip = 444444
var state = DEFAULT
func init():
visible = true
SHOOTING_SPEED = 60.0 / RPM
var tween = create_tween()
MODEL.position = DRAW_POS
MODEL.rotation = DRAW_ROT
tween.set_trans(Tween.TRANS_CIRC)
tween.set_ease(Tween.EASE_IN_OUT)
can_shoot = true
tween.tween_callback(InitialPos).set_delay(DRAW_TIME)
func InitialPos():
var tween = create_tween()
tween.set_trans(Tween.TRANS_CIRC)
tween.set_ease(Tween.EASE_IN_OUT)
tween.set_parallel(true)
tween.tween_property(MODEL, "position", Vector3.ZERO, RECOIL_COOLDOWN / 2)
tween.tween_property(MODEL, "rotation", Vector3.ZERO, RECOIL_COOLDOWN / 2)
tween.tween_callback(func(): state = INITIAL).set_delay(SHOOTING_SPEED / 2)
func Shoot():
if clip > 0 && state == INITIAL && can_shoot:
if !FIREMODE:
can_shoot = false
clip -= 1
state = SHOOT;
var tween = create_tween()
tween.set_trans(Tween.TRANS_ELASTIC)
tween.set_ease(Tween.EASE_OUT)
tween.set_parallel(true)
tween.tween_property(MODEL, "position", Vector3(.0, MOMENTUM.x, MOMENTUM.y), RECOIL_COOLDOWN / 2)
var rand_rot_y = randi_range(-ANGULAR_MOMENTUM.y,ANGULAR_MOMENTUM.y)
var rand_rot_z = randi_range(-ANGULAR_MOMENTUM.z,ANGULAR_MOMENTUM.z)
tween.tween_property(MODEL, "rotation", Vector3(deg_to_rad(ANGULAR_MOMENTUM.x),deg_to_rad(rand_rot_y),deg_to_rad(rand_rot_z)),RECOIL_COOLDOWN /2)
tween.tween_callback(InitialPos).set_delay(SHOOTING_SPEED / 2)
return true
return false
func Release():
if !FIREMODE:
can_shoot = true
func Reload():
if(clip < MAX_CLIP && state == INITIAL):
state = RELOAD
return true
return false

122
scripts/player/Weapons.gd Normal file
View File

@@ -0,0 +1,122 @@
extends Node3D
const CONFIG_PATH = "user://weapons.scoom"
const REVOLVER = 0
const REST = 0
const BOB = 1
var state = 0
@onready var player_root = get_node("../../../../PlayerQ3") as CharacterBody3D
var weapons = []
var current_weapon = 0
var file_data = {
REVOLVER:
{
"HAND_POS": Vector3(0.4,-0.45,-1),
"HAND_ROT": Vector3(0,PI,0),
"MODEL": "Revolver",
"MAX_CLIP": 5,
"DAMAGE": 25,
"MOMENTUM": Vector2(0.3, -0.25),
"ANGULAR_MOMENTUM": Vector3(-60, 7, 10),
"RECOIL_COOLDOWN": 0.35,
"RPM": 120,
"DRAW_POS": Vector3(0,-0.5,-0.3),
"DRAW_ROT": Vector3(1.3, 0, 0)
}
}
var mouse_mov : Vector3
var sway_threshold = 5
var sway_lerp = 5
@export var sway_left : Vector3
@export var sway_right : Vector3
@export var sway_normal : Vector3
func _ready():
save_data(file_data)
load_data()
for i in range(0, file_data.size()):
var root = Weapon.new()
root.name = str(i)
var resource = "res://scenes/weapons/" + file_data[i].MODEL + ".tscn"
var weapon_model_resource = load(resource)
var weapon_model = weapon_model_resource.instantiate()
root.add_child(weapon_model)
root.position = file_data[i].HAND_POS
root.rotation = file_data[i].HAND_ROT
root.hide()
add_child(root)
root.MAX_CLIP = file_data[i].MAX_CLIP
root.DAMAGE = file_data[i].DAMAGE
root.MOMENTUM = file_data[i].MOMENTUM
root.ANGULAR_MOMENTUM = file_data[i].ANGULAR_MOMENTUM
root.RECOIL_COOLDOWN = file_data[i].RECOIL_COOLDOWN
root.RPM = file_data[i].RPM
root.MODEL = root.get_node(file_data[i].MODEL)
root.DRAW_POS = file_data[i].DRAW_POS
root.DRAW_ROT = file_data[i].DRAW_ROT
weapons.append(root)
weapons[current_weapon].init()
func _input(event):
if event is InputEventMouseMotion:
mouse_mov.y = clampf(-event.relative.x, -0.1, 0.1)
mouse_mov.x = clampf(event.relative.y, -0.1, 0.1)
func _unhandled_input(_event):
if weapons.size() > 1 && Input.is_action_just_released("wheel_up"):
weapons[current_weapon].hide()
current_weapon = (current_weapon + 1) % weapons.size()
weapons[current_weapon].init()
if weapons.size() > 1 && Input.is_action_just_released("wheel_down"):
weapons[current_weapon].hide()
current_weapon = (current_weapon - 1) % weapons.size()
weapons[current_weapon].init()
var time = 0
func _process(delta):
if Input.is_action_pressed("shoot"):
weapons[current_weapon].Shoot()
if Input.is_action_just_released("shoot"):
weapons[current_weapon].Release()
#SWAY
if mouse_mov != null && mouse_mov.length() > 0:
weapons[current_weapon].MODEL.rotation = weapons[current_weapon].MODEL.rotation.lerp(mouse_mov, sway_lerp * delta)
mouse_mov = Vector3.ZERO
else:
weapons[current_weapon].MODEL.rotation = weapons[current_weapon].MODEL.rotation.lerp(Vector3.ZERO, sway_lerp * delta)
#BOB
if player_root.velocity.length() > 0:
time += delta
var bobOscillate = sin(time * 4 * (2 * PI)) * 0.01
position.y = bobOscillate
bobOscillate = sin(time * 4 * (PI) + PI/4) * 0.015
position.x = bobOscillate
#else:
#position = lerp(position, Vector3.ZERO, )
func save_data(data):
var file = FileAccess.open(CONFIG_PATH, FileAccess.WRITE)
file.store_var(data)
func load_data():
var file = FileAccess.open(CONFIG_PATH, FileAccess.READ)
var data = file.get_var()
file_data = data