Files
demo-godot/palyer.gd

55 lines
2.4 KiB
GDScript3
Raw Normal View History

2026-01-04 19:35:08 +08:00
extends CharacterBody3D
2026-01-06 00:18:13 +08:00
## 角色的质量,单位 kg
2026-01-07 13:06:12 +08:00
const weight := 40.0
## 角色前进的动力,同样先简化处理,单位
const power := 1800.0
2026-01-06 00:18:13 +08:00
## 一个最简单的阻尼系数[br]
2026-01-07 13:06:12 +08:00
## 阻力计算公式 速度² × 阻尼系数 + 库仑阻尼系数[br]
## 假设最高速度是慢跑 10km/h , 2.77m/s那么阻力需要在这个速度下维持和动力平衡。也就是...84.3
const damping := 10.0
## 补充库仑阻尼系数[br]
## 我们不希望角色慢慢接近静止。所以还需要一个库仑阻尼提供某个速度下的快速停止效果
const coulomb_damping = 1.0
## TODO 目前并不能稳定收束到静止状态。阻尼仍然需要继续设计
## TODO 转向手感不好。但是如果操作时手动加一个目前移动方向的反向指令手感会好的多。
## 仔细想想也是,指令代表的是“希望的方向”,而不是“操作的方向”,所以这个反向力其实应该是程序手动加上的。现在还没有想好怎么调整这个转向手感。
## 顺便一体,角色的灵活程度很大程度上不取决于阻尼的设计,而是角色本身推重比。角色不够灵动需要调整推重比而不是阻尼
2026-01-04 19:35:08 +08:00
var fall_acceleration = 75
var target_velocity = Vector3.ZERO
2026-01-06 00:18:13 +08:00
func _physics_process(delta: float) -> void:
2026-01-07 13:06:12 +08:00
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())
2026-01-04 19:35:08 +08:00
if !is_on_floor():
target_velocity.y = target_velocity.y - ( fall_acceleration * delta )
velocity = target_velocity
move_and_slide()
2026-01-06 00:18:13 +08:00
## 获取当前指令的关联向量[br]
## 难道需要两层才生效?
2026-01-07 13:06:12 +08:00
func get_cmd_direction() -> Vector3:
2026-01-06 00:18:13 +08:00
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()