Procedural recoil

mail@pastecode.io avatar
unknown
plain_text
6 months ago
4.1 kB
2
Indexable
Never
var recoil_pos_curves: Array[Curve] = []
var recoil_rot_curves: Array[Curve] = []

var is_ads: bool = false

var recoil_duration := 0.8
var recoil_timer := 0.0
var is_recoiling := false
var recoil_min := -1
var recoil_max := 1

@export var use_recoil_pos_x := true
@export var use_recoil_pos_y := true
@export var use_recoil_pos_z := true

@export var use_recoil_rot_x := true
@export var use_recoil_rot_y := true
@export var use_recoil_rot_z := true

var last_recoil_dir := 1.0
var recoil_force_pos: Vector3 = Vector3.ZERO
var recoil_force_rot: Vector3 = Vector3.ZERO

func load_data():

	%SIK_L.target_node = %WeaponManager.current_weapon.get_node("IKTarget_L").get_path()
	%SIK_R.target_node = %WeaponManager.current_weapon.get_node("IKTarget_R").get_path()
	%SIK_L.start()
	%SIK_R.start()
	
	recoil_pos_curves = %WeaponManager.current_weapon.recoil_pos_curves
	recoil_rot_curves = %WeaponManager.current_weapon.recoil_rot_curves

func _process(_delta: float) -> void:

	if Input.is_action_just_pressed("ads"):
		is_ads = !is_ads

func trigger():
	#print("shoot")
	is_recoiling = true
	recoil_timer = 0.0
		
	last_recoil_dir = 1.0 if randf() < 0.5 else -1.0
	
	recoil_force_pos = Vector3(randf_range(1, 6), randf_range(1, 6), randf_range(3, 6))
	recoil_force_rot = Vector3(randf_range(10, 20), randf_range(5, 8), randf_range(1, 3))

func reset_pos_rot(delta: float) -> void:
	%WeaponManager.current_weapon.position = lerp(%WeaponManager.current_weapon.position, %WeaponManager.current_weapon.original_pos, delta * 15)
	%WeaponManager.current_weapon.rotation = lerp(%WeaponManager.current_weapon.rotation, Vector3.ZERO, delta * 15)
	%armature_test_arm.position = lerp(%armature_test_arm.position, Vector3(0.14, 0.0, 0.0), delta * 25)

func _physics_process(delta: float) -> void:
	if is_ads == false:
		reset_pos_rot(delta)
		
	elif is_ads == true:
                (ADS Code ...)

                # Apply the target rotation to the weapon using spherical linear interpolation (slerp)
		%WeaponManager.current_weapon.global_transform.basis = %WeaponManager.current_weapon.global_transform.basis.slerp(target_rot, delta * 15)

                (ADS Code ...)

		# Interpolate the weapon's position using linear interpolation (lerp)
		%WeaponManager.current_weapon.global_transform.origin = lerp(%WeaponManager.current_weapon.global_transform.origin, target_pos, delta * 15)

	recoil(delta)

func recoil(delta: float) -> void:
	if is_recoiling:
		recoil_timer += delta * 3

		var recoil_pos_offset = Vector3.ZERO
		if use_recoil_pos_x:
			recoil_pos_offset.x = recoil_pos_curves[0].sample(recoil_timer) * recoil_force_pos.x * last_recoil_dir
		if use_recoil_pos_y:
			recoil_pos_offset.y = recoil_pos_curves[1].sample(recoil_timer) * recoil_force_pos.y
		if use_recoil_pos_z:
			recoil_pos_offset.z = recoil_pos_curves[2].sample(recoil_timer) * recoil_force_pos.z

		recoil_pos_offset *= delta
		
		recoil_pos_offset = Vector3(
			clampf(recoil_pos_offset.x, recoil_min, recoil_max),
			clampf(recoil_pos_offset.y, recoil_min, recoil_max),
			clampf(recoil_pos_offset.z, recoil_min, recoil_max)
		)

		%WeaponManager.current_weapon.translate_object_local(recoil_pos_offset)
		
		var recoil_rot_offset = Vector3.ZERO
		if use_recoil_rot_x:
			recoil_rot_offset.x = recoil_rot_curves[0].sample(recoil_timer) * recoil_force_rot.x
		if use_recoil_rot_y:
			recoil_rot_offset.y = recoil_rot_curves[1].sample(recoil_timer) * recoil_force_rot.y * last_recoil_dir
		if use_recoil_rot_z:
			recoil_rot_offset.z = recoil_rot_curves[2].sample(recoil_timer) * recoil_force_rot.z * last_recoil_dir

		recoil_rot_offset *= delta

		%WeaponManager.current_weapon.rotate_object_local(Vector3(1, 0, 0), recoil_rot_offset.x)
		%WeaponManager.current_weapon.rotate_object_local(Vector3(0, 1, 0), recoil_rot_offset.y)
		%WeaponManager.current_weapon.rotate_object_local(Vector3(0, 0, 1), recoil_rot_offset.z)

		if recoil_timer >= 1.0:
			is_recoiling = false
			recoil_timer = 0.0

func change_weapon():
	load_data()
Leave a Comment