add: smooth move

This commit is contained in:
aurinex
2025-08-08 16:36:54 +05:00
parent b7ccc4e3d3
commit 5145bdfa9e
6 changed files with 137 additions and 47 deletions

4
materials/level.tres Normal file
View File

@ -0,0 +1,4 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://dv185w3f5gjp4"]
[resource]
albedo_color = Color(0.230315, 0.230315, 0.230315, 1)

View File

@ -0,0 +1,5 @@
[gd_scene load_steps=2 format=3 uid="uid://b4ixstqw06c4y"]
[ext_resource type="PackedScene" uid="uid://cg7of11dls47q" path="res://scenes/godot_plush_model.glb" id="1_fn30i"]
[node name="godot_plush_model" instance=ExtResource("1_fn30i")]

View File

@ -1,29 +1,45 @@
[gd_scene load_steps=5 format=3 uid="uid://8ywbh7j4mmai"] [gd_scene load_steps=6 format=3 uid="uid://8ywbh7j4mmai"]
[ext_resource type="PackedScene" uid="uid://dsrbro31ggv7u" path="res://scenes/player.tscn" id="1_2q6dc"] [ext_resource type="PackedScene" uid="uid://dsrbro31ggv7u" path="res://scenes/player.tscn" id="1_2q6dc"]
[ext_resource type="Material" uid="uid://dv185w3f5gjp4" path="res://materials/level.tres" id="2_w7c3h"]
[sub_resource type="PlaneMesh" id="PlaneMesh_rd3vj"] [sub_resource type="Environment" id="Environment_2q6dc"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_w7c3h"] [sub_resource type="BoxMesh" id="BoxMesh_2q6dc"]
albedo_color = Color(5.41471e-08, 0.281997, 1.44392e-07, 1)
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_2q6dc"] [sub_resource type="BoxMesh" id="BoxMesh_w7c3h"]
[node name="level" type="Node3D"] [node name="level" type="Node3D"]
[node name="StaticBody3D" type="StaticBody3D" parent="."]
[node name="MeshInstance3D" type="MeshInstance3D" parent="StaticBody3D"]
transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0)
mesh = SubResource("PlaneMesh_rd3vj")
skeleton = NodePath("../..")
surface_material_override/0 = SubResource("StandardMaterial3D_w7c3h")
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D"]
shape = SubResource("WorldBoundaryShape3D_2q6dc")
[node name="Player" parent="." instance=ExtResource("1_2q6dc")] [node name="Player" parent="." instance=ExtResource("1_2q6dc")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0640043, 0.486621, -0.407444) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0640043, 0.486621, -0.407444)
jump_velocity = 7.0
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 4, -1) transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 4, -1)
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_2q6dc")
[node name="CSGMesh3D" type="CSGMesh3D" parent="."]
transform = Transform3D(38.6121, 0, 0, 0, 0.894564, 0, 0, 0, 34.4712, 0, 0, 0)
use_collision = true
mesh = SubResource("BoxMesh_2q6dc")
[node name="CSGMesh3D2" type="CSGMesh3D" parent="."]
transform = Transform3D(1.00624, 0, 0, 0, 1.00624, 0, 0, 0, 1.00624, -0.146904, 1.43323, 3.63201)
use_collision = true
mesh = SubResource("BoxMesh_w7c3h")
material = ExtResource("2_w7c3h")
[node name="CSGMesh3D3" type="CSGMesh3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.293807, 2.86646, 6.43488)
use_collision = true
mesh = SubResource("BoxMesh_w7c3h")
material = ExtResource("2_w7c3h")
[node name="CSGMesh3D4" type="CSGMesh3D" parent="."]
transform = Transform3D(13.2076, 0, 0, 0, 1, 0, 0, 0, 1, -0.587614, 4.46185, 8.71996)
use_collision = true
mesh = SubResource("BoxMesh_w7c3h")
material = ExtResource("2_w7c3h")

View File

@ -0,0 +1,44 @@
[gd_scene load_steps=6 format=3 uid="uid://8ywbh7j4mmai"]
[ext_resource type="PackedScene" uid="uid://dsrbro31ggv7u" path="res://scenes/player.tscn" id="1_2q6dc"]
[ext_resource type="Material" uid="uid://dv185w3f5gjp4" path="res://materials/level.tres" id="2_w7c3h"]
[sub_resource type="Environment" id="Environment_2q6dc"]
[sub_resource type="BoxMesh" id="BoxMesh_2q6dc"]
[sub_resource type="BoxMesh" id="BoxMesh_w7c3h"]
[node name="level" type="Node3D"]
[node name="Player" parent="." instance=ExtResource("1_2q6dc")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0640043, 0.486621, -0.407444)
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 4, -1)
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_2q6dc")
[node name="CSGMesh3D" type="CSGMesh3D" parent="."]
transform = Transform3D(38.6121, 0, 0, 0, 0.894564, 0, 0, 0, 34.4712, 0, 0, 0)
use_collision = true
mesh = SubResource("BoxMesh_2q6dc")
[node name="CSGMesh3D2" type="CSGMesh3D" parent="."]
transform = Transform3D(1.00624, 0, 0, 0, 1.00624, 0, 0, 0, 1.00624, -0.146904, 1.43323, 3.63201)
use_collision = true
mesh = SubResource("BoxMesh_w7c3h")
material = ExtResource("2_w7c3h")
[node name="CSGMesh3D3" type="CSGMesh3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.293807, 2.86646, 6.43488)
use_collision = true
mesh = SubResource("BoxMesh_w7c3h")
material = ExtResource("2_w7c3h")
[node name="CSGMesh3D4" type="CSGMesh3D" parent="."]
transform = Transform3D(13.2076, 0, 0, 0, 1, 0, 0, 0, 1, -0.587614, 4.46185, 8.71996)
use_collision = true
mesh = SubResource("BoxMesh_w7c3h")
material = ExtResource("2_w7c3h")

View File

@ -7,22 +7,29 @@ const LERP_VELOCITY: float = 0.15
@export var _character: CharacterBody3D = null @export var _character: CharacterBody3D = null
@export var animation_player: AnimationPlayer = null @export var animation_player: AnimationPlayer = null
func animate(_velocity: Vector3) -> void: func animate(velocity: Vector3) -> void:
if not _character.is_on_floor(): if not _character.is_on_floor():
if _velocity.y < 0: if velocity.y < 0:
animation_player.play("fall") animation_player.play("fall")
else: else:
animation_player.play("up") animation_player.play("up")
return return
if _velocity.length() > 0.1: # Если есть движение # Используем _has_input вместо проверки длины скорости
if _character._has_input:
if _character.is_running(): if _character.is_running():
animation_player.play("run") # Спринт animation_player.play("run")
else: else:
animation_player.play("walk") # Обычная ходьба animation_player.play("walk")
return return
animation_player.play("idle") # Бездействие # Плавное переключение на idle при инерции
if velocity.length() > 0.5: # Небольшой порог для плавного перехода
var current_anim = animation_player.current_animation
if current_anim != "walk" and current_anim != "run":
animation_player.play("walk", 0.1) # Плавный переход с blend_time 0.1 сек
else:
animation_player.play("idle", 0.2) # Плавный переход на idle
@rpc("any_peer", "reliable") @rpc("any_peer", "reliable")
func sync_player_rotation(rotation_y: float) -> void: func sync_player_rotation(rotation_y: float) -> void:

View File

@ -5,8 +5,10 @@ class_name Character
@export var normal_speed: float = 6.0 @export var normal_speed: float = 6.0
@export var sprint_speed: float = 10.0 @export var sprint_speed: float = 10.0
@export var jump_velocity: float = 10.0 @export var jump_velocity: float = 10.0
@export var gravity_scale: float = 1.0 # Позволяет регулировать гравитацию @export var gravity_scale: float = 1.0
@export var rotation_speed: float = 10.0 @export var rotation_speed: float = 10.0
@export var acceleration: float = 10.0 # Сила ускорения
@export var deceleration: float = 8.0 # Сила замедления
@export_group("References") @export_group("References")
@export var body: Node3D = null @export var body: Node3D = null
@ -14,24 +16,28 @@ class_name Character
@export var respawn_point: Vector3 = Vector3(0, 5, 0) @export var respawn_point: Vector3 = Vector3(0, 5, 0)
var _current_speed: float var _current_speed: float
var _target_velocity: Vector3 = Vector3.ZERO # Целевая скорость
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var _has_input: bool = false
var _can_sprint: bool = true
func _ready(): func _ready():
$SpringArmOffset/SpringArm3D/Camera3D.current = false $SpringArmOffset/SpringArm3D/Camera3D.current = false
func _physics_process(delta): func _physics_process(delta):
var current_scene = get_tree().get_current_scene() # Обработка гравитации
if not is_on_floor(): if not is_on_floor():
velocity.y -= gravity * delta velocity.y -= gravity * delta
_can_sprint = false # В воздухе нельзя ускоряться
if is_on_floor():
if Input.is_action_just_pressed("jump"):
velocity.y = jump_velocity
else: else:
velocity.y -= gravity * delta _can_sprint = true # На земле можно ускоряться
_move() # Обработка прыжка
if is_on_floor() and Input.is_action_just_pressed("jump"):
velocity.y = jump_velocity
_can_sprint = false # При прыжке сразу отключаем спринт
_move(delta)
move_and_slide() move_and_slide()
if body and body.has_method("animate"): if body and body.has_method("animate"):
@ -40,13 +46,9 @@ func _physics_process(delta):
func _process(_delta): func _process(_delta):
_check_fall_and_respawn() _check_fall_and_respawn()
func freeze(): func _move(delta: float) -> void:
velocity.x = 0
velocity.z = 0
_current_speed = 0
func _move() -> void:
var input_direction = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") var input_direction = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
_has_input = input_direction.length() > 0.1
# Получаем направление движения относительно камеры # Получаем направление движения относительно камеры
var camera_basis = $SpringArmOffset/SpringArm3D/Camera3D.global_transform.basis var camera_basis = $SpringArmOffset/SpringArm3D/Camera3D.global_transform.basis
@ -55,23 +57,33 @@ func _move() -> void:
_update_speed() _update_speed()
if direction: if direction:
velocity.x = direction.x * _current_speed # Устанавливаем целевую скорость с учетом направления
velocity.z = direction.z * _current_speed _target_velocity.x = direction.x * _current_speed
_target_velocity.z = direction.z * _current_speed
# Плавно изменяем скорость в сторону целевой
velocity.x = lerp(velocity.x, _target_velocity.x, acceleration * delta)
velocity.z = lerp(velocity.z, _target_velocity.z, acceleration * delta)
# Поворачиваем тело персонажа в направлении движения # Поворачиваем тело персонажа в направлении движения
if velocity.length() > 0.1: # Только если есть значительное движение if velocity.length() > 0.1:
var target_rotation = atan2(velocity.x, velocity.z) var target_rotation = atan2(_target_velocity.x, _target_velocity.z)
body.rotation.y = lerp_angle(body.rotation.y, target_rotation, rotation_speed * get_process_delta_time()) body.rotation.y = lerp_angle(body.rotation.y, target_rotation, rotation_speed * delta)
else: else:
velocity.x = move_toward(velocity.x, 0, _current_speed) # Если нет ввода, плавно уменьшаем скорость
velocity.z = move_toward(velocity.z, 0, _current_speed) _target_velocity = Vector3.ZERO
velocity.x = lerp(velocity.x, 0.0, deceleration * delta)
velocity.z = lerp(velocity.z, 0.0, deceleration * delta)
func is_running() -> bool: func is_running() -> bool:
return Input.is_action_pressed("shift") and _current_speed == sprint_speed return Input.is_action_pressed("shift") and _current_speed == sprint_speed
func _update_speed() -> void: func _update_speed() -> void:
_current_speed = sprint_speed if Input.is_action_pressed("shift") else normal_speed # Ускорение работает только когда персонаж на земле
if _can_sprint and Input.is_action_pressed("shift"):
_current_speed = sprint_speed
else:
_current_speed = normal_speed
func _check_fall_and_respawn(): func _check_fall_and_respawn():
if global_transform.origin.y < -15.0: if global_transform.origin.y < -15.0:
@ -80,3 +92,5 @@ func _check_fall_and_respawn():
func _respawn(): func _respawn():
global_transform.origin = respawn_point global_transform.origin = respawn_point
velocity = Vector3.ZERO velocity = Vector3.ZERO
_target_velocity = Vector3.ZERO
_can_sprint = true