Files
demo-godot/palyer.gd
2026-01-07 13:06:12 +08:00

55 lines
2.4 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends CharacterBody3D
## 角色的质量,单位 kg
const weight := 40.0
## 角色前进的动力,同样先简化处理,单位
const power := 1800.0
## 一个最简单的阻尼系数[br]
## 阻力计算公式 速度² × 阻尼系数 + 库仑阻尼系数[br]
## 假设最高速度是慢跑 10km/h , 2.77m/s那么阻力需要在这个速度下维持和动力平衡。也就是...84.3
const damping := 10.0
## 补充库仑阻尼系数[br]
## 我们不希望角色慢慢接近静止。所以还需要一个库仑阻尼提供某个速度下的快速停止效果
const coulomb_damping = 1.0
## TODO 目前并不能稳定收束到静止状态。阻尼仍然需要继续设计
## TODO 转向手感不好。但是如果操作时手动加一个目前移动方向的反向指令手感会好的多。
## 仔细想想也是,指令代表的是“希望的方向”,而不是“操作的方向”,所以这个反向力其实应该是程序手动加上的。现在还没有想好怎么调整这个转向手感。
## 顺便一体,角色的灵活程度很大程度上不取决于阻尼的设计,而是角色本身推重比。角色不够灵动需要调整推重比而不是阻尼
var fall_acceleration = 75
var target_velocity = Vector3.ZERO
func _physics_process(delta: float) -> void:
var velocity_direction: Vector3 = velocity.normalized()
var cmd_direction: Vector3 = get_cmd_direction()
# 当前阻力
var damping_vector: Vector3 = -velocity_direction * ( velocity.length_squared() * damping + coulomb_damping )
# 阻力 + 指令力合力
var result_vector: Vector3 = cmd_direction * power + damping_vector
# 合力下发生的速度变化
var acceleration = result_vector.normalized() * result_vector.length() / weight * delta
target_velocity = velocity + acceleration
if target_velocity != Vector3.ZERO:
$pivot.basis = Basis.looking_at(target_velocity.normalized())
if !is_on_floor():
target_velocity.y = target_velocity.y - ( fall_acceleration * delta )
velocity = target_velocity
move_and_slide()
## 获取当前指令的关联向量[br]
## 难道需要两层才生效?
func get_cmd_direction() -> Vector3:
var vector := Vector3.ZERO
if Input.is_action_pressed("move_forward"):
vector.z -= 1
if Input.is_action_pressed("move_back"):
vector.z += 1
if Input.is_action_pressed("move_left"):
vector.x -= 1
if Input.is_action_pressed("move_right"):
vector.x += 1
return vector.normalized()