Подтягивание: центр капсулы ставим над уступом, убрана камера-сальто
- Подтягивание на уступы выше ~2 м не работало: цель ставила центр капсулы на уровень поверхности, тело оказывалось наполовину в уступе, и физика выталкивала назад. Теперь центр на полвысоты капсулы выше поверхности (проверено ботом: уступы 1,2–2,7 м, тонкие и сплошные, коробка и меш, ходьба и спринт — везде успешно; раньше от 2,0 м не работало) - Откачено сальто камеры при двойном прыжке (тошнит, не видно куда прыгать) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WxZo3ekR5m1af437Qzqwc1
This commit is contained in:
+4
-25
@@ -20,7 +20,6 @@ const SLIDE_JUMP_BOOST = 1.15 # Бонус скорости при прыжк
|
||||
# --- Двойной прыжок ---
|
||||
const AIR_JUMPS = 1 # Сколько прыжков в воздухе (0 — отключить)
|
||||
const AIR_JUMP_VELOCITY = 5.5
|
||||
const AIR_JUMP_FLIP_TIME = 0.6 # Сальто камеры при двойном прыжке, сек (как у анимации air_jump; 0 — отключить)
|
||||
|
||||
# --- Рывок (клавиша Q) ---
|
||||
const DASH_SPEED = 20.0 # Не больше MAX_SPEED
|
||||
@@ -160,8 +159,6 @@ var mantle_target: Vector3 = Vector3.ZERO
|
||||
var mantle_dir: Vector3 = Vector3.ZERO
|
||||
|
||||
# Камера
|
||||
var flip_pivot: Node3D = null # Ось на уровне глаз: ею крутим сальто, не мешая взгляду мышью
|
||||
var flip_timer: float = 0.0
|
||||
var head_base_pos: Vector3 = Vector3.ZERO
|
||||
var head_offset_y: float = 0.0
|
||||
var land_offset: float = 0.0
|
||||
@@ -196,12 +193,6 @@ var default_collision_y: float = 0.0
|
||||
func _ready() -> void:
|
||||
add_to_group("local_player")
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
flip_pivot = Node3D.new()
|
||||
flip_pivot.name = "CameraPivot"
|
||||
flip_pivot.position = head.position
|
||||
add_child(flip_pivot)
|
||||
head.reparent(flip_pivot, false)
|
||||
head.position = Vector3.ZERO
|
||||
head_base_pos = head.position
|
||||
base_fov = head.fov
|
||||
|
||||
@@ -493,7 +484,6 @@ func _air_jump(direction: Vector3) -> void:
|
||||
velocity.y = AIR_JUMP_VELOCITY
|
||||
air_jumps_left -= 1
|
||||
jump_buffer_timer = 0.0
|
||||
flip_timer = AIR_JUMP_FLIP_TIME
|
||||
# Можно сменить направление полёта прямо в прыжке
|
||||
if direction != Vector3.ZERO:
|
||||
var h_speed: float = maxf(Vector2(velocity.x, velocity.z).length(), WALK_SPEED)
|
||||
@@ -507,7 +497,7 @@ func _try_dash() -> void:
|
||||
if is_dashing or is_mantling or dashes_left <= 0 or dash_cooldown_timer > 0.0:
|
||||
return
|
||||
|
||||
var look := (global_transform.basis * Basis(Vector3.RIGHT, head.rotation.x)) * Vector3.FORWARD # без сальто камеры
|
||||
var look := -head.global_transform.basis.z
|
||||
var dir: Vector3
|
||||
if is_on_floor():
|
||||
# На земле рвёмся по направлению ввода, а без ввода — вперёд
|
||||
@@ -693,7 +683,8 @@ func _try_mantle() -> bool:
|
||||
is_mantling = true
|
||||
mantle_t = 0.0
|
||||
mantle_start = base
|
||||
mantle_target = ledge_pos + Vector3.UP * 0.05
|
||||
# Центр капсулы — на полвысоты над уступом: иначе тело наполовину в уступе и физика выталкивает назад
|
||||
mantle_target = ledge_pos + Vector3.UP * (default_capsule_height * 0.5 + 0.05)
|
||||
mantle_dir = fwd
|
||||
velocity = Vector3.ZERO
|
||||
shake_strength = maxf(shake_strength, 0.03)
|
||||
@@ -804,17 +795,7 @@ func _can_stand() -> bool:
|
||||
|
||||
# --- КАМЕРА И ЭФФЕКТЫ ---
|
||||
|
||||
# Сальто вперёд: ось камеры делает полный оборот за AIR_JUMP_FLIP_TIME (плавно, с разгоном и торможением)
|
||||
func _update_flip(delta: float) -> void:
|
||||
flip_timer = maxf(flip_timer - delta, 0.0)
|
||||
if flip_timer <= 0.0:
|
||||
flip_pivot.rotation.x = 0.0
|
||||
return
|
||||
var u := 1.0 - flip_timer / AIR_JUMP_FLIP_TIME
|
||||
flip_pivot.rotation.x = -TAU * u * u * (3.0 - 2.0 * u)
|
||||
|
||||
func _update_camera(delta: float, input_dir: Vector2) -> void:
|
||||
_update_flip(delta)
|
||||
var h_speed := Vector2(velocity.x, velocity.z).length()
|
||||
var sprint_factor: float = clamp((h_speed - WALK_SPEED) / (SPRINT_SPEED - WALK_SPEED), 0.0, 1.0)
|
||||
|
||||
@@ -925,8 +906,6 @@ func die() -> void:
|
||||
return
|
||||
is_dead = true
|
||||
death_timer = DEATH_TIME
|
||||
flip_timer = 0.0
|
||||
flip_pivot.rotation.x = 0.0
|
||||
if is_sliding:
|
||||
_end_slide()
|
||||
if is_crouching:
|
||||
@@ -945,7 +924,7 @@ func _process_death(delta: float) -> void:
|
||||
|
||||
# Камера падает и заваливается набок, экран краснеет
|
||||
var k := 1.0 - exp(-6.0 * delta)
|
||||
head.position = head.position.lerp(Vector3(head_base_pos.x, DEATH_CAMERA_HEIGHT - flip_pivot.position.y, head_base_pos.z), k)
|
||||
head.position = head.position.lerp(Vector3(head_base_pos.x, DEATH_CAMERA_HEIGHT, head_base_pos.z), k)
|
||||
head.rotation.z = lerpf(head.rotation.z, deg_to_rad(DEATH_ROLL), k)
|
||||
head.fov = lerpf(head.fov, base_fov, k)
|
||||
shake_strength = lerpf(shake_strength, 0.0, 10.0 * delta)
|
||||
|
||||
Reference in New Issue
Block a user