Added strafe banking & fall kick camera effects

This commit is contained in:
Rob Kelly 2025-09-29 16:21:21 -06:00
parent a775865ed9
commit b0c6bc7530
9 changed files with 123 additions and 3 deletions

View File

@ -0,0 +1,60 @@
extends Node3D
## Give the camera a little kick when the player falls, proportional to landing velocity
@export var enabled := true
@export var character: CharacterBody3D
## Minimum landing speed before kick is applied, in m/s
@export var min_landing_speed := 4.0
## How far the camera gets pitched on kick in degrees per m/s of landing velocity
@export var angle_curve: Curve
## How far down the camera gets kicked in meters per m/s of landing velocity
@export var offset_curve: Curve
## How long the rebound takes in seconds per m/s of landing velocity
@export var rebound_time_curve: Curve
var _last_speed := 0.0
var _in_air := false
var _tween: Tween
func _get_tween() -> Tween:
if _tween and _tween.is_valid():
_tween.kill()
_tween = create_tween()
return _tween
func do_kick(landing_speed: float) -> void:
print_debug("Landing speed: ", landing_speed)
if landing_speed < min_landing_speed:
return
# Initial kick
rotation.x = -deg_to_rad(angle_curve.sample(landing_speed))
position.y = -offset_curve.sample(landing_speed)
# Rebound
var rebound_time := rebound_time_curve.sample(landing_speed)
var tween := _get_tween()
tween.set_parallel(true)
tween.tween_property(self, "rotation:x", 0, rebound_time).set_trans(Tween.TRANS_CIRC).set_ease(
Tween.EASE_OUT
)
tween.tween_property(self, "position:y", 0, rebound_time).set_trans(Tween.TRANS_CIRC).set_ease(
Tween.EASE_OUT
)
func _process(_delta: float) -> void:
if character.is_on_floor():
if _in_air:
# First frame after land
do_kick(absf(_last_speed))
_in_air = false
else:
_in_air = true
_last_speed = character.velocity.y

View File

@ -0,0 +1 @@
uid://bndyjh51gkqeo

View File

@ -0,0 +1,26 @@
extends Node3D
## Bank the camera to the sides when the player strafes, and pitch up and down with forward motion
const ACCELERATION := 16.0
@export var enabled := true
@export var character: CharacterBody3D
## Camera pitch effect in degrees per m/s of forward movement
@export var pitch_curve: Curve
## Camera roll effect in degrees per m/s of side movement
@export var roll_curve: Curve
func _process(delta: float) -> void:
var weight := 1.0 - exp(-ACCELERATION * delta)
var forward_dot := character.velocity.dot(global_transform.basis.z)
var target_x := deg_to_rad(pitch_curve.sample(forward_dot))
rotation.x = lerp_angle(rotation.x, target_x, weight)
var right_dot := character.velocity.dot(global_transform.basis.x)
var target_z := deg_to_rad(roll_curve.sample(right_dot))
rotation.z = lerp_angle(rotation.z, target_z, weight)

View File

@ -0,0 +1 @@
uid://buq2c8inefgdl

View File

@ -1,10 +1,11 @@
[gd_scene load_steps=17 format=3 uid="uid://dtbulshrxetes"]
[gd_scene load_steps=22 format=3 uid="uid://dtbulshrxetes"]
[ext_resource type="Script" uid="uid://bihaf1xlwpkdo" path="res://src/player/player.gd" id="1_5f2sf"]
[ext_resource type="Script" uid="uid://f3kssctvn2bo" path="res://src/player/camera/camera_controller.gd" id="1_mf2ua"]
[ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_rxibo"]
[ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_mf2ua"]
[ext_resource type="Script" uid="uid://buq2c8inefgdl" path="res://src/player/camera/strafe_bank_effect.gd" id="3_x42xx"]
[ext_resource type="Script" uid="uid://bndyjh51gkqeo" path="res://src/player/camera/fall_kick_effect.gd" id="4_8ydov"]
[ext_resource type="Script" uid="uid://032jyhgkb2rv" path="res://src/player/camera/mouselook_controller.gd" id="4_244u8"]
[ext_resource type="Script" uid="uid://c0nxcunx0fo4r" path="res://src/player/movement_controller.gd" id="6_jiejy"]
[ext_resource type="Script" uid="uid://d11erhxna68vd" path="res://src/player/player_input_controller.gd" id="7_o822w"]
@ -15,6 +16,29 @@
[sub_resource type="CapsuleMesh" id="CapsuleMesh_4anbu"]
[sub_resource type="Curve" id="Curve_x42xx"]
_limits = [-1.0, 1.0, -7.0, 7.0]
_data = [Vector2(-7, -1), 0.0, 0.0, 0, 0, Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(7, 1), 0.0, 0.0, 0, 0]
point_count = 3
[sub_resource type="Curve" id="Curve_l271a"]
_limits = [-2.5, 2.5, -7.0, 7.0]
_data = [Vector2(-7, 2.5), 0.0, 0.0, 0, 0, Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(7, -2.5), 0.0, 0.0, 0, 0]
point_count = 3
[sub_resource type="Curve" id="Curve_8ydov"]
_limits = [0.0, 4.0, 0.0, 10.0]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(10, 4), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="Curve" id="Curve_cwolq"]
_limits = [0.0, 0.05, 0.0, 10.0]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(10, 0.05), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="Curve" id="Curve_ylhto"]
_limits = [0.0, 0.6, 0.0, 10.0]
_data = [Vector2(0, 0.1), 0.0, 0.0, 0, 0, Vector2(10, 0.6), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="Resource" id="Resource_244u8"]
script = ExtResource("2_mf2ua")
@ -55,15 +79,23 @@ yaw_root = NodePath("../..")
script = ExtResource("3_x42xx")
character = NodePath("../../..")
pitch_curve = SubResource("Curve_x42xx")
roll_curve = SubResource("Curve_l271a")
[node name="PhantomCamera3D" type="Node3D" parent="CameraOffset/CameraController/StrafeBankEffect"]
[node name="FallKickEffect" type="Node3D" parent="CameraOffset/CameraController/StrafeBankEffect" node_paths=PackedStringArray("character")]
script = ExtResource("4_8ydov")
character = NodePath("../../../..")
angle_curve = SubResource("Curve_8ydov")
offset_curve = SubResource("Curve_cwolq")
rebound_time_curve = SubResource("Curve_ylhto")
[node name="PhantomCamera3D" type="Node3D" parent="CameraOffset/CameraController/StrafeBankEffect/FallKickEffect"]
script = ExtResource("1_rxibo")
priority = 1
tween_resource = SubResource("Resource_244u8")
noise_emitter_layer = 1
metadata/_custom_type_script = "uid://csjccrhj5wnx7"
[node name="MeshInstance3D" type="MeshInstance3D" parent="CameraOffset/CameraController/StrafeBankEffect/PhantomCamera3D"]
[node name="MeshInstance3D" type="MeshInstance3D" parent="CameraOffset/CameraController/StrafeBankEffect/FallKickEffect/PhantomCamera3D"]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, -0.45)
gi_mode = 0
mesh = SubResource("CapsuleMesh_o822w")