add: smooth move
This commit is contained in:
4
materials/level.tres
Normal file
4
materials/level.tres
Normal 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)
|
5
scenes/godot_plush_model.tscn
Normal file
5
scenes/godot_plush_model.tscn
Normal 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")]
|
@ -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")
|
||||||
|
44
scenes/level.tscn5923790033.tmp
Normal file
44
scenes/level.tscn5923790033.tmp
Normal 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")
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user