diff --git a/.gitignore b/.gitignore index 970d9f0..b45eb22 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .godot/ .import/ +*.code-workspace \ No newline at end of file diff --git a/palyer.gd b/palyer.gd index 1c500fc..52c5fb0 100644 --- a/palyer.gd +++ b/palyer.gd @@ -1,39 +1,37 @@ extends CharacterBody3D ## 角色的质量,单位 kg -const weight := 60 -## 角色前进的动力,同样先简化处理,单位 N -const power := 800 +const weight := 40.0 +## 角色前进的动力,同样先简化处理,单位 +const power := 1800.0 ## 一个最简单的阻尼系数[br] -## 阻力计算公式 速度² × 阻尼系数[br] -## 假设最高速度是慢跑 10km/h , 2.77m/s,那么阻力需要在这个速度下维持和动力平衡。也就是...104.3 -const damping := 104.3 -## 最后一次计算之后的,当前运动状态的向量 -var last_vector = Vector3.ZERO +## 阻力计算公式 速度² × 阻尼系数 + 库仑阻尼系数[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 cmd_vector_direction := get_cmd_vector() - # 运动方向 - var pre_vector_direction = last_vector.normalized() - # 计算当前运动状态,方向在上一步已经更新过了。剩下的是模量问题。 - # 指令力 - var cmd_vector_power = cmd_vector_direction * power - # 阻力 - var damping_vector = -pre_vector.normalized() * last_vector.length_squared() * damping - - # 若指令方向和运动方向不同,则必然会产生 - if cmd_vector_direction != pre_vector_direction: - pre_vector_direction = (pre_vector_direction + cmd_vector_direction).normalized() - $pivot.basis = Basis.looking_at(pre_vector_direction) - # 速度计算部分 - #target_velocity.x = direction.x * now_speed - #target_velocity.z = direction.z * now_speed - + 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 ) @@ -42,7 +40,7 @@ func _physics_process(delta: float) -> void: ## 获取当前指令的关联向量[br] ## 难道需要两层才生效? -func get_cmd_vector() -> Vector3: +func get_cmd_direction() -> Vector3: var vector := Vector3.ZERO if Input.is_action_pressed("move_forward"): vector.z -= 1