Aligned foot rotation to ground normal
This commit is contained in:
parent
f7209d2164
commit
1e5ab718bf
@ -140,6 +140,7 @@ scale_max = 1.1
|
|||||||
tilt = 0.15
|
tilt = 0.15
|
||||||
|
|
||||||
[node name="Enemies" type="Node3D" parent="World"]
|
[node name="Enemies" type="Node3D" parent="World"]
|
||||||
|
visible = false
|
||||||
script = ExtResource("15_25nmg")
|
script = ExtResource("15_25nmg")
|
||||||
scene = ExtResource("15_hgl78")
|
scene = ExtResource("15_hgl78")
|
||||||
noise = SubResource("FastNoiseLite_yp2fx")
|
noise = SubResource("FastNoiseLite_yp2fx")
|
||||||
|
@ -90,6 +90,7 @@ bone_idx = 12
|
|||||||
|
|
||||||
[node name="Weapon" type="BoneAttachment3D" parent="Model/Female/Armature/GeneralSkeleton" index="6"]
|
[node name="Weapon" type="BoneAttachment3D" parent="Model/Female/Armature/GeneralSkeleton" index="6"]
|
||||||
transform = Transform3D(0, -1, 0, 0, 0, -1, 1, 0, 0, -0.609469, 1.26691, -0.0234125)
|
transform = Transform3D(0, -1, 0, 0, 0, -1, 1, 0, 0, -0.609469, 1.26691, -0.0234125)
|
||||||
|
visible = false
|
||||||
bone_name = "RightMiddleProximal"
|
bone_name = "RightMiddleProximal"
|
||||||
bone_idx = 44
|
bone_idx = 44
|
||||||
|
|
||||||
@ -124,6 +125,7 @@ libraries = {
|
|||||||
skeleton = NodePath("../Model/Female/Armature/GeneralSkeleton")
|
skeleton = NodePath("../Model/Female/Armature/GeneralSkeleton")
|
||||||
movement = NodePath("../Movement")
|
movement = NodePath("../Movement")
|
||||||
footsteps = SubResource("AudioStreamRandomizer_4yj1k")
|
footsteps = SubResource("AudioStreamRandomizer_4yj1k")
|
||||||
|
step_threshold = 0.1
|
||||||
|
|
||||||
[node name="Health" parent="." instance=ExtResource("2_np5ag")]
|
[node name="Health" parent="." instance=ExtResource("2_np5ag")]
|
||||||
max_value = 100.0
|
max_value = 100.0
|
||||||
|
@ -6,3 +6,5 @@ var audio: AudioStreamPlayer3D
|
|||||||
var position: Vector3
|
var position: Vector3
|
||||||
var velocity: Vector3
|
var velocity: Vector3
|
||||||
var attachment: BoneAttachment3D
|
var attachment: BoneAttachment3D
|
||||||
|
var floor_distance: float
|
||||||
|
var normal: Vector3
|
@ -1,14 +1,17 @@
|
|||||||
class_name FootstepsComponent
|
class_name FootstepsComponent
|
||||||
extends Node
|
extends Node3D
|
||||||
|
|
||||||
@export var skeleton: Skeleton3D
|
@export var skeleton: Skeleton3D
|
||||||
@export var movement: MovementComponent
|
@export var movement: MovementComponent
|
||||||
@export var footsteps: AudioStreamRandomizer
|
@export var footsteps: AudioStreamRandomizer
|
||||||
@export var step_threshold := 0.1
|
@export var step_threshold := 0.1
|
||||||
|
@export var ik_step_threshold := 0.2
|
||||||
|
@export var ik_speed := 5.0
|
||||||
|
|
||||||
const feet_names := ["LeftFoot", "RightFoot"]
|
const feet_names := ["LeftFoot", "RightFoot"]
|
||||||
|
|
||||||
var feet: Array[Foot] = []
|
var feet: Array[Foot] = []
|
||||||
|
var ik_time: float
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
for foot_name in feet_names:
|
for foot_name in feet_names:
|
||||||
@ -17,6 +20,8 @@ func _ready():
|
|||||||
foot.bone_id = skeleton.find_bone(foot_name)
|
foot.bone_id = skeleton.find_bone(foot_name)
|
||||||
foot.audio = get_node(foot_name)
|
foot.audio = get_node(foot_name)
|
||||||
foot.position = skeleton.to_global(skeleton.get_bone_global_pose(foot.bone_id).origin)
|
foot.position = skeleton.to_global(skeleton.get_bone_global_pose(foot.bone_id).origin)
|
||||||
|
foot.floor_distance = INF
|
||||||
|
foot.normal = Vector3.UP
|
||||||
foot.attachment = BoneAttachment3D.new()
|
foot.attachment = BoneAttachment3D.new()
|
||||||
foot.attachment.bone_name = foot_name
|
foot.attachment.bone_name = foot_name
|
||||||
foot.attachment.bone_idx = foot.bone_id
|
foot.attachment.bone_idx = foot.bone_id
|
||||||
@ -26,13 +31,25 @@ func _ready():
|
|||||||
|
|
||||||
func _process(delta: float):
|
func _process(delta: float):
|
||||||
for foot in feet:
|
for foot in feet:
|
||||||
|
var global_pose := skeleton.get_bone_global_pose(foot.bone_id)
|
||||||
var old_position := foot.position
|
var old_position := foot.position
|
||||||
foot.position = skeleton.to_global(skeleton.get_bone_global_pose(foot.bone_id).origin)
|
foot.position = skeleton.to_global(global_pose.origin)
|
||||||
foot.velocity = (foot.position - old_position) / delta
|
|
||||||
|
|
||||||
if foot.position.y > step_threshold:
|
if foot.floor_distance < ik_step_threshold:
|
||||||
|
var bone_to_global := skeleton.global_transform * global_pose
|
||||||
|
var normal_local := bone_to_global.basis.transposed() * foot.normal
|
||||||
|
var pose := skeleton.get_bone_pose(foot.bone_id)
|
||||||
|
var rot := get_foot_rotation(pose.basis, normal_local)
|
||||||
|
ik_time = minf(ik_time + ik_speed * delta, 1.0)
|
||||||
|
skeleton.set_bone_pose_rotation(foot.bone_id, pose.basis.slerp(rot, ik_time))
|
||||||
|
else:
|
||||||
|
ik_time = 0
|
||||||
|
|
||||||
|
if foot.floor_distance > step_threshold:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
foot.velocity = (foot.position - old_position) / delta
|
||||||
|
|
||||||
if foot.velocity.y > 0:
|
if foot.velocity.y > 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -44,6 +61,51 @@ func _process(delta: float):
|
|||||||
|
|
||||||
play(foot.audio)
|
play(foot.audio)
|
||||||
|
|
||||||
|
func _physics_process(_delta):
|
||||||
|
var space_state = get_world_3d().direct_space_state
|
||||||
|
|
||||||
|
for foot in feet:
|
||||||
|
var from := foot.position
|
||||||
|
var to := foot.position + Vector3(0, -10, 0)
|
||||||
|
var query = PhysicsRayQueryParameters3D.create(from, to, 1)
|
||||||
|
var result = space_state.intersect_ray(query)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
foot.floor_distance = (foot.position - result.position).length()
|
||||||
|
foot.normal = result.normal
|
||||||
|
else:
|
||||||
|
foot.floor_distance = INF
|
||||||
|
foot.normal = Vector3.UP
|
||||||
|
|
||||||
func play(audio_player: AudioStreamPlayer3D):
|
func play(audio_player: AudioStreamPlayer3D):
|
||||||
audio_player.stream = footsteps
|
audio_player.stream = footsteps
|
||||||
audio_player.play()
|
audio_player.play()
|
||||||
|
|
||||||
|
func get_foot_rotation(base: Basis, normal: Vector3) -> Basis:
|
||||||
|
var rot := align_with_y(base, normal)
|
||||||
|
return rot.rotated(Vector3.UP, PI)
|
||||||
|
|
||||||
|
func align_with_y(base: Basis, normal: Vector3) -> Basis:
|
||||||
|
base.x = -base.z.cross(normal)
|
||||||
|
base.y = normal
|
||||||
|
return base.orthonormalized()
|
||||||
|
|
||||||
|
# func get_foot_rotation2(base: Basis, normal: Vector3) -> Basis:
|
||||||
|
# normal.x = -normal.x
|
||||||
|
# normal.z = -normal.z
|
||||||
|
# return align_up(base, normal)
|
||||||
|
|
||||||
|
# func align_up(base: Basis, normal: Vector3) -> Basis:
|
||||||
|
# var result = Basis()
|
||||||
|
# var node_scale = base.get_scale().abs()
|
||||||
|
|
||||||
|
# result.x = normal.cross(base.z)
|
||||||
|
# result.y = normal
|
||||||
|
# result.z = base.x.cross(normal)
|
||||||
|
|
||||||
|
# result = result.orthonormalized()
|
||||||
|
# result.x *= node_scale.x
|
||||||
|
# result.y *= node_scale.y
|
||||||
|
# result.z *= node_scale.z
|
||||||
|
|
||||||
|
# return result
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[ext_resource type="Script" path="res://player/footsteps/FootstepsComponent.gd" id="1_xjrot"]
|
[ext_resource type="Script" path="res://player/footsteps/FootstepsComponent.gd" id="1_xjrot"]
|
||||||
|
|
||||||
[node name="Footsteps" type="Node"]
|
[node name="Footsteps" type="Node3D"]
|
||||||
script = ExtResource("1_xjrot")
|
script = ExtResource("1_xjrot")
|
||||||
|
|
||||||
[node name="LeftFoot" type="AudioStreamPlayer3D" parent="."]
|
[node name="LeftFoot" type="AudioStreamPlayer3D" parent="."]
|
||||||
|
Loading…
Reference in New Issue
Block a user