This commit is contained in:
2025-07-18 00:49:08 +10:00
commit f2ae975aef
16 changed files with 916 additions and 0 deletions

4
.editorconfig Normal file
View File

@@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
*.bin filter=lfs diff=lfs merge=lfs -text

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

BIN
assets/mech/mech.bin LFS Normal file

Binary file not shown.

522
assets/mech/mech.gltf Normal file
View File

@@ -0,0 +1,522 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v4.4.56",
"version":"2.0"
},
"scene":0,
"scenes":[
{
"name":"Mech",
"nodes":[
0,
17,
16
]
}
],
"nodes":[
{
"mesh":0,
"name":"Human-noimp",
"scale":[
0.42965173721313477,
1,
0.42965173721313477
]
},
{
"name":"Head",
"translation":[
0,
4.1141815185546875,
0
]
},
{
"name":"Hand_L",
"rotation":[
0.009082679636776447,
0,
0,
0.9999587535858154
],
"translation":[
0,
5.403164863586426,
7.450580596923828e-09
]
},
{
"children":[
2
],
"name":"Elbow_L",
"rotation":[
-0.01818717271089554,
0,
0,
0.9998346567153931
],
"translation":[
0,
5.389776706695557,
1.4901161193847656e-08
]
},
{
"children":[
3
],
"name":"Shoulder_L",
"rotation":[
-0.9999585747718811,
0,
0,
0.009105246514081955
],
"scale":[
1,
0.9999999403953552,
0.9999999403953552
],
"translation":[
5.912047863006592,
3.309244155883789,
-0.43695497512817383
]
},
{
"name":"Hand_R",
"rotation":[
0.009082679636776447,
0,
0,
0.9999587535858154
],
"translation":[
0,
5.403164863586426,
7.450580596923828e-09
]
},
{
"children":[
5
],
"name":"Elbow_R",
"rotation":[
-0.01818717271089554,
0,
0,
0.9998346567153931
],
"translation":[
0,
5.389776706695557,
1.4901161193847656e-08
]
},
{
"children":[
6
],
"name":"Shoulder_R",
"rotation":[
-0.9999585747718811,
0,
0,
0.009105246514081955
],
"scale":[
1,
0.9999999403953552,
0.9999999403953552
],
"translation":[
-5.912047863006592,
3.309244155883789,
-0.43695497512817383
]
},
{
"children":[
1,
4,
7
],
"name":"Chest",
"translation":[
0,
2.0279788970947266,
0
]
},
{
"name":"Ankle_L",
"rotation":[
-3.1258235111408794e-08,
0.6990172266960144,
-0.715104877948761,
3.0555007413113344e-08
],
"scale":[
1,
0.9999997019767761,
0.9999999403953552
],
"translation":[
-2.384185791015625e-07,
5.512336254119873,
-3.790826319516327e-09
]
},
{
"children":[
9
],
"name":"Knee_L",
"rotation":[
0.02231159433722496,
1.1917964570784534e-07,
-2.659750419908846e-09,
0.9997510313987732
],
"translation":[
-6.24524005843341e-08,
5.733645915985107,
-4.476817139220657e-09
]
},
{
"children":[
10
],
"name":"Thigh_L",
"rotation":[
0.9999401569366455,
-1.3037820822958679e-09,
-1.1920218412342365e-07,
0.010936916805803776
],
"scale":[
1,
1,
1.0000001192092896
],
"translation":[
2.3312768936157227,
0.05723857879638672,
-2.450956912980473e-07
]
},
{
"name":"Ankle_R",
"rotation":[
-3.1258235111408794e-08,
-0.6990172266960144,
0.715104877948761,
3.0555007413113344e-08
],
"scale":[
1,
0.9999997019767761,
0.9999999403953552
],
"translation":[
2.384185791015625e-07,
5.512336254119873,
-3.790826319516327e-09
]
},
{
"children":[
12
],
"name":"Knee_R",
"rotation":[
0.02231159433722496,
-1.1917964570784534e-07,
2.659750419908846e-09,
0.9997510313987732
],
"translation":[
6.24524005843341e-08,
5.733645915985107,
-4.476817139220657e-09
]
},
{
"children":[
13
],
"name":"Thigh_R",
"rotation":[
0.9999401569366455,
1.3037820822958679e-09,
1.1920218412342365e-07,
0.010936916805803776
],
"scale":[
1,
1,
1.0000001192092896
],
"translation":[
-2.3312768936157227,
0.05723857879638672,
-2.450956912980473e-07
]
},
{
"children":[
8,
11,
14
],
"name":"Pelvis",
"rotation":[
0.7071067690849304,
0,
0,
0.7071067690849304
],
"translation":[
0,
0,
11.918725967407227
]
},
{
"children":[
15
],
"name":"Root",
"rotation":[
-0.7071067690849304,
0,
0,
0.7071067690849304
]
},
{
"mesh":1,
"name":"Mech",
"skin":0
}
],
"meshes":[
{
"name":"Cube.001",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3
}
]
},
{
"name":"Mech",
"primitives":[
{
"attributes":{
"POSITION":4,
"NORMAL":5,
"TEXCOORD_0":6,
"JOINTS_0":7,
"WEIGHTS_0":8
},
"indices":9
}
]
}
],
"skins":[
{
"inverseBindMatrices":10,
"joints":[
16,
15,
8,
1,
4,
3,
2,
7,
6,
5,
11,
10,
9,
14,
13,
12
],
"name":"Armature"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":24,
"max":[
0.8999999761581421,
1.7999999523162842,
0.8999999761581421
],
"min":[
-0.8999999761581421,
0,
-0.8999999761581421
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":24,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":24,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":36,
"type":"SCALAR"
},
{
"bufferView":4,
"componentType":5126,
"count":386,
"max":[
7.236874103546143,
19.951175689697266,
2.520752429962158
],
"min":[
-7.236874103546143,
-0.09633678197860718,
-2.4137799739837646
],
"type":"VEC3"
},
{
"bufferView":5,
"componentType":5126,
"count":386,
"type":"VEC3"
},
{
"bufferView":6,
"componentType":5126,
"count":386,
"type":"VEC2"
},
{
"bufferView":7,
"componentType":5121,
"count":386,
"type":"VEC4"
},
{
"bufferView":8,
"componentType":5126,
"count":386,
"type":"VEC4"
},
{
"bufferView":9,
"componentType":5123,
"count":612,
"type":"SCALAR"
},
{
"bufferView":10,
"componentType":5126,
"count":16,
"type":"MAT4"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":288,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":288,
"byteOffset":288,
"target":34962
},
{
"buffer":0,
"byteLength":192,
"byteOffset":576,
"target":34962
},
{
"buffer":0,
"byteLength":72,
"byteOffset":768,
"target":34963
},
{
"buffer":0,
"byteLength":4632,
"byteOffset":840,
"target":34962
},
{
"buffer":0,
"byteLength":4632,
"byteOffset":5472,
"target":34962
},
{
"buffer":0,
"byteLength":3088,
"byteOffset":10104,
"target":34962
},
{
"buffer":0,
"byteLength":1544,
"byteOffset":13192,
"target":34962
},
{
"buffer":0,
"byteLength":6176,
"byteOffset":14736,
"target":34962
},
{
"buffer":0,
"byteLength":1224,
"byteOffset":20912,
"target":34963
},
{
"buffer":0,
"byteLength":1024,
"byteOffset":22136
}
],
"buffers":[
{
"byteLength":23160,
"uri":"mech.bin"
}
]
}

View File

@@ -0,0 +1,37 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://3pl3xkb4yjdn"
path="res://.godot/imported/mech.gltf-eda25fc6898b7b8ce4b778e0c739a83a.scn"
[deps]
source_file="res://assets/mech/mech.gltf"
dest_files=["res://.godot/imported/mech.gltf-eda25fc6898b7b8ce4b778e0c739a83a.scn"]
[params]
nodes/root_type=""
nodes/root_name="Model"
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
_subresources={}
gltf/naming_version=1
gltf/embedded_image_handling=1

1
icon.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 994 B

37
icon.svg.import Normal file
View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c225wwru8kkfs"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

35
project.godot Normal file
View File

@@ -0,0 +1,35 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="mech"
config/version="0.0.1"
run/main_scene="uid://cn6ogqjs52exo"
config/features=PackedStringArray("4.4", "Forward Plus")
boot_splash/bg_color=Color(0, 0, 0, 1)
boot_splash/show_image=false
config/icon="res://icon.svg"
[debug]
gdscript/warnings/untyped_declaration=2
gdscript/warnings/unsafe_call_argument=2
gdscript/warnings/integer_division=0
[display]
window/size/viewport_width=1920
window/size/viewport_height=1080
window/size/always_on_top=true
window/size/window_width_override=1280
window/size/window_height_override=720
window/stretch/mode="canvas_items"
window/stretch/aspect="expand"

View File

@@ -0,0 +1,4 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://dmsfluwqwmclf"]
[resource]
albedo_color = Color(1, 0, 0, 1)

36
scenes/main.tscn Normal file
View File

@@ -0,0 +1,36 @@
[gd_scene load_steps=4 format=3 uid="uid://cn6ogqjs52exo"]
[ext_resource type="PackedScene" uid="uid://dp1r8j1j13e87" path="res://scenes/mech.tscn" id="1_o5qli"]
[sub_resource type="Sky" id="Sky_o5qli"]
[sub_resource type="Environment" id="Environment_0wfyh"]
sky = SubResource("Sky_o5qli")
[node name="Main" type="Node3D"]
[node name="Geometry" type="Node" parent="."]
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="Geometry"]
use_collision = true
[node name="CSGBox3D" type="CSGBox3D" parent="Geometry/CSGCombiner3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -5, 0)
size = Vector3(1000, 10, 1000)
[node name="Environment" type="Node" parent="."]
[node name="Lights" type="Node" parent="Environment"]
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Environment/Lights"]
transform = Transform3D(0.648612, -0.552462, 0.523535, 5.96046e-08, 0.687848, 0.725855, -0.76112, -0.470798, 0.446146, 0, 0, 0)
shadow_enabled = true
[node name="WorldEnvironment" type="WorldEnvironment" parent="Environment"]
environment = SubResource("Environment_0wfyh")
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(0.333396, 0.220921, -0.916538, 7.45058e-09, 0.972158, 0.234328, 0.942787, -0.0781238, 0.324113, -29.9826, 15.4696, 25.0052)
[node name="Mech" parent="." instance=ExtResource("1_o5qli")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)

109
scenes/mech.tscn Normal file
View File

@@ -0,0 +1,109 @@
[gd_scene load_steps=7 format=3 uid="uid://dp1r8j1j13e87"]
[ext_resource type="PackedScene" uid="uid://3pl3xkb4yjdn" path="res://assets/mech/mech.gltf" id="1_0w1yf"]
[ext_resource type="Script" uid="uid://c5n47rrsak7xb" path="res://scripts/mech.gd" id="1_7iq05"]
[ext_resource type="Script" uid="uid://dj5teb5844s8w" path="res://scripts/mech_skeleton_modifier.gd" id="3_qrhul"]
[ext_resource type="Material" uid="uid://dmsfluwqwmclf" path="res://resources/materials/bone_mat.tres" id="4_6gdys"]
[sub_resource type="BoxMesh" id="BoxMesh_dqpf0"]
material = ExtResource("4_6gdys")
[sub_resource type="BoxShape3D" id="BoxShape3D_6gdys"]
size = Vector3(2.64, 1.207, 3.923)
[node name="Mech" type="Node3D" node_paths=PackedStringArray("_skeleton", "_leg_ik_l", "_leg_foot_body_l", "_leg_ik_magnet_l", "_leg_ik_r", "_leg_foot_body_r", "_leg_ik_magnet_r")]
script = ExtResource("1_7iq05")
_skeleton = NodePath("Model/Skeleton3D")
_leg_ik_l = NodePath("Model/Skeleton3D/IKLegL")
_leg_foot_body_l = NodePath("FootL")
_leg_ik_magnet_l = NodePath("FootL/IKTargetL/IKMagnetL")
_leg_ik_r = NodePath("Model/Skeleton3D/IKLegR")
_leg_foot_body_r = NodePath("FootR")
_leg_ik_magnet_r = NodePath("FootR/IKTargetR/IKMagnetR")
[node name="Model" parent="." instance=ExtResource("1_0w1yf")]
[node name="MechSkeletonModifier" type="SkeletonModifier3D" parent="Model/Skeleton3D" index="1" node_paths=PackedStringArray("_leg_ik_target_l", "_leg_ik_target_r")]
_import_path = NodePath("")
unique_name_in_owner = false
process_mode = 0
process_priority = 0
process_physics_priority = 0
process_thread_group = 0
physics_interpolation_mode = 0
auto_translate_mode = 0
editor_description = ""
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
rotation_edit_mode = 0
rotation_order = 2
top_level = false
visible = true
visibility_parent = NodePath("")
active = true
influence = 1.0
script = ExtResource("3_qrhul")
_leg_ik_target_l = NodePath("../../../FootL/IKTargetL")
_leg_ik_target_r = NodePath("../../../FootR/IKTargetR")
[node name="IKLegL" type="SkeletonIK3D" parent="Model/Skeleton3D" index="2"]
root_bone = &"Thigh_L"
tip_bone = &"Ankle_L"
use_magnet = true
magnet = Vector3(0, 0, 10)
target_node = NodePath("../../../FootL/IKTargetL")
[node name="IKLegR" type="SkeletonIK3D" parent="Model/Skeleton3D" index="3"]
root_bone = &"Thigh_R"
tip_bone = &"Ankle_R"
use_magnet = true
magnet = Vector3(0, 0, 10)
target_node = NodePath("../../../FootR/IKTargetR")
[node name="BoneMesh" type="MeshInstance3D" parent="Model/Skeleton3D" index="4"]
mesh = SubResource("BoxMesh_dqpf0")
skeleton = NodePath("../..")
[node name="FootL" type="CharacterBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.331, 0.733, 0)
[node name="CollisionShape3D" type="CollisionShape3D" parent="FootL"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.103271, 0.575317)
shape = SubResource("BoxShape3D_6gdys")
[node name="IKTargetL" type="Marker3D" parent="FootL"]
transform = Transform3D(-1, 0, 8.74228e-08, 8.74228e-08, -5.96046e-07, 1, 5.68434e-14, 1, 7.15256e-07, 0.000279903, -0.000217974, -2.45096e-07)
[node name="BoneMesh" type="MeshInstance3D" parent="FootL/IKTargetL"]
transform = Transform3D(-1, 8.74228e-08, 5.2108e-14, -5.68628e-15, -7.15256e-07, 1, 8.74228e-08, 1, 5.96046e-07, 0, 0, 0)
mesh = SubResource("BoxMesh_dqpf0")
skeleton = NodePath("../../..")
[node name="IKMagnetL" type="Marker3D" parent="FootL/IKTargetL"]
transform = Transform3D(1, 0, 3.72706e-20, 0, 1, 0, 3.38813e-20, 0, 1, 1.43051e-06, 9.99999, 2)
[node name="BoneMesh" type="MeshInstance3D" parent="FootL/IKTargetL/IKMagnetL"]
mesh = SubResource("BoxMesh_dqpf0")
skeleton = NodePath("")
[node name="FootR" type="CharacterBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.331, 0.733, 0)
[node name="CollisionShape3D" type="CollisionShape3D" parent="FootR"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.103271, 0.575317)
shape = SubResource("BoxShape3D_6gdys")
[node name="IKTargetR" type="Marker3D" parent="FootR"]
transform = Transform3D(-1, 0, 8.74228e-08, 8.74228e-08, -5.96046e-07, 1, 5.68434e-14, 1, 7.15256e-07, 0, 0, 0)
[node name="BoneMesh" type="MeshInstance3D" parent="FootR/IKTargetR"]
mesh = SubResource("BoxMesh_dqpf0")
skeleton = NodePath("../../..")
[node name="IKMagnetR" type="Marker3D" parent="FootR/IKTargetR"]
transform = Transform3D(1, 0, 3.72706e-20, 0, 1, 0, 3.38813e-20, 0, 1, 1.43051e-06, 9.99999, 2)
[node name="BoneMesh" type="MeshInstance3D" parent="FootR/IKTargetR/IKMagnetR"]
mesh = SubResource("BoxMesh_dqpf0")
skeleton = NodePath("")
[editable path="Model"]

77
scripts/mech.gd Normal file
View File

@@ -0,0 +1,77 @@
class_name Mech extends Node3D
@export_group("Skeleton")
@export var _skeleton: Skeleton3D
@export_subgroup("Left")
@export var _ankle_bone_l: String = "Ankle_L"
@export var _leg_ik_l: SkeletonIK3D
@export var _leg_foot_body_l: CharacterBody3D
@export var _leg_ik_magnet_l: Node3D
@export_subgroup("Right")
@export var _ankle_bone_r: String = "Ankle_R"
@export var _leg_ik_r: SkeletonIK3D
@export var _leg_foot_body_r: CharacterBody3D
@export var _leg_ik_magnet_r: Node3D
@export_group("Walking")
@export var _mouse_walk_sensitivity: float = 1
var _mouse_relative: Vector2
func _ready() -> void:
_leg_ik_l.start()
_leg_ik_r.start()
_ready_leg_ik(_leg_foot_body_l, _ankle_bone_l)
_ready_leg_ik(_leg_foot_body_r, _ankle_bone_r)
func _ready_leg_ik(foot_body: Node3D, bone: String) -> void:
foot_body.position = (
_skeleton.get_bone_global_rest(_skeleton.find_bone(bone)).origin
)
func _process(_delta: float) -> void:
_process_leg_ik(_leg_ik_l, _leg_ik_magnet_l)
_process_leg_ik(_leg_ik_r, _leg_ik_magnet_r)
func _process_leg_ik(ik: SkeletonIK3D, ik_magnet: Node3D) -> void:
ik.magnet = to_local(ik_magnet.global_position)
func _physics_process(_delta: float) -> void:
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
_handle_leg_moving(_mouse_relative, _leg_foot_body_l)
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
_handle_leg_moving(_mouse_relative, _leg_foot_body_r)
_mouse_relative = Vector2.ZERO
func _handle_leg_moving(mouse_delta: Vector2, foot_body: CharacterBody3D) -> void:
var velocity_local := Vector3(
0,
-mouse_delta.y * _mouse_walk_sensitivity,
mouse_delta.x * _mouse_walk_sensitivity
)
foot_body.velocity = transform.basis * velocity_local
foot_body.move_and_slide()
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
var event_mouse := event as InputEventMouseMotion
_mouse_relative = event_mouse.screen_relative
else:
_mouse_relative = Vector2.ZERO
if event is InputEventMouseButton:
var event_mouse := event as InputEventMouseButton
if event_mouse.is_pressed():
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
else:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE

1
scripts/mech.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://c5n47rrsak7xb

View File

@@ -0,0 +1,42 @@
class_name MechSkeletonModifier extends SkeletonModifier3D
@export var _pelvis_bone: String = "Pelvis"
@export var _ankle_bone_l: String = "Ankle_L"
@export var _leg_ik_target_l: Node3D
@export var _ankle_bone_r: String = "Ankle_R"
@export var _leg_ik_target_r: Node3D
var _skeleton: Skeleton3D
var _pelvis_rest_y: float
func _ready() -> void:
_skeleton = get_skeleton()
var pelvis_rest := _skeleton.get_bone_global_rest(_skeleton.find_bone(_pelvis_bone))
var ankle_rest_l := _skeleton.get_bone_global_rest(
_skeleton.find_bone(_ankle_bone_l)
)
var ankle_rest_r := _skeleton.get_bone_global_rest(
_skeleton.find_bone(_ankle_bone_r)
)
_pelvis_rest_y = (
pelvis_rest.origin.y - (ankle_rest_l.origin.y + ankle_rest_r.origin.y) / 2
)
func _process_modification() -> void:
if not _skeleton:
return
var pelvis_bone := _skeleton.find_bone(_pelvis_bone)
var pelvis_bone_pose := _skeleton.get_bone_global_pose(pelvis_bone)
var leg_target_pos_l := to_local(_leg_ik_target_l.global_position)
var leg_target_pos_r := to_local(_leg_ik_target_r.global_position)
var pelvis_pos := (leg_target_pos_l + leg_target_pos_r) / 2
pelvis_pos.y = minf(leg_target_pos_l.y, leg_target_pos_r.y) + _pelvis_rest_y
pelvis_bone_pose.origin = pelvis_pos
_skeleton.set_bone_global_pose(pelvis_bone, pelvis_bone_pose)

View File

@@ -0,0 +1 @@
uid://dj5teb5844s8w