├── .gitignore ├── LICENSE ├── README.md └── project ├── .gitattributes ├── .gitignore ├── addons └── godot-jolt │ ├── LICENSE.txt │ ├── THIRDPARTY.txt │ ├── godot-jolt.gdextension │ ├── linux │ ├── godot-jolt_linux-x64.so │ ├── godot-jolt_linux-x64_editor.so │ ├── godot-jolt_linux-x86.so │ └── godot-jolt_linux-x86_editor.so │ ├── macos │ ├── godot-jolt_macos.framework │ │ ├── Resources │ │ │ └── Info.plist │ │ ├── _CodeSignature │ │ │ └── CodeResources │ │ └── godot-jolt_macos │ └── godot-jolt_macos_editor.framework │ │ ├── Resources │ │ └── Info.plist │ │ ├── _CodeSignature │ │ └── CodeResources │ │ └── godot-jolt_macos_editor │ └── windows │ ├── godot-jolt_windows-x64.dll │ ├── godot-jolt_windows-x64_editor.dll │ ├── godot-jolt_windows-x86.dll │ └── godot-jolt_windows-x86_editor.dll ├── assets ├── checkerboard.jpg ├── checkerboard.jpg.import ├── cross_hairs.png ├── cross_hairs.png.import ├── mannequin │ ├── mannequin.glb │ └── mannequin.glb.import ├── player.blend ├── sand.png └── sand.png.import ├── icon.svg ├── icon.svg.import ├── project.godot └── src ├── Bullet ├── bullet.gd └── bullet.tscn ├── BulletGlow ├── bullet_glow.gd └── bullet_glow.tscn ├── BulletSpark ├── bullet_spark.gd └── bullet_spark.tscn ├── CannedColaSoda ├── canned_cola_soda.tscn └── standard_material.tres ├── Mannequin ├── broken_body_part.gd ├── mannequin.gd ├── mannequin.tscn └── physics_skeleton.gd ├── NPC ├── npc.gd └── npc.tscn ├── Player ├── player.gd └── player.tscn ├── Rock ├── Rock.gd └── Rock.tscn ├── ShootingDisplayOfCans └── shooting_display_of_cans.tscn ├── Singletons └── Global.gd ├── Structures ├── Building │ └── building.tscn └── Floor │ └── floor.tscn └── World ├── world.gd └── world.tscn /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Godot 4+ specific ignores 4 | .godot/ 5 | 6 | # Godot-specific ignores 7 | .import/ 8 | export.cfg 9 | export_presets.cfg 10 | 11 | # Imported translations (automatically generated from CSV files) 12 | *.translation 13 | 14 | # Mono-specific ignores 15 | .mono/ 16 | data_*/ 17 | mono_crash.*.json 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2023 Matthew Brennan Jones 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot Ragdoll Example 2 | 3 | 4 | 5 | 👇👇👇Link to Youtube video 👇👇👇 6 | 7 | [![Raycast bullets in Godot](https://img.youtube.com/vi/vyWlwVPRODA/0.jpg)](https://www.youtube.com/watch?v=vyWlwVPRODA, "Godot Active ragdolls with breakable floppy limbs") 8 | 9 | 10 | ## NPC mannequin and animations are from Mixamo 11 | 12 | https://www.mixamo.com 13 | 14 | Licensed under [Adobe General Terms of Use](https://www.adobe.com/legal/terms.html) 15 | -------------------------------------------------------------------------------- /project/.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize EOL for all files that Git considers text files. 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /project/.gitignore: -------------------------------------------------------------------------------- 1 | # Godot 4+ specific ignores 2 | .godot/ 3 | -------------------------------------------------------------------------------- /project/addons/godot-jolt/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Mikael Hermansson and Godot Jolt contributors. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /project/addons/godot-jolt/THIRDPARTY.txt: -------------------------------------------------------------------------------- 1 | Godot Jolt incorporates third-party material from the projects listed below. 2 | 3 | Godot Engine (https://github.com/godotengine/godot) 4 | 5 | Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). 6 | Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to 10 | deal in the Software without restriction, including without limitation the 11 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 | sell copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | IN THE SOFTWARE. 25 | 26 | godot-cpp (https://github.com/godot-jolt/godot-cpp) 27 | 28 | Copyright (c) 2017-present Godot Engine contributors. 29 | Copyright (c) 2022-present Mikael Hermansson. 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to 33 | deal in the Software without restriction, including without limitation the 34 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 35 | sell copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 46 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 47 | IN THE SOFTWARE. 48 | 49 | Jolt Physics (https://github.com/godot-jolt/jolt) 50 | 51 | Copyright (c) 2021 Jorrit Rouwe. 52 | 53 | Permission is hereby granted, free of charge, to any person obtaining a copy 54 | of this software and associated documentation files (the "Software"), to 55 | deal in the Software without restriction, including without limitation the 56 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 57 | sell copies of the Software, and to permit persons to whom the Software is 58 | furnished to do so, subject to the following conditions: 59 | 60 | The above copyright notice and this permission notice shall be included in 61 | all copies or substantial portions of the Software. 62 | 63 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 64 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 65 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 66 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 67 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 68 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 69 | IN THE SOFTWARE. 70 | 71 | mimalloc (https://github.com/godot-jolt/mimalloc) 72 | 73 | Copyright (c) 2018-2021 Microsoft Corporation, Daan Leijen. 74 | 75 | Permission is hereby granted, free of charge, to any person obtaining a copy 76 | of this software and associated documentation files (the "Software"), to 77 | deal in the Software without restriction, including without limitation the 78 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 79 | sell copies of the Software, and to permit persons to whom the Software is 80 | furnished to do so, subject to the following conditions: 81 | 82 | The above copyright notice and this permission notice shall be included in 83 | all copies or substantial portions of the Software. 84 | 85 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 86 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 87 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 88 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 89 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 90 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 91 | IN THE SOFTWARE. 92 | -------------------------------------------------------------------------------- /project/addons/godot-jolt/godot-jolt.gdextension: -------------------------------------------------------------------------------- 1 | [configuration] 2 | 3 | entry_symbol = "godot_jolt_main" 4 | compatibility_minimum = 4.1 5 | 6 | [libraries] 7 | 8 | windows.release.x86_64 = "windows/godot-jolt_windows-x64.dll" 9 | windows.debug.x86_64 = "windows/godot-jolt_windows-x64_editor.dll" 10 | 11 | windows.release.x86_32 = "windows/godot-jolt_windows-x86.dll" 12 | windows.debug.x86_32 = "windows/godot-jolt_windows-x86_editor.dll" 13 | 14 | linux.release.x86_64 = "linux/godot-jolt_linux-x64.so" 15 | linux.debug.x86_64 = "linux/godot-jolt_linux-x64_editor.so" 16 | 17 | linux.release.x86_32 = "linux/godot-jolt_linux-x86.so" 18 | linux.debug.x86_32 = "linux/godot-jolt_linux-x86_editor.so" 19 | 20 | macos.release = "macos/godot-jolt_macos.framework" 21 | macos.debug = "macos/godot-jolt_macos_editor.framework" 22 | -------------------------------------------------------------------------------- /project/addons/godot-jolt/linux/godot-jolt_linux-x64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/linux/godot-jolt_linux-x64.so -------------------------------------------------------------------------------- /project/addons/godot-jolt/linux/godot-jolt_linux-x64_editor.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/linux/godot-jolt_linux-x64_editor.so -------------------------------------------------------------------------------- /project/addons/godot-jolt/linux/godot-jolt_linux-x86.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/linux/godot-jolt_linux-x86.so -------------------------------------------------------------------------------- /project/addons/godot-jolt/linux/godot-jolt_linux-x86_editor.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/linux/godot-jolt_linux-x86_editor.so -------------------------------------------------------------------------------- /project/addons/godot-jolt/macos/godot-jolt_macos.framework/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleInfoDictionaryVersion 6 | 6.0 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | godot-jolt_macos 11 | CFBundleName 12 | Godot Jolt 13 | CFBundleDisplayName 14 | Godot Jolt 15 | CFBundleIdentifier 16 | org.godot-jolt.godot-jolt 17 | NSHumanReadableCopyright 18 | Copyright (c) Mikael Hermansson and Godot Jolt contributors. 19 | CFBundleVersion 20 | 0.7.0 21 | CFBundleShortVersionString 22 | 0.7.0 23 | CFBundlePackageType 24 | FMWK 25 | CSResourcesFileMapped 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /project/addons/godot-jolt/macos/godot-jolt_macos.framework/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Resources/Info.plist 8 | 9 | CyyTXlw+5KVWTBKf4hsm1fESGUE= 10 | 11 | 12 | files2 13 | 14 | Resources/Info.plist 15 | 16 | hash2 17 | 18 | +eS5JzFPyUrG61UN70sHUHyOmYybC9/+Alctl+2RKTg= 19 | 20 | 21 | 22 | rules 23 | 24 | ^Resources/ 25 | 26 | ^Resources/.*\.lproj/ 27 | 28 | optional 29 | 30 | weight 31 | 1000 32 | 33 | ^Resources/.*\.lproj/locversion.plist$ 34 | 35 | omit 36 | 37 | weight 38 | 1100 39 | 40 | ^Resources/Base\.lproj/ 41 | 42 | weight 43 | 1010 44 | 45 | ^version.plist$ 46 | 47 | 48 | rules2 49 | 50 | .*\.dSYM($|/) 51 | 52 | weight 53 | 11 54 | 55 | ^(.*/)?\.DS_Store$ 56 | 57 | omit 58 | 59 | weight 60 | 2000 61 | 62 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 63 | 64 | nested 65 | 66 | weight 67 | 10 68 | 69 | ^.* 70 | 71 | ^Info\.plist$ 72 | 73 | omit 74 | 75 | weight 76 | 20 77 | 78 | ^PkgInfo$ 79 | 80 | omit 81 | 82 | weight 83 | 20 84 | 85 | ^Resources/ 86 | 87 | weight 88 | 20 89 | 90 | ^Resources/.*\.lproj/ 91 | 92 | optional 93 | 94 | weight 95 | 1000 96 | 97 | ^Resources/.*\.lproj/locversion.plist$ 98 | 99 | omit 100 | 101 | weight 102 | 1100 103 | 104 | ^Resources/Base\.lproj/ 105 | 106 | weight 107 | 1010 108 | 109 | ^[^/]+$ 110 | 111 | nested 112 | 113 | weight 114 | 10 115 | 116 | ^embedded\.provisionprofile$ 117 | 118 | weight 119 | 20 120 | 121 | ^version\.plist$ 122 | 123 | weight 124 | 20 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /project/addons/godot-jolt/macos/godot-jolt_macos.framework/godot-jolt_macos: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/macos/godot-jolt_macos.framework/godot-jolt_macos -------------------------------------------------------------------------------- /project/addons/godot-jolt/macos/godot-jolt_macos_editor.framework/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleInfoDictionaryVersion 6 | 6.0 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | godot-jolt_macos_editor 11 | CFBundleName 12 | Godot Jolt 13 | CFBundleDisplayName 14 | Godot Jolt 15 | CFBundleIdentifier 16 | org.godot-jolt.godot-jolt 17 | NSHumanReadableCopyright 18 | Copyright (c) Mikael Hermansson and Godot Jolt contributors. 19 | CFBundleVersion 20 | 0.7.0 21 | CFBundleShortVersionString 22 | 0.7.0 23 | CFBundlePackageType 24 | FMWK 25 | CSResourcesFileMapped 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /project/addons/godot-jolt/macos/godot-jolt_macos_editor.framework/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Resources/Info.plist 8 | 9 | XH8QDnynFWnffS3UXcFsiGaRFGQ= 10 | 11 | 12 | files2 13 | 14 | Resources/Info.plist 15 | 16 | hash2 17 | 18 | ZJosGVVywtP0y84i6zvBV/q1crWPdZGbD+exKGKcH3U= 19 | 20 | 21 | 22 | rules 23 | 24 | ^Resources/ 25 | 26 | ^Resources/.*\.lproj/ 27 | 28 | optional 29 | 30 | weight 31 | 1000 32 | 33 | ^Resources/.*\.lproj/locversion.plist$ 34 | 35 | omit 36 | 37 | weight 38 | 1100 39 | 40 | ^Resources/Base\.lproj/ 41 | 42 | weight 43 | 1010 44 | 45 | ^version.plist$ 46 | 47 | 48 | rules2 49 | 50 | .*\.dSYM($|/) 51 | 52 | weight 53 | 11 54 | 55 | ^(.*/)?\.DS_Store$ 56 | 57 | omit 58 | 59 | weight 60 | 2000 61 | 62 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 63 | 64 | nested 65 | 66 | weight 67 | 10 68 | 69 | ^.* 70 | 71 | ^Info\.plist$ 72 | 73 | omit 74 | 75 | weight 76 | 20 77 | 78 | ^PkgInfo$ 79 | 80 | omit 81 | 82 | weight 83 | 20 84 | 85 | ^Resources/ 86 | 87 | weight 88 | 20 89 | 90 | ^Resources/.*\.lproj/ 91 | 92 | optional 93 | 94 | weight 95 | 1000 96 | 97 | ^Resources/.*\.lproj/locversion.plist$ 98 | 99 | omit 100 | 101 | weight 102 | 1100 103 | 104 | ^Resources/Base\.lproj/ 105 | 106 | weight 107 | 1010 108 | 109 | ^[^/]+$ 110 | 111 | nested 112 | 113 | weight 114 | 10 115 | 116 | ^embedded\.provisionprofile$ 117 | 118 | weight 119 | 20 120 | 121 | ^version\.plist$ 122 | 123 | weight 124 | 20 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /project/addons/godot-jolt/macos/godot-jolt_macos_editor.framework/godot-jolt_macos_editor: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/macos/godot-jolt_macos_editor.framework/godot-jolt_macos_editor -------------------------------------------------------------------------------- /project/addons/godot-jolt/windows/godot-jolt_windows-x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/windows/godot-jolt_windows-x64.dll -------------------------------------------------------------------------------- /project/addons/godot-jolt/windows/godot-jolt_windows-x64_editor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/windows/godot-jolt_windows-x64_editor.dll -------------------------------------------------------------------------------- /project/addons/godot-jolt/windows/godot-jolt_windows-x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/windows/godot-jolt_windows-x86.dll -------------------------------------------------------------------------------- /project/addons/godot-jolt/windows/godot-jolt_windows-x86_editor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/addons/godot-jolt/windows/godot-jolt_windows-x86_editor.dll -------------------------------------------------------------------------------- /project/assets/checkerboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/assets/checkerboard.jpg -------------------------------------------------------------------------------- /project/assets/checkerboard.jpg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c5vcwaniev6jw" 6 | path.s3tc="res://.godot/imported/checkerboard.jpg-abe44bbd4c14865e450f13b2f298616c.s3tc.ctex" 7 | metadata={ 8 | "imported_formats": ["s3tc_bptc"], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://assets/checkerboard.jpg" 15 | dest_files=["res://.godot/imported/checkerboard.jpg-abe44bbd4c14865e450f13b2f298616c.s3tc.ctex"] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/high_quality=false 21 | compress/lossy_quality=0.7 22 | compress/hdr_compression=1 23 | compress/normal_map=0 24 | compress/channel_pack=0 25 | mipmaps/generate=true 26 | mipmaps/limit=-1 27 | roughness/mode=0 28 | roughness/src_normal="" 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/normal_map_invert_y=false 32 | process/hdr_as_srgb=false 33 | process/hdr_clamp_exposure=false 34 | process/size_limit=0 35 | detect_3d/compress_to=0 36 | -------------------------------------------------------------------------------- /project/assets/cross_hairs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/assets/cross_hairs.png -------------------------------------------------------------------------------- /project/assets/cross_hairs.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bhtx5f5lxr5l8" 6 | path="res://.godot/imported/cross_hairs.png-50aa67b238488c0c1bb0c5c8fdd67ac7.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://assets/cross_hairs.png" 14 | dest_files=["res://.godot/imported/cross_hairs.png-50aa67b238488c0c1bb0c5c8fdd67ac7.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /project/assets/mannequin/mannequin.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/assets/mannequin/mannequin.glb -------------------------------------------------------------------------------- /project/assets/player.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/assets/player.blend -------------------------------------------------------------------------------- /project/assets/sand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImmersiveRPG/ExampleRagdoll/d6bad4084d2f083e197ba6277e26e39fc359b3e7/project/assets/sand.png -------------------------------------------------------------------------------- /project/assets/sand.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://du2fgctptabbl" 6 | path.s3tc="res://.godot/imported/sand.png-9f865ffb29e91443d533cc74947c6644.s3tc.ctex" 7 | metadata={ 8 | "imported_formats": ["s3tc_bptc"], 9 | "vram_texture": true 10 | } 11 | 12 | [deps] 13 | 14 | source_file="res://assets/sand.png" 15 | dest_files=["res://.godot/imported/sand.png-9f865ffb29e91443d533cc74947c6644.s3tc.ctex"] 16 | 17 | [params] 18 | 19 | compress/mode=2 20 | compress/high_quality=false 21 | compress/lossy_quality=0.7 22 | compress/hdr_compression=1 23 | compress/normal_map=0 24 | compress/channel_pack=0 25 | mipmaps/generate=true 26 | mipmaps/limit=-1 27 | roughness/mode=0 28 | roughness/src_normal="" 29 | process/fix_alpha_border=true 30 | process/premult_alpha=false 31 | process/normal_map_invert_y=false 32 | process/hdr_as_srgb=false 33 | process/hdr_clamp_exposure=false 34 | process/size_limit=0 35 | detect_3d/compress_to=0 36 | -------------------------------------------------------------------------------- /project/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /project/icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cpiwhnqvrjghq" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /project/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="Ragdoll Example" 14 | run/main_scene="res://src/World/world.tscn" 15 | config/features=PackedStringArray("4.1", "Forward Plus") 16 | config/icon="res://icon.svg" 17 | 18 | [autoload] 19 | 20 | Global="*res://src/Singletons/Global.gd" 21 | 22 | [display] 23 | 24 | window/size/viewport_width=1700 25 | window/size/viewport_height=800 26 | 27 | [input] 28 | 29 | MoveRight={ 30 | "deadzone": 0.5, 31 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) 32 | ] 33 | } 34 | MoveLeft={ 35 | "deadzone": 0.5, 36 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) 37 | ] 38 | } 39 | MoveBack={ 40 | "deadzone": 0.5, 41 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) 42 | ] 43 | } 44 | MoveForward={ 45 | "deadzone": 0.5, 46 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) 47 | ] 48 | } 49 | Sprint={ 50 | "deadzone": 0.5, 51 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"echo":false,"script":null) 52 | ] 53 | } 54 | ToggleFullScreen={ 55 | "deadzone": 0.5, 56 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194342,"key_label":0,"unicode":0,"echo":false,"script":null) 57 | ] 58 | } 59 | Quit={ 60 | "deadzone": 0.5, 61 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"echo":false,"script":null) 62 | ] 63 | } 64 | ToggleMouseCapture={ 65 | "deadzone": 0.5, 66 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"echo":false,"script":null) 67 | ] 68 | } 69 | NpcDie={ 70 | "deadzone": 0.5, 71 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"echo":false,"script":null) 72 | ] 73 | } 74 | BreakRightArm={ 75 | "deadzone": 0.5, 76 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":114,"echo":false,"script":null) 77 | ] 78 | } 79 | BreakLeftArm={ 80 | "deadzone": 0.5, 81 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":84,"key_label":0,"unicode":116,"echo":false,"script":null) 82 | ] 83 | } 84 | BreakRightLeg={ 85 | "deadzone": 0.5, 86 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":89,"key_label":0,"unicode":121,"echo":false,"script":null) 87 | ] 88 | } 89 | BreakLeftLeg={ 90 | "deadzone": 0.5, 91 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":85,"key_label":0,"unicode":117,"echo":false,"script":null) 92 | ] 93 | } 94 | BreakHead={ 95 | "deadzone": 0.5, 96 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":73,"key_label":0,"unicode":105,"echo":false,"script":null) 97 | ] 98 | } 99 | BreakEverything={ 100 | "deadzone": 0.5, 101 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":79,"key_label":0,"unicode":111,"echo":false,"script":null) 102 | ] 103 | } 104 | ThrowNPC={ 105 | "deadzone": 0.5, 106 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":80,"key_label":0,"unicode":112,"echo":false,"script":null) 107 | ] 108 | } 109 | ThrowCola={ 110 | "deadzone": 0.5, 111 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"echo":false,"script":null) 112 | ] 113 | } 114 | ShootBullet={ 115 | "deadzone": 0.5, 116 | "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) 117 | ] 118 | } 119 | NPCMove={ 120 | "deadzone": 0.5, 121 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":77,"key_label":0,"unicode":109,"echo":false,"script":null) 122 | ] 123 | } 124 | 125 | [layer_names] 126 | 127 | 3d_physics/layer_1="terrain" 128 | 3d_physics/layer_2="item" 129 | 3d_physics/layer_3="player" 130 | 3d_physics/layer_4="npc" 131 | 3d_physics/layer_5="position_trigger" 132 | 3d_physics/layer_6="furniture" 133 | 3d_physics/layer_7="structure" 134 | 3d_physics/layer_8="interact_point" 135 | 3d_physics/layer_9="vehicle" 136 | 3d_physics/layer_10="destructible" 137 | 3d_physics/layer_11="small" 138 | 3d_physics/layer_12="sun" 139 | 3d_physics/layer_13="liquid" 140 | 3d_physics/layer_14="body_part" 141 | 3d_physics/layer_15="animal" 142 | 3d_physics/layer_16="label" 143 | 3d_physics/layer_17="temperature" 144 | 145 | [physics] 146 | 147 | 3d/physics_engine="JoltPhysics3D" 148 | -------------------------------------------------------------------------------- /project/src/Bullet/bullet.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends Node3D 6 | class_name Bullet 7 | 8 | var _bullet_type := -1 9 | var _mass := -1.0 10 | var _max_distance := -1.0 11 | var _glow = null 12 | var _speed := 0.0 13 | var _velocity : Vector3 14 | var _is_setup := false 15 | 16 | var _total_distance := 0.0 17 | @onready var _ray : RayCast3D = $RayCast3D 18 | 19 | # NOTE: Make sure min bounce distance is greater than max raycast distance 20 | const MIN_BOUNCE_DISTANCE := 0.1 21 | const MIN_RAYCAST_DISTANCE := 0.05 22 | 23 | func _physics_process(delta : float) -> void: 24 | if not _is_setup: return 25 | var is_destroyed := false 26 | 27 | _glow.update(self.global_transform.origin) 28 | 29 | # Move the bullet 30 | var distance := _velocity.length() * delta 31 | self.transform.origin -= _velocity * delta 32 | 33 | # Change the ray start position to the bullets's previous position 34 | # NOTE: The ray is backwards, so if it is hitting multiple targets, we 35 | # get the target closest to the bullet start position. 36 | # Also make the ray at least the min length 37 | if distance > MIN_RAYCAST_DISTANCE: 38 | _ray.target_position.z = -distance 39 | _ray.transform.origin.z = distance 40 | else: 41 | _ray.target_position.z = -MIN_RAYCAST_DISTANCE 42 | _ray.transform.origin.z = MIN_RAYCAST_DISTANCE 43 | 44 | # Check if hit something 45 | _ray.force_raycast_update() 46 | if _ray.is_colliding(): 47 | var collider := _ray.get_collider() 48 | print("Bullet hit %s" % [collider.name]) 49 | 50 | # Move the bullet back to the position of the collision 51 | self.global_transform.origin = _ray.get_collision_point() 52 | 53 | if collider.is_in_group("body_part"): 54 | var force := _mass * _velocity.length() 55 | collider.owner.emit_signal("hit", collider, self.global_transform.origin, -self.global_transform.basis.z, force, _bullet_type) 56 | is_destroyed = true 57 | # Hit object 58 | elif collider.is_in_group("item"): 59 | # Nudge the object 60 | var force := _mass * _velocity.length() 61 | collider.apply_central_impulse(-self.transform.basis.z * force) 62 | is_destroyed = true 63 | # Hit something unexpected 64 | else: 65 | is_destroyed = true 66 | 67 | # Add bullet spark 68 | Global.create_bullet_spark(self.global_transform.origin) 69 | 70 | # Update glow 71 | _glow.update(self.global_transform.origin) 72 | 73 | # Delete the bullet if it is slow 74 | if distance < 1.0: 75 | is_destroyed = true 76 | 77 | # Delete the bullet if it has gone its max distance 78 | _total_distance += distance 79 | if _total_distance > _max_distance: 80 | is_destroyed = true 81 | 82 | if is_destroyed: 83 | self.queue_free() 84 | _glow._is_parent_bullet_destroyed = true 85 | 86 | func start(bullet_type : Global.BulletType) -> void: 87 | # Get the bullet info from the database 88 | _bullet_type = bullet_type 89 | var entry : Dictionary = Global.DB["Bullets"][_bullet_type] 90 | _mass = entry["mass"] 91 | _max_distance = entry["max_distance"] 92 | _speed = entry["speed"] 93 | _velocity = self.transform.basis.z * _speed 94 | 95 | # Add bullet glow 96 | _glow = Global._scene_bullet_glow.instantiate() 97 | Global._world.add_child(_glow) 98 | _glow.global_transform.origin = self.global_transform.origin 99 | _glow.start(self) 100 | 101 | _is_setup = true 102 | -------------------------------------------------------------------------------- /project/src/Bullet/bullet.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://casialoq8fi2d"] 2 | 3 | [ext_resource type="Script" path="res://src/Bullet/bullet.gd" id="1_jyo32"] 4 | 5 | [sub_resource type="CapsuleMesh" id="CapsuleMesh_3evlp"] 6 | radius = 0.006 7 | height = 0.025 8 | radial_segments = 16 9 | rings = 1 10 | 11 | [node name="Bullet" type="Node3D"] 12 | script = ExtResource("1_jyo32") 13 | 14 | [node name="MeshInstance3D" type="MeshInstance3D" parent="."] 15 | transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0) 16 | mesh = SubResource("CapsuleMesh_3evlp") 17 | 18 | [node name="RayCast3D" type="RayCast3D" parent="."] 19 | transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0) 20 | target_position = Vector3(0, 0, 0) 21 | collision_mask = 25443 22 | collide_with_areas = true 23 | -------------------------------------------------------------------------------- /project/src/BulletGlow/bullet_glow.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends MeshInstance3D 6 | class_name BulletGlow 7 | 8 | var _points : Array[Vector3] = [] 9 | var _prev_pos := Vector3.ZERO 10 | var _immediate_mesh : ImmediateMesh = null 11 | var _is_parent_bullet_destroyed := false 12 | 13 | func _ready() -> void: 14 | _immediate_mesh = self.mesh 15 | 16 | func update(parent_pos : Vector3) -> void: 17 | # If the parent bullet still exists, add a point when it moves at least a meter 18 | var distance := _prev_pos.distance_to(parent_pos) 19 | if distance > 0.1: 20 | _prev_pos = parent_pos 21 | 22 | # Save position as local space 23 | _points.append(parent_pos - self.global_transform.origin) 24 | 25 | if _points.size() > 6: 26 | _points.pop_front() 27 | 28 | func _physics_process(_delta : float) -> void: 29 | # If the bullet is destroyed, delete the points 30 | if _is_parent_bullet_destroyed: 31 | if not _points.is_empty(): 32 | _points.pop_front() 33 | else: 34 | self.queue_free() 35 | 36 | func _process(_delta : float) -> void: 37 | if not _immediate_mesh: return 38 | if _points.size() < 2: return 39 | 40 | # Draw the line 41 | _immediate_mesh.clear_surfaces() 42 | _immediate_mesh.surface_begin(Mesh.PRIMITIVE_LINES) 43 | for i in _points.size(): 44 | if i + 1 < _points.size(): 45 | var a := _points[i] 46 | var b := _points[i + 1] 47 | _immediate_mesh.surface_add_vertex(a) 48 | _immediate_mesh.surface_add_vertex(b) 49 | _immediate_mesh.surface_end() 50 | 51 | func start(bullet : Node3D) -> void: 52 | _points.append(bullet.global_transform.origin - self.global_transform.origin) 53 | self._physics_process(0.0) 54 | -------------------------------------------------------------------------------- /project/src/BulletGlow/bullet_glow.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://bqnr822reuy5i"] 2 | 3 | [ext_resource type="Script" path="res://src/BulletGlow/bullet_glow.gd" id="1_fnef4"] 4 | 5 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_2tka4"] 6 | transparency = 1 7 | albedo_color = Color(1, 0.654902, 0, 1) 8 | emission_enabled = true 9 | emission = Color(1, 1, 1, 1) 10 | emission_energy_multiplier = 8.0 11 | emission_on_uv2 = true 12 | 13 | [sub_resource type="ImmediateMesh" id="ImmediateMesh_2r8of"] 14 | resource_local_to_scene = true 15 | 16 | [node name="BulletGlow" type="MeshInstance3D"] 17 | material_override = SubResource("StandardMaterial3D_2tka4") 18 | mesh = SubResource("ImmediateMesh_2r8of") 19 | script = ExtResource("1_fnef4") 20 | -------------------------------------------------------------------------------- /project/src/BulletSpark/bullet_spark.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends MeshInstance3D 6 | 7 | 8 | func _on_timer_die_timeout() -> void: 9 | self.queue_free() 10 | -------------------------------------------------------------------------------- /project/src/BulletSpark/bullet_spark.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://b3kn873utmgu2"] 2 | 3 | [ext_resource type="Script" path="res://src/BulletSpark/bullet_spark.gd" id="1_oewmt"] 4 | 5 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_5pm02"] 6 | transparency = 1 7 | albedo_color = Color(1, 0.654902, 0, 1) 8 | emission_enabled = true 9 | emission = Color(1, 1, 1, 1) 10 | emission_energy_multiplier = 8.0 11 | emission_on_uv2 = true 12 | 13 | [sub_resource type="SphereMesh" id="SphereMesh_3dchx"] 14 | material = SubResource("StandardMaterial3D_5pm02") 15 | radius = 0.1 16 | height = 0.2 17 | radial_segments = 16 18 | rings = 8 19 | 20 | [node name="BulletSpark" type="MeshInstance3D"] 21 | mesh = SubResource("SphereMesh_3dchx") 22 | script = ExtResource("1_oewmt") 23 | 24 | [node name="TimerDie" type="Timer" parent="."] 25 | wait_time = 0.1 26 | one_shot = true 27 | autostart = true 28 | 29 | [connection signal="timeout" from="TimerDie" to="." method="_on_timer_die_timeout"] 30 | -------------------------------------------------------------------------------- /project/src/CannedColaSoda/canned_cola_soda.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://chcausi51uaf6"] 2 | 3 | [ext_resource type="Material" uid="uid://qu667h24wu1g" path="res://src/CannedColaSoda/standard_material.tres" id="1_qxco8"] 4 | 5 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_vpalr"] 6 | height = 0.122 7 | radius = 0.033 8 | 9 | [sub_resource type="CylinderMesh" id="CylinderMesh_gk3pp"] 10 | material = ExtResource("1_qxco8") 11 | top_radius = 0.033 12 | bottom_radius = 0.033 13 | height = 0.122 14 | radial_segments = 16 15 | rings = 1 16 | 17 | [node name="CannedColaSoda" type="RigidBody3D" groups=["item"]] 18 | collision_layer = 2 19 | collision_mask = 8295 20 | mass = 0.38 21 | sleeping = true 22 | 23 | [node name="CollisionShape3D" type="CollisionShape3D" parent="."] 24 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.061, 0) 25 | shape = SubResource("CylinderShape3D_vpalr") 26 | 27 | [node name="MeshInstance3D" type="MeshInstance3D" parent="CollisionShape3D"] 28 | mesh = SubResource("CylinderMesh_gk3pp") 29 | -------------------------------------------------------------------------------- /project/src/CannedColaSoda/standard_material.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="StandardMaterial3D" format=3 uid="uid://qu667h24wu1g"] 2 | 3 | [resource] 4 | albedo_color = Color(0, 1, 0, 1) 5 | -------------------------------------------------------------------------------- /project/src/Mannequin/broken_body_part.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends Skeleton3D 6 | 7 | signal hit(collider : Node, origin : Vector3, angle : Vector3, force : float, bullet_type : int) 8 | 9 | var _broken_part := -1 10 | var _mount_bone : PhysicalBone3D = null 11 | var _is_first_show := true 12 | var _owner_npc : Node = null 13 | var _is_attached_to_parent_skeleton := true 14 | 15 | 16 | func start(owner_npc : Node, broken_part : Global.BodyPart, parent_skeleton : Skeleton3D) -> void: 17 | # Hide self until after first process event 18 | #self.hide() 19 | 20 | # Hook up signals 21 | var err = self.connect("hit", Callable(self, "_on_hit")) 22 | assert(err == OK) 23 | 24 | _owner_npc = owner_npc 25 | _broken_part = broken_part 26 | 27 | var parent_mount_bone := Global.get_skeleton_mount_bone(parent_skeleton, _broken_part) 28 | 29 | _mount_bone = Global.get_skeleton_mount_bone(self, _broken_part) 30 | var animation_bones = Global.get_skeleton_animation_bones(self, _broken_part) 31 | 32 | # Move the skeleton and mount to the parent mount location 33 | _mount_bone.global_transform = parent_mount_bone.global_transform# + parent_mount_bone.body_offset.origin 34 | self.global_transform = parent_skeleton.global_transform 35 | 36 | # Move physical bones to location of animation bones 37 | for entry in Global.body_parts_2_animation_bones(Global.enum_all_values(Global.BodyPart)): 38 | var physical_bone = self.get_node_or_null("Physical Bone %s" % [entry]) 39 | if physical_bone: 40 | var bone_id = self.find_bone(entry) 41 | physical_bone.global_transform = self.get_bone_global_pose(bone_id) 42 | physical_bone.global_transform.origin += self.global_transform.origin 43 | 44 | # Remove all non broken part physical bones 45 | for entry in Global.body_parts_2_animation_bones(Global.enum_all_values(Global.BodyPart)): 46 | if not animation_bones.has(entry): 47 | var physical_bone = self.get_node_or_null("Physical Bone %s" % [entry]) 48 | if physical_bone: 49 | physical_bone.queue_free() 50 | 51 | # Start ragdolling and turn gravity back on 52 | for child in self.get_children(): 53 | if child is PhysicalBone3D: 54 | child.gravity_scale = 1.0 55 | self.physical_bones_start_simulation() 56 | 57 | # Tuck all animation bones that are not removed into mount bone 58 | var trans := _mount_bone.global_transform 59 | trans.origin -= self.global_transform.origin 60 | trans = Global.transform_shrink(trans, 0.001) 61 | for entry in Global.body_parts_2_animation_bones(Global.enum_all_values(Global.BodyPart)): 62 | if not animation_bones.has(entry): 63 | var bone_id := self.find_bone(entry) 64 | self.set_bone_global_pose_override(bone_id, trans, 1.0, true) 65 | 66 | func _on_hit(collider : Node, origin : Vector3, angle : Vector3, force : float, bullet_type : int) -> void: 67 | # Forward hit to NPC with body part info 68 | var name := collider.name.trim_prefix("Physical Bone ") 69 | var body_part := Global.physical_bone_2_body_part(name) 70 | 71 | if _owner_npc == null or not is_instance_valid(_owner_npc): 72 | _owner_npc = null 73 | 74 | if _is_attached_to_parent_skeleton and _owner_npc != null: 75 | _owner_npc.emit_signal("hit_body_part", collider, body_part, origin, angle, force, bullet_type) 76 | else: 77 | collider.apply_central_impulse(angle * force) 78 | 79 | func _process(_delta : float) -> void: 80 | # Move skeleton position to mount location 81 | self.global_transform.origin = _mount_bone.global_transform.origin 82 | 83 | # Show self if end of first process event 84 | if _is_first_show: 85 | #self.show() 86 | _is_first_show = false 87 | -------------------------------------------------------------------------------- /project/src/Mannequin/mannequin.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends Node3D 6 | 7 | signal hit(collider : Node, origin : Vector3, angle : Vector3, force : float, bullet_type : int) 8 | 9 | var _physics_skeleton : Skeleton3D = null 10 | 11 | var is_ragdoll := false 12 | var _bone_names := [] 13 | var _body_part_status := {} 14 | 15 | func _ready() -> void: 16 | # Setup duplication flags to get everything except scripts 17 | var flags := 0 18 | flags += DUPLICATE_SIGNALS 19 | flags += DUPLICATE_GROUPS 20 | #flags += DUPLICATE_SCRIPTS 21 | flags += DUPLICATE_USE_INSTANTIATION 22 | 23 | # Duplicate the animation skeleton into a new one for physics 24 | var animation_skeleton = $Armature/Skeleton3D 25 | var physics_skeleton = animation_skeleton.duplicate(flags) 26 | physics_skeleton.name = "PhysicsSkeleton3D" 27 | _physics_skeleton = physics_skeleton 28 | 29 | # Remove all the parts no longer needed from the animation skeleton 30 | for child in animation_skeleton.get_children(): 31 | if child is PhysicalBone3D or child is BoneAttachment3D or child is MeshInstance3D: 32 | child.queue_free() 33 | 34 | # Set the script on the physics skeleton 35 | var script := load("res://src/Mannequin/physics_skeleton.gd") 36 | physics_skeleton.set_script(script) 37 | physics_skeleton._animation_skeleton = animation_skeleton 38 | physics_skeleton._is_syncing = false 39 | 40 | $Armature.add_child(physics_skeleton) 41 | 42 | # Set the skeleton's children to have the same owner as the original 43 | for child in Global.recursively_get_all_children(physics_skeleton): 44 | if child != physics_skeleton: 45 | child.owner = animation_skeleton.owner 46 | 47 | physics_skeleton._is_syncing = true 48 | 49 | # Init lookup tables of body parts 50 | for part in Global.BodyPart.values(): 51 | _body_part_status[part] = Global.BodyPartStatus.Normal 52 | 53 | # Get a list of all bone names that have a physical and animation bone 54 | var total := _physics_skeleton.get_bone_count() 55 | #print(total) 56 | for i in total: 57 | var entry := _physics_skeleton.get_bone_name(i) 58 | #print(entry) 59 | if _physics_skeleton.has_node("Physical Bone %s" % [entry]): 60 | _bone_names.append(entry) 61 | #print(_bone_names) 62 | 63 | func _on_hit(collider : Node, origin : Vector3, angle : Vector3, force : float, bullet_type : int) -> void: 64 | # Forward hit to NPC with body part info 65 | var name := collider.name.trim_prefix("Physical Bone ") 66 | var body_part := Global.physical_bone_2_body_part(name) 67 | self.owner.emit_signal("hit_body_part", collider, body_part, origin, angle, force, bullet_type) 68 | 69 | # FIXME: This should only need to be done once on ragdoll start 70 | func _process(_delta : float) -> void: 71 | if not is_ragdoll: return 72 | 73 | # Get the location of the spine animation bone 74 | var mount_id := _physics_skeleton.find_bone(Global.bone_names[Global.BodyPart.TorsoMiddle][0]) 75 | var trans := _physics_skeleton.get_bone_global_pose(mount_id) 76 | trans = Global.transform_shrink(trans, 0.001) 77 | 78 | # Get all broken body parts 79 | var to_tuck := 0 80 | for part in Global.BodyPart: 81 | var body_part = Global.BodyPart[part] 82 | if _body_part_status[body_part] != Global.BodyPartStatus.Normal: 83 | to_tuck |= body_part 84 | 85 | # Tuck all animation bones that attach to broken body parts 86 | var animation_bones = Global.body_parts_2_animation_bones(to_tuck) 87 | for entry in animation_bones: 88 | var bone_id := _physics_skeleton.find_bone(entry) 89 | _physics_skeleton.set_bone_global_pose_override(bone_id, trans, 1.0, true) 90 | 91 | func push_at_angle(angle : Vector3, force : float) -> void: 92 | # Get the physical bones of all the large parts 93 | var bones := [] 94 | for entry in Global.body_parts_2_animation_bones(Global.enum_all_values(Global.BodyPart)): 95 | var physical_bone = _physics_skeleton.get_node_or_null("Physical Bone %s" % [entry]) 96 | if physical_bone: 97 | bones.append(physical_bone) 98 | 99 | # Fling the physical bones 100 | force = force / float(bones.size()) 101 | for bone in bones: 102 | bone.apply_central_impulse(angle * force) 103 | 104 | func set_body_part_status(body_part : Global.BodyPart, status : Global.BodyPartStatus) -> void: 105 | # Just return if the current part status is worse than the new body part status 106 | var prev_status = self._body_part_status[body_part] 107 | if prev_status >= status: return 108 | 109 | # Update the body part status and any connected parts 110 | match body_part: 111 | Global.BodyPart.Head: 112 | self._body_part_status[Global.BodyPart.Head] = status 113 | Global.BodyPart.TorsoUpper, Global.BodyPart.TorsoMiddle, Global.BodyPart.TorsoLower: 114 | self._body_part_status[Global.BodyPart.TorsoUpper] = status 115 | self._body_part_status[Global.BodyPart.TorsoMiddle] = status 116 | self._body_part_status[Global.BodyPart.TorsoLower] = status 117 | Global.BodyPart.Pelvis: 118 | self._body_part_status[Global.BodyPart.Pelvis] = status 119 | Global.BodyPart.UpperArmR, Global.BodyPart.LowerArmR, Global.BodyPart.HandR: 120 | self._body_part_status[Global.BodyPart.UpperArmR] = status 121 | self._body_part_status[Global.BodyPart.LowerArmR] = status 122 | self._body_part_status[Global.BodyPart.HandR] = status 123 | Global.BodyPart.UpperArmL, Global.BodyPart.LowerArmL, Global.BodyPart.HandL: 124 | self._body_part_status[Global.BodyPart.UpperArmL] = status 125 | self._body_part_status[Global.BodyPart.LowerArmL] = status 126 | self._body_part_status[Global.BodyPart.HandL] = status 127 | Global.BodyPart.UpperLegR, Global.BodyPart.LowerLegR, Global.BodyPart.FootR: 128 | self._body_part_status[Global.BodyPart.UpperLegR] = status 129 | self._body_part_status[Global.BodyPart.LowerLegR] = status 130 | self._body_part_status[Global.BodyPart.FootR] = status 131 | Global.BodyPart.UpperLegL, Global.BodyPart.LowerLegL, Global.BodyPart.FootL: 132 | self._body_part_status[Global.BodyPart.UpperLegL] = status 133 | self._body_part_status[Global.BodyPart.LowerLegL] = status 134 | self._body_part_status[Global.BodyPart.FootL] = status 135 | _: 136 | push_error("Unexpected Global.BodyPart: %s" % [body_part]) 137 | return 138 | 139 | # Change the body part to crippled or destroyed 140 | match self._body_part_status[body_part]: 141 | Global.BodyPartStatus.Normal: 142 | pass 143 | Global.BodyPartStatus.Crippled: 144 | self._set_body_part_crippled(body_part) 145 | Global.BodyPartStatus.Destroyed: 146 | if prev_status == Global.BodyPartStatus.Normal: 147 | self._set_body_part_crippled(body_part) 148 | self._set_body_part_destroyed(body_part) 149 | _: 150 | push_error("Unexpected Global.BodyPartStatus: %s" % [body_part]) 151 | 152 | 153 | func _set_body_part_crippled(body_part : Global.BodyPart) -> void: 154 | # Figure out where to mount the crippled body part 155 | var tuck_bone_id := Global.get_skeleton_tuck_bone(_physics_skeleton, body_part) 156 | var to_hide := Global.get_skeleton_animation_bones(_physics_skeleton, body_part) 157 | 158 | # Duplicate the body part and attach it to the mount 159 | var broken_skeleton = self._duplicate_body_part_into_own_skeleton(body_part) 160 | #broken_skeleton._mount_bone.apply_central_impulse(angle * force) 161 | 162 | # Hide the original body part 163 | self._hide_body_part(to_hide, tuck_bone_id) 164 | 165 | func _set_body_part_destroyed(body_part : Global.BodyPart) -> void: 166 | # Disconnect the body part from the mount 167 | var pin_joint = null 168 | match body_part: 169 | Global.BodyPart.Head: 170 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorNeck/Anchor/PinJoint3D 171 | Global.BodyPart.UpperArmR: 172 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorRightShoulder/Anchor/PinJoint3D 173 | Global.BodyPart.UpperArmL: 174 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorLeftShoulder/Anchor/PinJoint3D 175 | Global.BodyPart.UpperLegR: 176 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorRightHip/Anchor/PinJoint3D 177 | Global.BodyPart.UpperLegL: 178 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorLeftHip/Anchor/PinJoint3D 179 | _: 180 | pass 181 | 182 | if pin_joint: 183 | var broken_skeleton = get_node(pin_joint.node_b).owner 184 | broken_skeleton._is_attached_to_parent_skeleton = false 185 | pin_joint.node_b = NodePath() 186 | 187 | func _hide_body_part(to_hide : Array, tuck_bone_id : int) -> void: 188 | # Hide animation bones by shrinking and tucking them inside the tuck bone 189 | # and removing physical bones 190 | var trans := _physics_skeleton.get_bone_global_pose(tuck_bone_id) 191 | trans = Global.transform_shrink(trans, 0.0001) 192 | for entry in to_hide: 193 | var bone_id := _physics_skeleton.find_bone(entry) 194 | _physics_skeleton.set_bone_global_pose_override(bone_id, trans, 1.0, true) 195 | var bone := _physics_skeleton.get_node_or_null("Physical Bone %s" % [entry]) 196 | if bone: 197 | bone.collision_layer = 0 198 | bone.collision_mask = 0 199 | bone.get_parent().remove_child(bone) 200 | bone.queue_free() 201 | 202 | func _duplicate_body_part_into_own_skeleton(body_part : Global.BodyPart) -> Skeleton3D: 203 | # Duplicate the skeleton without attached signals 204 | var flags := 0 205 | #flags += DUPLICATE_SIGNALS 206 | flags += DUPLICATE_GROUPS 207 | #flags += DUPLICATE_SCRIPTS 208 | flags += DUPLICATE_USE_INSTANTIATION 209 | var skeleton = _physics_skeleton.duplicate(flags) 210 | 211 | # Remove any bone attachments 212 | for child in Global.recursively_get_all_children(skeleton): 213 | if child is BoneAttachment3D: 214 | child.get_parent().remove_child(child) 215 | child.queue_free() 216 | 217 | # Set the skeleton to owner of all its child nodes 218 | for child in Global.recursively_get_all_children(skeleton): 219 | if child != skeleton: 220 | child.owner = skeleton 221 | 222 | # Have bones stop reacting to physics 223 | skeleton.physical_bones_stop_simulation() 224 | for child in skeleton.get_children(): 225 | if child is PhysicalBone3D: 226 | child.gravity_scale = 0.0 227 | 228 | # Set position 229 | Global._world.add_child(skeleton) 230 | #skeleton.global_transform = _physics_skeleton.global_transform # FIXME: Do we need this? 231 | #skeleton.global_rotation = _physics_skeleton.global_rotation # FIXME: Do we need this? 232 | 233 | # Add script 234 | var script = load("res://src/Mannequin/broken_body_part.gd") 235 | skeleton.set_script(script) 236 | skeleton.start(self.owner, body_part, _physics_skeleton) 237 | 238 | var pin_joint : PinJoint3D = null 239 | var anchor : StaticBody3D = null 240 | 241 | match body_part: 242 | Global.BodyPart.Head: 243 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorNeck/Anchor/PinJoint3D 244 | anchor = $Armature/PhysicsSkeleton3D/AnchorNeck/Anchor 245 | Global.BodyPart.UpperArmR: 246 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorRightShoulder/Anchor/PinJoint3D 247 | anchor = $Armature/PhysicsSkeleton3D/AnchorRightShoulder/Anchor 248 | Global.BodyPart.UpperArmL: 249 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorLeftShoulder/Anchor/PinJoint3D 250 | anchor = $Armature/PhysicsSkeleton3D/AnchorLeftShoulder/Anchor 251 | Global.BodyPart.UpperLegR: 252 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorRightHip/Anchor/PinJoint3D 253 | anchor = $Armature/PhysicsSkeleton3D/AnchorRightHip/Anchor 254 | Global.BodyPart.UpperLegL: 255 | pin_joint = $Armature/PhysicsSkeleton3D/AnchorLeftHip/Anchor/PinJoint3D 256 | anchor = $Armature/PhysicsSkeleton3D/AnchorLeftHip/Anchor 257 | _: 258 | pass 259 | 260 | # Move the PinJoint and Skeleton to anchor location, and pin Skeleton to anchor 261 | if pin_joint and anchor: 262 | skeleton.global_transform.origin = anchor.global_transform.origin 263 | skeleton._mount_bone.global_transform.origin = anchor.global_transform.origin - skeleton._mount_bone.body_offset.origin 264 | pin_joint.node_b = skeleton._mount_bone.get_path() 265 | 266 | return skeleton 267 | 268 | func _start_ragdoll() -> void: 269 | $AnimationPlayer.stop() 270 | is_ragdoll = true 271 | 272 | for child in _physics_skeleton.get_children(): 273 | if child is PhysicalBone3D: 274 | child.gravity_scale = 1.0 275 | _physics_skeleton._is_syncing = false 276 | 277 | func _stop_ragdoll() -> void: 278 | $AnimationPlayer.play("idle") 279 | is_ragdoll = false 280 | 281 | for child in _physics_skeleton.get_children(): 282 | if child is PhysicalBone3D: 283 | child.gravity_scale = 0.0 284 | _physics_skeleton._is_syncing = true 285 | -------------------------------------------------------------------------------- /project/src/Mannequin/mannequin.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=31 format=3 uid="uid://dpkf4sjfur2by"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://i3t8kiv0jfxl" path="res://assets/mannequin/mannequin.glb" id="1_qtyj3"] 4 | [ext_resource type="Script" path="res://src/Mannequin/mannequin.gd" id="2_6m6pc"] 5 | 6 | [sub_resource type="SphereShape3D" id="SphereShape3D_ctvsv"] 7 | radius = 0.001 8 | 9 | [sub_resource type="SphereShape3D" id="SphereShape3D_wns6n"] 10 | radius = 0.001 11 | 12 | [sub_resource type="SphereShape3D" id="SphereShape3D_ccon2"] 13 | radius = 0.001 14 | 15 | [sub_resource type="SphereShape3D" id="SphereShape3D_dhq6f"] 16 | radius = 0.01 17 | 18 | [sub_resource type="CylinderMesh" id="CylinderMesh_0nwn6"] 19 | top_radius = 0.1 20 | bottom_radius = 0.1 21 | height = 1.0 22 | 23 | [sub_resource type="SphereShape3D" id="SphereShape3D_jps1h"] 24 | radius = 0.001 25 | 26 | [sub_resource type="BoxMesh" id="BoxMesh_k13tw"] 27 | size = Vector3(0.5, 0.5, 0.5) 28 | 29 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_gniu7"] 30 | height = 0.105176 31 | radius = 0.143702 32 | 33 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_mcb4c"] 34 | height = 0.0896446 35 | radius = 0.144312 36 | 37 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_gh660"] 38 | height = 0.165391 39 | radius = 0.139566 40 | 41 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_y6twj"] 42 | height = 0.103767 43 | radius = 0.0585105 44 | 45 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_3nmod"] 46 | height = 0.0696775 47 | radius = 0.0367377 48 | 49 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_7ywly"] 50 | radius = 0.0937323 51 | height = 0.204031 52 | 53 | [sub_resource type="BoxShape3D" id="BoxShape3D_acp8j"] 54 | size = Vector3(0.0739449, 0.10008, 0.0840425) 55 | 56 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_p5cwv"] 57 | radius = 0.0505633 58 | height = 0.274047 59 | 60 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_nclj6"] 61 | radius = 0.0376292 62 | height = 0.276145 63 | 64 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_87825"] 65 | height = 0.0471939 66 | radius = 0.0571291 67 | 68 | [sub_resource type="BoxShape3D" id="BoxShape3D_aq1ss"] 69 | size = Vector3(0.0965899, 0.0998077, 0.0928991) 70 | 71 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_bxuej"] 72 | radius = 0.0535265 73 | height = 0.274047 74 | 75 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_fe61b"] 76 | radius = 0.0363751 77 | height = 0.276145 78 | 79 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_uygg8"] 80 | radius = 0.0832084 81 | height = 0.405994 82 | 83 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_kqje8"] 84 | radius = 0.0540956 85 | height = 0.42099 86 | 87 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_tfce0"] 88 | radius = 0.0157216 89 | height = 0.157216 90 | 91 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_bqmwm"] 92 | radius = 0.01 93 | height = 0.1 94 | 95 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_e8j4g"] 96 | radius = 0.0856494 97 | height = 0.405995 98 | 99 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_j0edi"] 100 | radius = 0.0521317 101 | height = 0.42099 102 | 103 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_3t23u"] 104 | radius = 0.0157216 105 | height = 0.157216 106 | 107 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_hw4c3"] 108 | radius = 0.01 109 | height = 0.1 110 | 111 | [node name="Mannequin" instance=ExtResource("1_qtyj3")] 112 | script = ExtResource("2_6m6pc") 113 | 114 | [node name="Skeleton3D" parent="Armature" index="0"] 115 | bones/0/rest = Transform3D(0.992982, 0.0492359, -0.107528, -0.0634908, 0.989019, -0.133454, 0.0997762, 0.139344, 0.985205, 0.00433382, 0.920002, 0.00816268) 116 | bones/0/position = Vector3(0.000864754, 0.979796, 0.0027928) 117 | bones/0/rotation = Quaternion(-0.0132648, -0.00104366, -0.00969562, 0.999865) 118 | bones/1/rest = Transform3D(0.968258, -0.0396657, 0.246786, 0.0672868, 0.992244, -0.104515, -0.240726, 0.117803, 0.963418, 8.59785e-06, 0.0992346, -0.0122733) 119 | bones/1/position = Vector3(8.59785e-06, 0.0992346, -0.0122733) 120 | bones/1/rotation = Quaternion(-0.0522968, -0.0011733, 0.000499752, 0.998631) 121 | bones/1/scale = Vector3(1, 1, 1) 122 | bones/2/rest = Transform3D(0.999243, -0.0270564, 0.0279495, 0.0253651, 0.997924, 0.0591904, -0.029493, -0.0584366, 0.997855, -1.95087e-12, 0.11732, -4.60178e-09) 123 | bones/2/position = Vector3(-1.95087e-12, 0.11732, -4.60178e-09) 124 | bones/2/rotation = Quaternion(0.00907353, -0.0216085, -0.0015535, 0.999724) 125 | bones/3/rest = Transform3D(0.99929, -0.0214758, 0.0309679, 0.0232042, 0.998129, -0.0565769, -0.0296949, 0.0572553, 0.997918, -2.00089e-12, 0.134588, 5.08745e-09) 126 | bones/3/position = Vector3(-2.00089e-12, 0.134588, 5.08745e-09) 127 | bones/3/rotation = Quaternion(0.0665062, -0.0216552, 9.20555e-05, 0.997551) 128 | bones/3/scale = Vector3(1, 1, 1) 129 | bones/4/rest = Transform3D(0.997638, 0.0532975, -0.0433327, -0.0567198, 0.995016, -0.0820153, 0.0387455, 0.0842794, 0.995689, 2.54798e-07, 0.150278, 0.00877904) 130 | bones/4/position = Vector3(2.54798e-07, 0.150278, 0.00877904) 131 | bones/4/rotation = Quaternion(-0.021263, 0.00741841, -0.0126164, 0.999667) 132 | bones/5/rest = Transform3D(0.993236, 0.00489484, -0.116011, 0.0346648, 0.941048, 0.336491, 0.110819, -0.338236, 0.934513, 2.56128e-08, 0.103218, 0.0314243) 133 | bones/5/position = Vector3(2.56128e-08, 0.103218, 0.0314243) 134 | bones/5/rotation = Quaternion(0.0481957, -0.0148507, 0.0315465, 0.998229) 135 | bones/5/scale = Vector3(1, 0.999999, 1) 136 | bones/7/rest = Transform3D(-0.0556941, 0.99427, -0.0912488, 0.0700884, -0.087272, -0.993716, -0.995985, -0.0617397, -0.0648263, 0.0610582, 0.0910627, 0.0075706) 137 | bones/7/position = Vector3(0.0610582, 0.0910627, 0.0075706) 138 | bones/7/rotation = Quaternion(0.418044, 0.568408, -0.582747, 0.403183) 139 | bones/7/scale = Vector3(1, 1, 1) 140 | bones/8/rest = Transform3D(0.479872, 0.703059, 0.524815, 0.0138178, 0.592059, -0.805776, -0.87723, 0.393921, 0.274398, 2.98023e-09, 0.129223, 5.22498e-08) 141 | bones/8/position = Vector3(2.98023e-09, 0.129223, 5.22498e-08) 142 | bones/8/rotation = Quaternion(0.542212, 0.197372, 0.240104, 0.780641) 143 | bones/8/scale = Vector3(1, 1, 1) 144 | bones/9/rest = Transform3D(0.30236, -0.953194, 9.60321e-08, 0.953194, 0.30236, -1.44795e-06, 1.35114e-06, 5.29339e-07, 1, -7.44901e-08, 0.274047, 1.72864e-08) 145 | bones/9/position = Vector3(-2.08459e-08, 0.274047, -1.2516e-08) 146 | bones/9/rotation = Quaternion(5.82854e-07, -1.6252e-07, 0.252872, 0.9675) 147 | bones/10/rest = Transform3D(0.98425, 0.0629889, -0.165181, -0.0689683, 0.997146, -0.030711, 0.162775, 0.0416195, 0.985785, -7.04833e-09, 0.276145, 9.73436e-09) 148 | bones/10/position = Vector3(-7.04833e-09, 0.276145, 9.73436e-09) 149 | bones/10/rotation = Quaternion(0.10677, 0.0583462, -0.127069, 0.984403) 150 | bones/11/rest = Transform3D(0.913927, -0.402679, -0.0508596, 0.350018, 0.845374, -0.403522, 0.205485, 0.350988, 0.913555, -0.0300297, 0.0378883, 0.0216716) 151 | bones/11/position = Vector3(-0.0300297, 0.0378883, 0.0216716) 152 | bones/11/rotation = Quaternion(0.172847, -0.17402, 0.140126, 0.959274) 153 | bones/11/scale = Vector3(1, 1, 1) 154 | bones/12/rest = Transform3D(0.987964, 0.15468, 0.0012732, -0.154674, 0.987761, 0.0200814, 0.00184857, -0.0200366, 0.999797, 9.2387e-09, 0.0474497, 1.15657e-07) 155 | bones/12/position = Vector3(-3.57616e-09, 0.0474497, 1.31376e-07) 156 | bones/12/rotation = Quaternion(-0.0212241, 0.0257346, -0.139646, 0.989639) 157 | bones/12/scale = Vector3(1, 1, 0.999999) 158 | bones/13/rest = Transform3D(0.999807, 0.0196602, 0.000345571, -0.0196532, 0.998582, 0.0494769, 0.000627643, -0.0494741, 0.998775, 3.33786e-08, 0.0438213, 5.38779e-08) 159 | bones/13/position = Vector3(2.74182e-08, 0.0438213, 6.19422e-09) 160 | bones/13/rotation = Quaternion(-0.0277218, 0.000143316, -0.018311, 0.999448) 161 | bones/13/scale = Vector3(1, 1, 1) 162 | bones/14/rest = Transform3D(0.958042, -0.140321, 0.249933, 0.144917, 0.989444, 1.1405e-05, -0.247297, 0.0362088, 0.968263, -7.39098e-08, 0.0345907, 6.28127e-08) 163 | bones/14/position = Vector3(-7.39098e-08, 0.0345907, 6.28127e-08) 164 | bones/14/rotation = Quaternion(0.00914615, 0.125638, 0.0720724, 0.989412) 165 | bones/14/scale = Vector3(1, 1, 1) 166 | bones/15/rest = Transform3D(0.999922, 0.012502, -0.000649455, -0.012502, 0.994541, -0.103592, -0.000649196, 0.103592, 0.99462, -0.0282204, 0.122666, 0.00231821) 167 | bones/15/rotation = Quaternion(0.183254, -0.00230831, -0.00963271, 0.983016) 168 | bones/16/rest = Transform3D(0.99967, 0.0255524, -0.00273664, -0.0255524, 0.976994, -0.211731, -0.00273655, 0.211731, 0.977324, -1.53992e-09, 0.0389197, 4.79037e-08) 169 | bones/16/position = Vector3(-1.53992e-09, 0.0389197, 4.79037e-08) 170 | bones/16/rotation = Quaternion(0.304104, -3.22856e-07, -0.0366996, 0.951932) 171 | bones/17/rest = Transform3D(0.99998, 0.00625929, -0.00016248, -0.00625929, 0.998634, -0.0518672, -0.000162394, 0.0518672, 0.998654, -9.94696e-10, 0.0341517, -5.35869e-08) 172 | bones/17/position = Vector3(-9.94696e-10, 0.0341517, -5.35869e-08) 173 | bones/17/rotation = Quaternion(0.150609, -1.5323e-07, -0.0181755, 0.988426) 174 | bones/19/rest = Transform3D(0.999922, 0.0124674, -0.000645659, -0.0124674, 0.994571, -0.103312, -0.000645879, 0.103312, 0.994649, -1.27144e-07, 0.127755, -7.93744e-08) 175 | bones/19/rotation = Quaternion(0.235741, -0.00216677, -0.0194892, 0.971618) 176 | bones/20/rest = Transform3D(0.999669, 0.0255851, -0.00274391, -0.0255851, 0.976933, -0.212007, -0.0027436, 0.212007, 0.977264, -4.63109e-09, 0.0361397, -2.15956e-08) 177 | bones/20/rotation = Quaternion(0.20694, -2.24014e-07, -0.0249735, 0.978035) 178 | bones/21/rest = Transform3D(0.99998, 0.00625937, -0.000162457, -0.00625937, 0.998634, -0.0518681, -0.000162427, 0.0518681, 0.998654, 2.80911e-07, 0.0345977, 2.31727e-08) 179 | bones/21/position = Vector3(2.80911e-07, 0.0345977, 2.31727e-08) 180 | bones/21/rotation = Quaternion(0.128979, -2.20731e-08, -0.0155652, 0.991525) 181 | bones/22/rest = Transform3D(0.999957, 0.00130825, 0.00915879, -0.00130827, 0.999999, -3.68971e-06, -0.00915879, -8.29265e-06, 0.999958, -3.06105e-07, 0.036802, 2.62024e-08) 182 | bones/22/position = Vector3(-3.06105e-07, 0.036802, 2.62024e-08) 183 | bones/22/rotation = Quaternion(-1.15075e-06, 0.00457945, -0.000654137, 0.999989) 184 | bones/22/scale = Vector3(1, 1, 1) 185 | bones/23/rest = Transform3D(0.999922, 0.0125005, -0.000649168, -0.0125005, 0.994542, -0.103589, -0.00064929, 0.103589, 0.99462, 0.0221664, 0.12147, -9.99714e-05) 186 | bones/23/rotation = Quaternion(0.28784, -0.00607675, -0.0143491, 0.957552) 187 | bones/24/rest = Transform3D(0.99967, 0.0255527, -0.00273676, -0.0255527, 0.976993, -0.211736, -0.00273663, 0.211736, 0.977323, 1.8882e-10, 0.0360118, -1.22717e-09) 188 | bones/24/position = Vector3(1.8882e-10, 0.0360118, -1.22717e-09) 189 | bones/24/rotation = Quaternion(0.149959, -1.08934e-07, -0.0180972, 0.988527) 190 | bones/24/scale = Vector3(1, 1, 1) 191 | bones/25/rest = Transform3D(0.999811, 0.0194016, -0.00156972, -0.0194016, 0.986801, -0.160772, -0.00157024, 0.160772, 0.98699, -3.38405e-10, 0.0330732, 4.92989e-08) 192 | bones/25/position = Vector3(-3.38405e-10, 0.0330732, 4.92989e-08) 193 | bones/25/rotation = Quaternion(0.0958666, 1.71525e-07, -0.0115691, 0.995327) 194 | bones/26/rest = Transform3D(0.999889, -0.00154095, 0.0147921, 0.00154121, 0.999999, -6.38458e-06, -0.014792, 2.91816e-05, 0.99989, -2.40928e-07, 0.0366012, 1.77123e-07) 195 | bones/26/rotation = Quaternion(8.89179e-06, 0.00739621, 0.000770561, 0.999972) 196 | bones/26/scale = Vector3(1, 1, 0.999999) 197 | bones/27/rest = Transform3D(0.996535, 0.0831714, -0.000222986, -0.0828183, 0.992051, -0.0947406, -0.00765849, 0.0944308, 0.995502, 0.0472584, 0.109082, 0.0022613) 198 | bones/27/rotation = Quaternion(0.395668, 0.00775074, -0.0655971, 0.916015) 199 | bones/27/scale = Vector3(1, 1, 1) 200 | bones/28/rest = Transform3D(0.998974, -0.0435196, 0.012547, 0.0452147, 0.974432, -0.220087, -0.00264806, 0.220429, 0.975399, 4.74426e-09, 0.0413666, -1.81309e-08) 201 | bones/28/position = Vector3(4.74426e-09, 0.0413666, -1.81309e-08) 202 | bones/28/rotation = Quaternion(0.187141, 0.0065668, 0.0127117, 0.982229) 203 | bones/28/scale = Vector3(1, 1, 0.999999) 204 | bones/29/rest = Transform3D(0.999811, 0.0194004, -0.0015688, -0.0194002, 0.9868, -0.160775, -0.001571, 0.160775, 0.98699, -2.59599e-09, 0.0259483, 2.51457e-08) 205 | bones/29/position = Vector3(-2.59599e-09, 0.0259483, 2.51457e-08) 206 | bones/29/rotation = Quaternion(0.0668004, 5.86286e-07, -0.00806044, 0.997734) 207 | bones/30/rest = Transform3D(0.999966, 0.00115073, 0.0081991, -0.00115078, 0.999999, 1.00235e-06, -0.0081991, -1.04376e-05, 0.999966, 5.27616e-10, 0.0292388, 7.99598e-08) 208 | bones/30/position = Vector3(6.4249e-09, 0.0292387, -5.24151e-08) 209 | bones/30/rotation = Quaternion(-2.86e-06, 0.00409959, -0.000575383, 0.999991) 210 | bones/31/rest = Transform3D(-0.117912, -0.988704, 0.092525, -0.0487526, -0.0872989, -0.994989, 0.991827, -0.121832, -0.0379083, -0.061057, 0.0910636, 0.00757074) 211 | bones/31/position = Vector3(-0.061057, 0.0910636, 0.00757074) 212 | bones/31/rotation = Quaternion(0.451353, -0.553943, 0.522429, 0.465291) 213 | bones/31/scale = Vector3(1, 1, 1) 214 | bones/32/rest = Transform3D(0.90875, 0.395561, -0.133057, -0.351833, 0.55465, -0.75404, -0.224469, 0.732048, 0.64321, 9.74363e-09, 0.129223, 3.00286e-07) 215 | bones/32/position = Vector3(5.77091e-09, 0.129223, 9.2161e-08) 216 | bones/32/rotation = Quaternion(0.56579, -0.175942, -0.266195, 0.760306) 217 | bones/32/scale = Vector3(1, 1, 1) 218 | bones/33/rest = Transform3D(-0.0426044, 0.999092, 1.54354e-07, -0.999092, -0.0426044, -5.69017e-07, -5.61924e-07, -1.78456e-07, 1, 2.92521e-09, 0.274047, -2.97836e-08) 219 | bones/33/position = Vector3(2.92521e-09, 0.274047, -2.97836e-08) 220 | bones/33/rotation = Quaternion(1.92523e-07, 6.74849e-08, -0.23426, 0.972174) 221 | bones/34/rest = Transform3D(0.968083, 0.00866809, 0.25048, -0.099094, 0.931206, 0.350764, -0.230208, -0.36439, 0.902344, 1.65044e-07, 0.276145, 1.12523e-07) 222 | bones/34/position = Vector3(1.36433e-07, 0.276145, 1.57823e-07) 223 | bones/34/rotation = Quaternion(0.00940975, 0.0183944, 0.128578, 0.991484) 224 | bones/35/rest = Transform3D(0.956894, 0.285969, 0.0507469, -0.26303, 0.927361, -0.266114, -0.123161, 0.241295, 0.962605, 0.0300297, 0.037888, 0.0216716) 225 | bones/35/position = Vector3(0.0300297, 0.037888, 0.0216716) 226 | bones/35/rotation = Quaternion(0.188905, 0.0366169, -0.0194748, 0.981119) 227 | bones/35/scale = Vector3(1, 1, 1) 228 | bones/36/rest = Transform3D(0.987121, -0.155686, -0.0368023, 0.158311, 0.983753, 0.084662, 0.0230237, -0.0893978, 0.99573, 3.03984e-08, 0.0474495, -1.81691e-07) 229 | bones/36/position = Vector3(3.03984e-08, 0.0474495, -1.81691e-07) 230 | bones/36/rotation = Quaternion(0.0202571, -0.0428732, 0.0153664, 0.998757) 231 | bones/36/scale = Vector3(1, 1, 1) 232 | bones/37/rest = Transform3D(0.999738, 0.0200436, -0.0110117, -0.0190984, 0.996603, 0.0801084, 0.01258, -0.0798772, 0.996725, -2.861e-08, 0.0438214, 3.07079e-09) 233 | bones/37/rotation = Quaternion(-0.0281114, -0.00134628, -0.0167768, 0.999463) 234 | bones/37/scale = Vector3(0.999999, 1, 1) 235 | bones/38/rest = Transform3D(0.957213, 0.140747, -0.252852, -0.145442, 0.989367, 0.00012501, 0.250181, 0.0366556, 0.967505, 2.18443e-07, 0.0345907, -1.92875e-07) 236 | bones/38/rotation = Quaternion(0.00923234, -0.127131, -0.0723282, 0.989202) 237 | bones/39/rest = Transform3D(0.999977, -0.00675646, 0.000187348, 0.00675645, 0.998439, -0.0554458, 0.000187562, 0.0554458, 0.998462, 0.0282204, 0.122666, 0.00231843) 238 | bones/39/position = Vector3(0.0282204, 0.122666, 0.0023183) 239 | bones/39/rotation = Quaternion(0.0963759, -0.00335106, 0.0449444, 0.994324) 240 | bones/39/scale = Vector3(1, 1, 1) 241 | bones/40/rest = Transform3D(0.999384, -0.034715, 0.00505125, 0.0347151, 0.957939, -0.284863, 0.00505022, 0.284863, 0.958555, -1.19417e-10, 0.0389196, -6.56542e-08) 242 | bones/40/position = Vector3(-1.19417e-10, 0.0389196, -6.56542e-08) 243 | bones/40/rotation = Quaternion(0.329634, 1.94014e-07, 0.0401714, 0.943254) 244 | bones/40/scale = Vector3(0.999999, 1, 1) 245 | bones/41/rest = Transform3D(0.999994, -0.00337978, 4.68998e-05, 0.00337978, 0.99961, -0.0277344, 4.68546e-05, 0.0277344, 0.999615, -3.66494e-08, 0.0341515, 3.27011e-08) 246 | bones/41/position = Vector3(1.34185e-08, 0.0341515, 4.70062e-08) 247 | bones/41/rotation = Quaternion(0.0699985, 1.31119e-07, 0.00853054, 0.997511) 248 | bones/42/rest = Transform3D(0.999906, -0.0027484, -0.0134185, 0.00275035, 0.999996, 0.000126701, 0.0134181, -0.000163594, 0.99991, 8.13816e-10, 0.0307799, -2.86758e-09) 249 | bones/42/position = Vector3(8.13816e-10, 0.0307799, -2.86758e-09) 250 | bones/42/rotation = Quaternion(-7.25753e-05, -0.00670931, 0.00137472, 0.999977) 251 | bones/42/scale = Vector3(1, 1, 1) 252 | bones/43/rest = Transform3D(0.999977, -0.00675647, 0.000187481, 0.00675647, 0.998439, -0.0554482, 0.000187446, 0.0554482, 0.998462, 6.11725e-08, 0.127755, 8.26227e-08) 253 | bones/43/position = Vector3(1.54156e-07, 0.127755, 3.25552e-08) 254 | bones/43/rotation = Quaternion(0.177003, -0.00792849, 0.0643204, 0.982074) 255 | bones/44/rest = Transform3D(0.999384, -0.0347153, 0.00505122, 0.0347154, 0.95794, -0.28486, 0.00505022, 0.28486, 0.958556, -1.6668e-08, 0.0361397, -1.63968e-08) 256 | bones/44/rotation = Quaternion(0.251778, 2.41905e-07, 0.0306836, 0.967299) 257 | bones/44/scale = Vector3(0.999999, 1, 1) 258 | bones/45/rest = Transform3D(0.999994, -0.00337971, 4.68328e-05, 0.00337971, 0.99961, -0.0277335, 4.69167e-05, 0.0277335, 0.999615, -1.58054e-07, 0.0345976, -6.05198e-08) 259 | bones/45/rotation = Quaternion(0.0466686, 0.0138785, 0.0063466, 0.998794) 260 | bones/46/rest = Transform3D(0.999905, 0.00341724, -0.01339, -0.00341588, 0.999994, 0.000124527, 0.0133904, -7.87762e-05, 0.99991, 3.46696e-07, 0.0368019, 5.41618e-08) 261 | bones/46/rotation = Quaternion(-5.0827e-05, -0.00669527, -0.00170832, 0.999976) 262 | bones/47/rest = Transform3D(0.999977, -0.00675809, 0.000187518, 0.00675809, 0.998439, -0.0554485, 0.000187501, 0.0554485, 0.998462, -0.0221663, 0.12147, -9.98432e-05) 263 | bones/47/position = Vector3(-0.0221663, 0.12147, -9.98432e-05) 264 | bones/47/rotation = Quaternion(0.254298, -0.00394204, 0.0458619, 0.96603) 265 | bones/48/rest = Transform3D(0.999384, -0.0347156, 0.0050511, 0.0347157, 0.957941, -0.284859, 0.00505039, 0.284859, 0.958556, 5.52191e-09, 0.0360119, -3.0664e-08) 266 | bones/48/position = Vector3(5.52191e-09, 0.0360119, -3.0664e-08) 267 | bones/48/rotation = Quaternion(0.190721, 1.76515e-07, 0.023243, 0.981369) 268 | bones/49/rest = Transform3D(0.999994, -0.00337997, 4.71165e-05, 0.00337997, 0.99961, -0.0277345, 4.66435e-05, 0.0277345, 0.999615, 8.80398e-09, 0.033073, -5.93006e-08) 269 | bones/49/rotation = Quaternion(0.0731918, 0.0159758, 0.0101122, 0.997139) 270 | bones/50/rest = Transform3D(0.999884, 0.00060163, -0.0152262, -0.000599783, 1, 0.000125877, 0.0152263, -0.00011673, 0.999884, 1.12111e-07, 0.0366012, -4.29642e-08) 271 | bones/50/rotation = Quaternion(-6.06535e-05, -0.00761335, -0.000300362, 0.999971) 272 | bones/50/scale = Vector3(1, 1, 1) 273 | bones/51/rest = Transform3D(0.999977, -0.00675804, 0.000187471, 0.00675804, 0.998439, -0.0554481, 0.000187542, 0.0554481, 0.998462, -0.0472583, 0.109082, 0.00226145) 274 | bones/51/position = Vector3(-0.0472583, 0.109082, 0.00226132) 275 | bones/51/rotation = Quaternion(0.322707, -0.0103765, 0.069344, 0.943898) 276 | bones/52/rest = Transform3D(0.999384, -0.0347151, 0.00505121, 0.0347152, 0.95794, -0.28486, 0.00505018, 0.28486, 0.958556, -1.01482e-07, 0.0413664, -4.65513e-08) 277 | bones/52/position = Vector3(5.80652e-09, 0.0413664, 3.4511e-08) 278 | bones/52/rotation = Quaternion(0.149931, 1.93372e-07, 0.0182717, 0.988528) 279 | bones/52/scale = Vector3(0.999999, 1, 1) 280 | bones/53/rest = Transform3D(0.999994, -0.00337956, 4.6709e-05, 0.00337955, 0.99961, -0.0277351, 4.70415e-05, 0.0277351, 0.999615, -1.15153e-07, 0.0259484, -1.65755e-09) 281 | bones/53/position = Vector3(1.47836e-08, 0.0259483, 3.88736e-08) 282 | bones/53/rotation = Quaternion(0.0676719, -7.96096e-08, 0.00824686, 0.997674) 283 | bones/54/rest = Transform3D(0.999846, -0.00441081, -0.0169974, 0.00441363, 0.99999, 0.000128529, 0.0169967, -0.00020353, 0.999855, 2.60599e-09, 0.0292388, 5.41511e-08) 284 | bones/54/rotation = Quaternion(-8.30181e-05, -0.00849886, 0.00220619, 0.999961) 285 | bones/54/scale = Vector3(1, 1, 0.999999) 286 | bones/55/rest = Transform3D(-0.985328, 0.170164, 0.0131576, -0.098287, -0.62877, 0.771355, 0.13953, 0.758744, 0.636269, 0.0912387, -0.0665719, -0.000554031) 287 | bones/55/position = Vector3(0.0912387, -0.0665719, -0.000554031) 288 | bones/55/rotation = Quaternion(-0.0373609, -0.0809437, -0.995729, 0.0239904) 289 | bones/55/scale = Vector3(1, 1, 1) 290 | bones/56/rest = Transform3D(0.991327, 0.0338358, -0.126991, 0.121277, -0.607798, 0.784776, -0.0506315, -0.793371, -0.606629, 3.03754e-10, 0.405994, -1.31782e-09) 291 | bones/56/position = Vector3(3.03754e-10, 0.405994, -1.31782e-09) 292 | bones/56/rotation = Quaternion(-0.217141, -0.0787356, 0.0160509, 0.972827) 293 | bones/56/scale = Vector3(1, 1, 0.999999) 294 | bones/57/rest = Transform3D(0.985549, -0.119607, 0.119951, 0.163562, 0.487728, -0.857537, 0.0440644, 0.864763, 0.500243, -4.79804e-09, 0.42099, 1.27824e-09) 295 | bones/57/position = Vector3(-4.79804e-09, 0.42099, 1.27824e-09) 296 | bones/57/rotation = Quaternion(0.619104, -0.0218967, 0.00708009, 0.784972) 297 | bones/58/rest = Transform3D(0.997412, 0.0150935, -0.0702887, -0.0447131, 0.895841, -0.44212, 0.0562943, 0.444119, 0.894198, -3.69206e-09, 0.157216, 1.04308e-08) 298 | bones/58/position = Vector3(-3.69206e-09, 0.157216, 1.04308e-08) 299 | bones/58/rotation = Quaternion(0.231634, -0.0325105, -0.0152938, 0.972139) 300 | bones/58/scale = Vector3(1, 1, 1) 301 | bones/59/rest = Transform3D(1, 8.95671e-08, 8.4663e-08, -8.9567e-08, 1, -7.60483e-08, -8.4663e-08, 7.60483e-08, 1, -9.46224e-09, 0.1, -2.23517e-09) 302 | bones/59/position = Vector3(-9.46224e-09, 0.1, -2.23517e-09) 303 | bones/59/rotation = Quaternion(3.80242e-08, 4.23315e-08, -4.47835e-08, 1) 304 | bones/59/scale = Vector3(1, 1, 1) 305 | bones/60/rest = Transform3D(-0.992344, 0.090686, -0.0838467, -0.0911975, -0.99583, 0.00228246, -0.0832902, 0.00991159, 0.996476, -0.0912503, -0.066556, -0.000553527) 306 | bones/60/position = Vector3(-0.0912503, -0.066556, -0.000553527) 307 | bones/60/rotation = Quaternion(-0.120633, 0.0785067, 0.988432, 0.0478206) 308 | bones/60/scale = Vector3(1, 1, 1) 309 | bones/61/rest = Transform3D(0.98823, 0.0619704, -0.139859, 0.0331276, 0.805877, 0.591156, 0.149343, -0.588831, 0.794339, 8.57211e-09, 0.405995, 8.35862e-10) 310 | bones/61/position = Vector3(8.57211e-09, 0.405995, 8.35862e-10) 311 | bones/61/rotation = Quaternion(-0.178421, 0.0348001, -0.0108445, 0.983279) 312 | bones/61/scale = Vector3(1, 1, 1) 313 | bones/62/rest = Transform3D(0.973756, -0.0443233, -0.223237, -0.215963, 0.129611, -0.967761, 0.0718283, 0.990574, 0.116637, -6.30674e-09, 0.42099, 4.70085e-09) 314 | bones/62/position = Vector3(-6.30674e-09, 0.42099, 4.70085e-09) 315 | bones/62/rotation = Quaternion(0.580867, 0.0465949, 0.00781418, 0.812626) 316 | bones/62/scale = Vector3(1, 1, 1) 317 | bones/63/rest = Transform3D(0.997979, 0.0119221, 0.0624193, 0.0463328, 0.535742, -0.84311, -0.0434923, 0.844297, 0.534107, 1.89272e-08, 0.157216, 2.74181e-08) 318 | bones/63/position = Vector3(1.89272e-08, 0.157216, 2.74181e-08) 319 | bones/63/rotation = Quaternion(0.227709, 0.0321197, 0.0152578, 0.97308) 320 | bones/63/scale = Vector3(1, 0.999999, 1) 321 | bones/64/rest = Transform3D(1, 6.43195e-09, 2.49274e-08, -6.43195e-09, 1, 2.25555e-09, -2.49274e-08, -2.25555e-09, 1, -1.81422e-08, 0.1, -4.47035e-10) 322 | bones/64/position = Vector3(-1.81422e-08, 0.1, -4.47035e-10) 323 | bones/64/rotation = Quaternion(-1.12777e-09, 1.24637e-08, -3.21598e-09, 1) 324 | bones/64/scale = Vector3(1, 1, 1) 325 | 326 | [node name="AnchorRightShoulder" type="BoneAttachment3D" parent="Armature/Skeleton3D" index="2"] 327 | transform = Transform3D(0.995755, 0.0119781, -0.0912622, -0.0137371, 0.999731, -0.0186702, 0.0910141, 0.0198446, 0.995652, 0.00787403, 1.32864, -0.042616) 328 | bone_name = "mixamorig_Spine2" 329 | bone_idx = 3 330 | 331 | [node name="Anchor" type="StaticBody3D" parent="Armature/Skeleton3D/AnchorRightShoulder" index="0"] 332 | transform = Transform3D(0.999997, -2.01399e-08, -2.98023e-07, -3.6438e-08, 0.999997, -1.30385e-08, -2.98023e-07, 1.86265e-08, 0.999996, -0.190789, 0.101901, 0.0154097) 333 | collision_layer = 0 334 | collision_mask = 0 335 | 336 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/AnchorRightShoulder/Anchor" index="0"] 337 | shape = SubResource("SphereShape3D_ctvsv") 338 | 339 | [node name="PinJoint3D" type="PinJoint3D" parent="Armature/Skeleton3D/AnchorRightShoulder/Anchor" index="1"] 340 | transform = Transform3D(1, -8.9407e-08, 1.0943e-08, -7.45058e-09, 1, -3.72529e-09, -1.83471e-07, 4.09782e-08, 1, 0, 0, 0) 341 | node_a = NodePath("..") 342 | 343 | [node name="AnchorLeftShoulder" type="BoneAttachment3D" parent="Armature/Skeleton3D" index="3"] 344 | transform = Transform3D(0.995755, 0.0119781, -0.0912622, -0.0137371, 0.999731, -0.0186702, 0.0910141, 0.0198446, 0.995652, 0.00787403, 1.32864, -0.042616) 345 | bone_name = "mixamorig_Spine2" 346 | bone_idx = 3 347 | 348 | [node name="Anchor" type="StaticBody3D" parent="Armature/Skeleton3D/AnchorLeftShoulder" index="0"] 349 | transform = Transform3D(0.999999, -9.19681e-09, -1.04308e-07, -9.0804e-09, 0.999999, -9.31323e-09, -1.11759e-07, 9.31323e-09, 0.999999, 0.191411, 0.0865282, -0.0340705) 350 | collision_layer = 0 351 | collision_mask = 0 352 | 353 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/AnchorLeftShoulder/Anchor" index="0"] 354 | shape = SubResource("SphereShape3D_wns6n") 355 | 356 | [node name="PinJoint3D" type="PinJoint3D" parent="Armature/Skeleton3D/AnchorLeftShoulder/Anchor" index="1"] 357 | transform = Transform3D(1, -1.16415e-10, -7.45058e-09, 5.82077e-10, 1, 0, -7.45058e-09, 1.86265e-09, 1, 0, 0, 0) 358 | node_a = NodePath("..") 359 | 360 | [node name="AnchorLeftHip" type="BoneAttachment3D" parent="Armature/Skeleton3D" index="4"] 361 | transform = Transform3D(0.99981, 0.0194163, -0.00182982, -0.0193609, 0.99946, 0.0265462, 0.00234426, -0.0265058, 0.999646, 0.000864754, 0.979796, 0.0027928) 362 | bone_name = "mixamorig_Hips" 363 | bone_idx = 0 364 | 365 | [node name="Anchor" type="StaticBody3D" parent="Armature/Skeleton3D/AnchorLeftHip" index="0"] 366 | transform = Transform3D(1, -3.34694e-10, 1.62981e-09, -1.1496e-08, 1, 1.11759e-08, 4.65661e-10, -1.11759e-08, 1, 0.0982798, -0.0852774, -0.00082304) 367 | collision_layer = 0 368 | collision_mask = 0 369 | 370 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/AnchorLeftHip/Anchor" index="0"] 371 | shape = SubResource("SphereShape3D_ccon2") 372 | 373 | [node name="PinJoint3D" type="PinJoint3D" parent="Armature/Skeleton3D/AnchorLeftHip/Anchor" index="1"] 374 | node_a = NodePath("..") 375 | 376 | [node name="AnchorRightHip" type="BoneAttachment3D" parent="Armature/Skeleton3D" index="5"] 377 | transform = Transform3D(0.99981, 0.0194163, -0.00182982, -0.0193609, 0.99946, 0.0265462, 0.00234426, -0.0265058, 0.999646, 0.000864754, 0.979796, 0.0027928) 378 | bone_name = "mixamorig_Hips" 379 | bone_idx = 0 380 | 381 | [node name="Anchor" type="StaticBody3D" parent="Armature/Skeleton3D/AnchorRightHip" index="0"] 382 | transform = Transform3D(1, -3.27418e-10, 9.31323e-10, -7.75617e-09, 1, 7.45058e-09, 2.32831e-10, -7.45058e-09, 1, -0.0946549, -0.0873501, -0.00209412) 383 | collision_layer = 0 384 | collision_mask = 0 385 | 386 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/AnchorRightHip/Anchor" index="0"] 387 | shape = SubResource("SphereShape3D_dhq6f") 388 | 389 | [node name="PinJoint3D" type="PinJoint3D" parent="Armature/Skeleton3D/AnchorRightHip/Anchor" index="1"] 390 | node_a = NodePath("..") 391 | 392 | [node name="AnchorNeck" type="BoneAttachment3D" parent="Armature/Skeleton3D" index="6"] 393 | transform = Transform3D(0.995755, 0.0119781, -0.0912622, -0.0137371, 0.999731, -0.0186702, 0.0910141, 0.0198446, 0.995652, 0.00787403, 1.32864, -0.042616) 394 | bone_name = "mixamorig_Spine2" 395 | bone_idx = 3 396 | 397 | [node name="Anchor" type="StaticBody3D" parent="Armature/Skeleton3D/AnchorNeck" index="0"] 398 | transform = Transform3D(1, 2.4098e-08, 1.78814e-07, -9.19681e-09, 1, -3.72529e-08, -1.3411e-07, 5.7742e-08, 1, 0.00143741, 0.169754, 0.02519) 399 | collision_layer = 0 400 | collision_mask = 0 401 | 402 | [node name="MeshInstance3D" type="MeshInstance3D" parent="Armature/Skeleton3D/AnchorNeck/Anchor" index="0"] 403 | visible = false 404 | mesh = SubResource("CylinderMesh_0nwn6") 405 | 406 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/AnchorNeck/Anchor" index="1"] 407 | shape = SubResource("SphereShape3D_jps1h") 408 | 409 | [node name="PinJoint3D" type="PinJoint3D" parent="Armature/Skeleton3D/AnchorNeck/Anchor" index="2"] 410 | node_a = NodePath("..") 411 | 412 | [node name="Marker" type="MeshInstance3D" parent="Armature/Skeleton3D/AnchorNeck/Anchor/PinJoint3D" index="0"] 413 | visible = false 414 | mesh = SubResource("BoxMesh_k13tw") 415 | 416 | [node name="Physical Bone mixamorig_Hips" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="7" groups=["body_part"]] 417 | transform = Transform3D(0.999651, -0.000127163, -0.0195816, -0.0193437, 0.149037, -0.988642, 0.00304442, 0.988832, 0.149011, 0.00184194, 1.02914, -0.00465452) 418 | collision_layer = 8192 419 | collision_mask = 24951 420 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.23981e-07, 9.5889e-06, 0.0499147) 421 | body_offset = Transform3D(0.999843, -0.00069455, -8.75318e-05, -4.39334e-06, 0.122744, -0.992438, 0.000700667, 0.992438, 0.122749, 4.15184e-06, 0.049536, -0.00613651) 422 | bone_name = "mixamorig_Hips" 423 | 424 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_Hips" index="0"] 425 | transform = Transform3D(1, 2.61934e-10, 3.49246e-09, -2.56114e-09, 1.78814e-07, 1, -2.31958e-08, -1, 4.47035e-08, 0.000958906, -0.00738712, 0.049003) 426 | shape = SubResource("CylinderShape3D_gniu7") 427 | 428 | [node name="Physical Bone mixamorig_Spine" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="8" groups=["body_part"]] 429 | transform = Transform3D(0.999834, -0.00218738, -0.0186259, -0.0181799, 0.130841, -0.991236, 0.00460513, 0.991522, 0.130778, 0.00391821, 1.1368, -0.0197894) 430 | collision_layer = 8192 431 | collision_mask = 24951 432 | joint_type = 1 433 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.99223e-06, 1.15349e-05, 0.058661) 434 | body_offset = Transform3D(1.00001, 1.546e-07, 1.45519e-08, 2.2992e-08, -1.52588e-05, -0.999999, 2.43541e-07, 1.00012, 9.68575e-07, 2.99141e-06, 0.058661, -1.15931e-05) 435 | bone_name = "mixamorig_Spine" 436 | joint_constraints/bias = 0.3 437 | joint_constraints/damping = 1.0 438 | joint_constraints/impulse_clamp = 0.0 439 | 440 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_Spine" index="0"] 441 | transform = Transform3D(1, 1.16415e-10, -4.65661e-10, -9.31323e-10, 0, 1, 8.3237e-09, -1, 0, 0.000666345, -0.0047951, 0.0363318) 442 | shape = SubResource("CylinderShape3D_mcb4c") 443 | 444 | [node name="Physical Bone mixamorig_Spine1" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="9" groups=["body_part"]] 445 | transform = Transform3D(0.998713, -0.0457473, -0.0212965, -0.0159805, 0.113568, -0.993401, 0.0478627, 0.99247, 0.112691, 0.00644132, 1.26179, -0.0350328) 446 | collision_layer = 8192 447 | collision_mask = 24951 448 | joint_type = 1 449 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.11838e-07, 2.17583e-07, 0.0672941) 450 | body_offset = Transform3D(0.999987, -7.26432e-07, 2.79397e-09, 4.19095e-07, 2.45869e-06, -0.999999, -2.5332e-07, 0.999993, 7.52509e-07, 4.11645e-07, 0.067294, -2.68221e-07) 451 | bone_name = "mixamorig_Spine1" 452 | joint_constraints/bias = 0.3 453 | joint_constraints/damping = 1.0 454 | joint_constraints/impulse_clamp = 0.0 455 | 456 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_Spine1" index="0"] 457 | transform = Transform3D(1, 4.65661e-09, -2.23517e-08, 0, 5.96046e-08, 1, 6.98492e-09, -1, -4.47035e-08, 0.000234948, -0.00166962, 0.0146046) 458 | shape = SubResource("CylinderShape3D_gh660") 459 | 460 | [node name="Physical Bone mixamorig_Spine2" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="10" groups=["body_part"]] 461 | transform = Transform3D(-0.995751, 0.0917775, -0.00663794, 0.0137366, 0.0769405, -0.996979, -0.0909845, -0.992796, -0.077876, 0.00837351, 1.40368, -0.0367542) 462 | collision_layer = 8192 463 | collision_mask = 24951 464 | joint_type = 1 465 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.68341e-08, 4.85219e-07, 0.0752643) 466 | body_offset = Transform3D(-0.999993, -2.74852e-05, -1.97347e-06, 8.57981e-08, 0.0583175, -0.998336, 2.90722e-05, -0.998292, -0.0583179, 7.17118e-08, 0.075139, 0.00438974) 467 | bone_name = "mixamorig_Spine2" 468 | joint_constraints/bias = 0.3 469 | joint_constraints/damping = 1.0 470 | joint_constraints/impulse_clamp = 0.0 471 | 472 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_Spine2" index="0"] 473 | transform = Transform3D(1, 1.86265e-09, 0, -1.49012e-08, 1.49012e-08, 1, 0, -1, 2.98023e-08, 6.82166e-05, 0.000382081, -0.00495064) 474 | shape = SubResource("CylinderShape3D_y6twj") 475 | 476 | [node name="Physical Bone mixamorig_Neck" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="11" groups=["body_part"]] 477 | transform = Transform3D(-0.99647, 0.0871129, -0.0175254, 0.0390014, 0.277734, -1.00768, -0.0762499, -1.00615, -0.286499, 0.009789, 1.53064, -0.0162831) 478 | collision_layer = 8192 479 | collision_mask = 24951 480 | joint_type = 2 481 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.19641e-06, -0.00014114, 0.0514896) 482 | body_offset = Transform3D(-1.00014, -0.00074219, -5.34765e-06, -1.49093e-06, 0.30154, -1.0015, -3.91155e-06, -1.00307, -0.307916, 1.36718e-06, 0.0516094, 0.0157129) 483 | bone_name = "mixamorig_Neck" 484 | joint_constraints/swing_span = 45.0 485 | joint_constraints/twist_span = 180.0 486 | joint_constraints/bias = 0.3 487 | joint_constraints/softness = 0.8 488 | joint_constraints/relaxation = 1.0 489 | 490 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_Neck" index="0"] 491 | transform = Transform3D(1, 5.58794e-09, -2.23517e-08, 0, -8.9407e-08, 1, 0, -1, 8.9407e-08, -0.000633031, -0.00422758, 0.0149987) 492 | shape = SubResource("CylinderShape3D_3nmod") 493 | 494 | [node name="Physical Bone mixamorig_Head" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="12" groups=["body_part"]] 495 | transform = Transform3D(-0.994201, 0.0940782, 0.0748695, -0.0233554, 0.43682, -1.03457, -0.107426, -1.00059, -0.501841, 0.00434433, 1.67226, 0.0376803) 496 | collision_layer = 8192 497 | collision_mask = 24951 498 | joint_type = 3 499 | joint_offset = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -0.000295789, -0.00340064, 0.0852653) 500 | joint_rotation = Vector3(0, 1.5708, 0) 501 | body_offset = Transform3D(-1.00026, -0.00373532, -0.00362915, -4.11645e-07, 0.362805, -1.06889, -1.76504e-05, -1.03402, -0.430402, 8.71718e-07, 0.0923734, 0.033182) 502 | bone_name = "mixamorig_Head" 503 | joint_constraints/angular_limit_enabled = true 504 | joint_constraints/angular_limit_upper = 90.0 505 | joint_constraints/angular_limit_lower = -10.0 506 | joint_constraints/angular_limit_bias = 0.3 507 | joint_constraints/angular_limit_softness = 0.9 508 | joint_constraints/angular_limit_relaxation = 1.0 509 | 510 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_Head" index="0"] 511 | transform = Transform3D(1, -2.23517e-08, -2.23517e-08, -2.23517e-08, 0, 1, 3.72529e-09, -1, -2.98023e-08, 0.0019997, 0.00860178, 0.0157543) 512 | shape = SubResource("CapsuleShape3D_7ywly") 513 | 514 | [node name="Physical Bone mixamorig_LeftShoulder" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="13" groups=["body_part"]] 515 | transform = Transform3D(-0.237629, -0.0411263, -0.970508, 0.0274558, -0.998989, 0.0356152, -0.971009, -0.0181813, 0.238516, 0.131781, 1.41652, -0.0431237) 516 | collision_layer = 8192 517 | collision_mask = 24951 518 | joint_type = 1 519 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.61416e-06, 0.000124394, 0.0646093) 520 | body_offset = Transform3D(1.00004, -4.84288e-08, 2.32458e-06, 5.30481e-06, -4.14904e-07, -1.00002, -9.22009e-07, 1, -2.7502e-06, 1.46404e-06, 0.0646107, -0.000124216) 521 | bone_name = "mixamorig_LeftShoulder" 522 | joint_constraints/bias = 0.3 523 | joint_constraints/damping = 1.0 524 | joint_constraints/impulse_clamp = 0.0 525 | 526 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_LeftShoulder" index="0"] 527 | transform = Transform3D(1, -2.98023e-08, 1.86265e-09, 5.58794e-09, -5.58794e-09, 1, 0, -0.999999, -8.84756e-09, 0.00341431, 0.000590563, 0.0139449) 528 | shape = SubResource("BoxShape3D_acp8j") 529 | 530 | [node name="Physical Bone mixamorig_LeftArm" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="14" groups=["body_part"]] 531 | transform = Transform3D(0.381777, -0.878412, -0.287461, 0.048908, -0.29138, 0.955353, -0.92296, -0.378792, -0.0682819, 0.233871, 1.28319, -0.049179) 532 | collision_layer = 8192 533 | collision_mask = 24951 534 | joint_type = 2 535 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.33894e-07, 9.71421e-08, 0.137023) 536 | body_offset = Transform3D(1, 2.14577e-06, 3.27826e-07, 3.20375e-07, -2.19978e-06, -0.999998, -3.57628e-07, 0.999997, 5.96046e-07, -1.78814e-07, 0.137023, -1.78814e-07) 537 | bone_name = "mixamorig_LeftArm" 538 | joint_constraints/swing_span = 45.0 539 | joint_constraints/twist_span = 180.0 540 | joint_constraints/bias = 0.3 541 | joint_constraints/softness = 0.8 542 | joint_constraints/relaxation = 1.0 543 | 544 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_LeftArm" index="0"] 545 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 546 | shape = SubResource("CapsuleShape3D_p5cwv") 547 | 548 | [node name="Physical Bone mixamorig_LeftForeArm" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="15" groups=["body_part"]] 549 | transform = Transform3D(0.473608, -0.878415, -0.0638909, -0.424809, -0.291381, 0.857108, -0.771513, -0.378792, -0.511159, 0.282077, 1.03394, 0.0307553) 550 | collision_layer = 8192 551 | collision_mask = 24951 552 | joint_type = 3 553 | joint_offset = Transform3D(-4.37114e-08, 0, 0.999999, 0, 1, 0, -0.999999, 0, -4.37114e-08, 3.15493e-06, -3.81058e-06, 0.138073) 554 | joint_rotation = Vector3(0, 1.5708, 0) 555 | body_offset = Transform3D(1, 5.96046e-08, 2.98023e-08, 2.98023e-08, -3.57628e-07, -1, 2.98023e-08, 1, -2.98023e-08, -3.15905e-06, 0.138073, 3.8147e-06) 556 | bone_name = "mixamorig_LeftForeArm" 557 | joint_constraints/angular_limit_enabled = true 558 | joint_constraints/angular_limit_upper = 90.0 559 | joint_constraints/angular_limit_lower = -10.0 560 | joint_constraints/angular_limit_bias = 0.3 561 | joint_constraints/angular_limit_softness = 0.9 562 | joint_constraints/angular_limit_relaxation = 1.0 563 | 564 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_LeftForeArm" index="0"] 565 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 566 | shape = SubResource("CapsuleShape3D_nclj6") 567 | 568 | [node name="Physical Bone mixamorig_LeftHand" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="16" groups=["body_part"]] 569 | transform = Transform3D(0.0641938, 0.993705, -0.0918705, 0.387354, 0.0600055, 0.920088, 0.919694, -0.0946287, -0.381064, 0.293645, 0.840608, 0.111426) 570 | collision_layer = 8192 571 | collision_mask = 24951 572 | joint_type = 2 573 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0195859, 0.00273153, 0.0730826) 574 | body_offset = Transform3D(-0.771013, 0.627863, 0.10639, -0.188347, -0.065189, -0.980046, -0.60833, -0.775592, 0.168528, 0.00561071, 0.0754913, 0.00171679) 575 | bone_name = "mixamorig_LeftHand" 576 | joint_constraints/swing_span = 45.0 577 | joint_constraints/twist_span = 180.0 578 | joint_constraints/bias = 0.3 579 | joint_constraints/softness = 0.8 580 | joint_constraints/relaxation = 1.0 581 | 582 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_LeftHand" index="0"] 583 | shape = SubResource("CylinderShape3D_87825") 584 | 585 | [node name="Physical Bone mixamorig_RightShoulder" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="17" groups=["body_part"]] 586 | transform = Transform3D(-0.249142, -0.053735, 0.966974, -0.030117, -0.997547, -0.0631939, 0.967999, -0.0448677, 0.246913, -0.115002, 1.42445, -0.0547817) 587 | collision_layer = 8192 588 | collision_mask = 24951 589 | joint_type = 1 590 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.15359e-07, -8.78912e-06, 0.0646114) 591 | body_offset = Transform3D(1, -5.96046e-08, -5.96046e-08, -3.57628e-07, -2.42144e-06, -0.999999, -1.12876e-06, 1, -2.346e-06, 1.19209e-07, 0.0646114, 8.9407e-06) 592 | bone_name = "mixamorig_RightShoulder" 593 | joint_constraints/bias = 0.3 594 | joint_constraints/damping = 1.0 595 | joint_constraints/impulse_clamp = 0.0 596 | 597 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_RightShoulder" index="0"] 598 | transform = Transform3D(1, 0, 7.45058e-09, -7.45058e-09, 1.58325e-08, 1, 0, -1, 0, -0.00349087, -0.000752926, 0.0135488) 599 | shape = SubResource("BoxShape3D_aq1ss") 600 | 601 | [node name="Physical Bone mixamorig_RightArm" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="18" groups=["body_part"]] 602 | transform = Transform3D(0.387337, 0.867055, 0.313354, -0.0285269, -0.328442, 0.944093, 0.921509, -0.374621, -0.102462, -0.220417, 1.29918, -0.0566946) 603 | collision_layer = 8192 604 | collision_mask = 24951 605 | joint_type = 2 606 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.32737e-07, 5.70501e-08, 0.137025) 607 | body_offset = Transform3D(1.00001, 1.78814e-07, -1.04308e-07, -2.16961e-05, -1.67638e-07, -1, -5.24521e-06, 1, 1.86265e-08, 4.47035e-07, 0.137025, -5.96046e-08) 608 | bone_name = "mixamorig_RightArm" 609 | joint_constraints/swing_span = 45.0 610 | joint_constraints/twist_span = 180.0 611 | joint_constraints/bias = 0.3 612 | joint_constraints/softness = 0.8 613 | joint_constraints/relaxation = 1.0 614 | 615 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_RightArm" index="0"] 616 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 617 | shape = SubResource("CapsuleShape3D_bxuej") 618 | 619 | [node name="Physical Bone mixamorig_RightForeArm" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="19" groups=["body_part"]] 620 | transform = Transform3D(0.487546, 0.867056, 0.102538, 0.404603, -0.328441, 0.853477, 0.773689, -0.374621, -0.510944, -0.277511, 1.05198, 0.0278921) 621 | collision_layer = 8192 622 | collision_mask = 24951 623 | joint_type = 3 624 | joint_offset = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -3.27965e-08, 6.99532e-08, 0.138073) 625 | joint_rotation = Vector3(0, 1.5708, 0) 626 | body_offset = Transform3D(1, 1.78814e-07, -6.25849e-07, -6.25849e-07, -2.08616e-07, -1, -1.49012e-07, 1, -5.06639e-07, 1.19209e-07, 0.138073, 0) 627 | bone_name = "mixamorig_RightForeArm" 628 | joint_constraints/angular_limit_enabled = true 629 | joint_constraints/angular_limit_upper = 90.0 630 | joint_constraints/angular_limit_lower = -10.0 631 | joint_constraints/angular_limit_bias = 0.3 632 | joint_constraints/angular_limit_softness = 0.9 633 | joint_constraints/angular_limit_relaxation = 1.0 634 | 635 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_RightForeArm" index="0"] 636 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 637 | shape = SubResource("CapsuleShape3D_fe61b") 638 | 639 | [node name="Physical Bone mixamorig_RightHand" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="20" groups=["body_part"]] 640 | transform = Transform3D(1.00001, 1.29938e-05, -1.16527e-05, -5.96046e-07, 1.00031, -9.24617e-06, 1.19209e-07, 4.68194e-05, 1.00021, -0.306774, 0.868753, 0.113467) 641 | collision_layer = 8192 642 | collision_mask = 24951 643 | joint_type = 2 644 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0151047, 0.0653631, -0.0150276) 645 | body_offset = Transform3D(0.41539, 0.184338, 0.890976, -0.20299, -0.936089, 0.288272, 0.886712, -0.300635, -0.351408, -0.00493398, 0.0685838, 0.000976086) 646 | bone_name = "mixamorig_RightHand" 647 | joint_constraints/swing_span = 45.0 648 | joint_constraints/twist_span = 180.0 649 | joint_constraints/bias = 0.3 650 | joint_constraints/softness = 0.8 651 | joint_constraints/relaxation = 1.0 652 | 653 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_RightHand" index="0"] 654 | transform = Transform3D(-0.290869, 0.956763, -6.41654e-07, -0.956763, -0.290869, 1.26781e-06, 1.02635e-06, 9.82676e-07, 1, -0.00206277, -0.00161922, 4.47035e-08) 655 | shape = SubResource("CylinderShape3D_87825") 656 | 657 | [node name="Physical Bone mixamorig_LeftUpLeg" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="21" groups=["body_part"]] 658 | transform = Transform3D(-0.996821, 0.0718691, -0.0343827, -0.0203423, 0.187658, 0.982023, 0.0770296, 0.979588, -0.185601, 0.0977741, 0.71213, 0.041894) 659 | collision_layer = 8192 660 | collision_mask = 24951 661 | joint_type = 2 662 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.83385e-08, 1.25931e-07, 0.202998) 663 | body_offset = Transform3D(1, -6.33299e-07, -9.22009e-08, -4.65661e-09, -1.11759e-06, -1, -1.04308e-07, 0.999987, -2.5332e-07, 6.70552e-08, 0.202998, -7.45058e-08) 664 | bone_name = "mixamorig_LeftUpLeg" 665 | joint_constraints/swing_span = 45.0 666 | joint_constraints/twist_span = 180.0 667 | joint_constraints/bias = 0.3 668 | joint_constraints/softness = 0.8 669 | joint_constraints/relaxation = 1.0 670 | 671 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_LeftUpLeg" index="0"] 672 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 673 | shape = SubResource("CapsuleShape3D_uygg8") 674 | 675 | [node name="Physical Bone mixamorig_LeftLeg" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="22" groups=["body_part"]] 676 | transform = Transform3D(-0.97119, 0.238294, 0.00237707, -0.0568864, -0.24151, 0.968729, 0.231416, 0.940683, 0.248108, 0.104253, 0.308872, 0.0273454) 677 | collision_layer = 8192 678 | collision_mask = 24951 679 | joint_type = 3 680 | joint_offset = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -2.16851e-07, -7.94959e-08, 0.210493) 681 | joint_rotation = Vector3(0, 1.5708, 0) 682 | body_offset = Transform3D(1, -2.83122e-07, 3.72529e-09, -5.96046e-08, 7.45058e-08, -1, -7.45058e-07, 0.999999, 2.98023e-07, 2.16067e-07, 0.210493, 1.67638e-08) 683 | bone_name = "mixamorig_LeftLeg" 684 | joint_constraints/angular_limit_enabled = true 685 | joint_constraints/angular_limit_upper = 90.0 686 | joint_constraints/angular_limit_lower = -10.0 687 | joint_constraints/angular_limit_bias = 0.3 688 | joint_constraints/angular_limit_softness = 0.9 689 | joint_constraints/angular_limit_relaxation = 1.0 690 | 691 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_LeftLeg" index="0"] 692 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 693 | shape = SubResource("CapsuleShape3D_kqje8") 694 | 695 | [node name="Physical Bone mixamorig_LeftFoot" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="23" groups=["body_part"]] 696 | transform = Transform3D(-0.959842, 0.0825776, -0.26811, -0.0517485, 0.88718, 0.458511, 0.275724, 0.453974, -0.84728, 0.124828, 0.0689152, 0.0417224) 697 | collision_layer = 8192 698 | collision_mask = 24951 699 | joint_type = 3 700 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.77316e-07, -3.06091e-08, 0.078608) 701 | body_offset = Transform3D(0.999999, -4.47035e-08, -2.08616e-07, -2.23517e-07, 2.98023e-07, -1, 1.3411e-07, 1, -1.2219e-06, 1.93715e-07, 0.078608, 1.2666e-07) 702 | bone_name = "mixamorig_LeftFoot" 703 | joint_constraints/angular_limit_enabled = false 704 | joint_constraints/angular_limit_upper = 90.0 705 | joint_constraints/angular_limit_lower = -90.0 706 | joint_constraints/angular_limit_bias = 0.3 707 | joint_constraints/angular_limit_softness = 0.9 708 | joint_constraints/angular_limit_relaxation = 1.0 709 | 710 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_LeftFoot" index="0"] 711 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 712 | shape = SubResource("CapsuleShape3D_tfce0") 713 | 714 | [node name="Physical Bone mixamorig_LeftToeBase" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="24" groups=["body_part"]] 715 | transform = Transform3D(-0.96474, 0.0205313, -0.2624, 0.0187158, 0.999916, 0.00941904, 0.262537, 0.00419115, -0.964912, 0.15901, 0.0324144, 0.156571) 716 | collision_layer = 8192 717 | collision_mask = 24951 718 | joint_type = 3 719 | joint_offset = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -1.42082e-05, -1.26998e-05, 0.0499962) 720 | joint_rotation = Vector3(0, 1.5708, 0) 721 | body_offset = Transform3D(0.999999, 8.3592e-06, -4.47035e-07, 2.68221e-07, 1.06203e-05, -1, -1.13086e-06, 1.00014, -2.12155e-06, 1.42306e-05, 0.0499962, 1.28075e-05) 722 | bone_name = "mixamorig_LeftToeBase" 723 | joint_constraints/angular_limit_enabled = true 724 | joint_constraints/angular_limit_upper = 90.0 725 | joint_constraints/angular_limit_lower = -10.0 726 | joint_constraints/angular_limit_bias = 0.3 727 | joint_constraints/angular_limit_softness = 0.9 728 | joint_constraints/angular_limit_relaxation = 1.0 729 | 730 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_LeftToeBase" index="0"] 731 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 732 | shape = SubResource("CapsuleShape3D_bqmwm") 733 | 734 | [node name="Physical Bone mixamorig_RightUpLeg" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="25" groups=["body_part"]] 735 | transform = Transform3D(-0.96422, -0.229787, 0.132805, 0.0877319, 0.196731, 0.976559, -0.250165, 0.954152, -0.169403, -0.118618, 0.716784, 0.0381813) 736 | collision_layer = 8192 737 | collision_mask = 24951 738 | joint_type = 2 739 | joint_offset = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5863e-06, -1.95143e-06, 0.203003) 740 | body_offset = Transform3D(1, 0.000128865, 5.55068e-07, -3.72529e-09, 3.17395e-05, -1, -1.49012e-08, 1.00096, -2.563e-06, -1.69873e-06, 0.203003, 2.47359e-06) 741 | bone_name = "mixamorig_RightUpLeg" 742 | joint_constraints/swing_span = 45.0 743 | joint_constraints/twist_span = 180.0 744 | joint_constraints/bias = 0.3 745 | joint_constraints/softness = 0.8 746 | joint_constraints/relaxation = 1.0 747 | 748 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_RightUpLeg" index="0"] 749 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 750 | shape = SubResource("CapsuleShape3D_e8j4g") 751 | 752 | [node name="Physical Bone mixamorig_RightLeg" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="26" groups=["body_part"]] 753 | transform = Transform3D(-0.942362, -0.330493, 0.0522301, 0.107761, -0.151997, 0.982487, -0.316767, 0.931489, 0.178852, -0.156572, 0.311763, 0.0349215) 754 | collision_layer = 8192 755 | collision_mask = 24951 756 | joint_type = 3 757 | joint_offset = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -1.38817e-06, 4.86649e-08, 0.210473) 758 | joint_rotation = Vector3(0, 1.5708, 0) 759 | body_offset = Transform3D(1, 5.06639e-07, -2.01166e-07, 1.78814e-07, -3.12924e-07, -0.999998, -2.38419e-07, 1, 7.59959e-07, 1.43051e-06, 0.210473, -2.08616e-07) 760 | bone_name = "mixamorig_RightLeg" 761 | joint_constraints/angular_limit_enabled = true 762 | joint_constraints/angular_limit_upper = 90.0 763 | joint_constraints/angular_limit_lower = -10.0 764 | joint_constraints/angular_limit_bias = 0.3 765 | joint_constraints/angular_limit_softness = 0.9 766 | joint_constraints/angular_limit_relaxation = 1.0 767 | 768 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_RightLeg" index="0"] 769 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 770 | shape = SubResource("CapsuleShape3D_j0edi") 771 | 772 | [node name="Physical Bone mixamorig_RightFoot" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="27" groups=["body_part"]] 773 | transform = Transform3D(-0.919618, -0.136684, 0.368266, 0.0517499, 0.88718, 0.458513, -0.389389, 0.440714, -0.808793, -0.196515, 0.0688894, 0.0608488) 774 | collision_layer = 8192 775 | collision_mask = 24951 776 | joint_type = 3 777 | joint_offset = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 2.15066e-09, -1.02388e-07, 0.0786082) 778 | joint_rotation = Vector3(0, 1.5708, 0) 779 | body_offset = Transform3D(1, -7.45058e-08, -5.96046e-07, -1.49012e-07, -8.04663e-07, -1, -8.9407e-08, 1, -1.19209e-07, 4.47035e-08, 0.0786082, 1.11759e-07) 780 | bone_name = "mixamorig_RightFoot" 781 | joint_constraints/angular_limit_enabled = true 782 | joint_constraints/angular_limit_upper = 30.0 783 | joint_constraints/angular_limit_lower = -60.0 784 | joint_constraints/angular_limit_bias = 0.3 785 | joint_constraints/angular_limit_softness = 0.9 786 | joint_constraints/angular_limit_relaxation = 1.0 787 | 788 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_RightFoot" index="0"] 789 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 790 | shape = SubResource("CapsuleShape3D_3t23u") 791 | 792 | [node name="Physical Bone mixamorig_RightToeBase" type="PhysicalBone3D" parent="Armature/Skeleton3D" index="28" groups=["body_part"]] 793 | transform = Transform3D(-0.92605, -0.0232659, 0.376755, -0.0180239, 0.999716, 0.0174996, -0.377024, 0.00943347, -0.926147, -0.244312, 0.0319656, 0.170734) 794 | collision_layer = 8192 795 | collision_mask = 24951 796 | joint_type = 3 797 | joint_offset = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -9.9627e-06, 5.81082e-06, 0.0500042) 798 | joint_rotation = Vector3(0, 1.5708, 0) 799 | body_offset = Transform3D(1.00002, -3.17907e-06, 1.78814e-07, 3.00407e-05, 7.6713e-06, -1, -2.69029e-05, 1.00003, 3.72529e-09, 9.95398e-06, 0.0500042, -5.81145e-06) 800 | bone_name = "mixamorig_RightToeBase" 801 | joint_constraints/angular_limit_enabled = true 802 | joint_constraints/angular_limit_upper = 90.0 803 | joint_constraints/angular_limit_lower = -10.0 804 | joint_constraints/angular_limit_bias = 0.3 805 | joint_constraints/angular_limit_softness = 0.9 806 | joint_constraints/angular_limit_relaxation = 1.0 807 | 808 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Armature/Skeleton3D/Physical Bone mixamorig_RightToeBase" index="0"] 809 | transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0) 810 | shape = SubResource("CapsuleShape3D_hw4c3") 811 | 812 | [connection signal="hit" from="." to="." method="_on_hit"] 813 | -------------------------------------------------------------------------------- /project/src/Mannequin/physics_skeleton.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends Skeleton3D 6 | 7 | var _animation_skeleton : Skeleton3D 8 | 9 | @export var linear_spring_stiffness := 1200.0 10 | @export var linear_spring_damping := 40.0 11 | const linear_force_max := 9999.0 12 | 13 | @export var angular_spring_stiffness := 4000.0 14 | @export var angular_spring_damping := 80.0 15 | const angular_force_max := 9999.0 16 | 17 | var _is_syncing := false 18 | 19 | func _ready() -> void: 20 | # Turn off bone gravity and start reacting to physics 21 | for child in self.get_children(): 22 | if child is PhysicalBone3D: 23 | child.gravity_scale = 0.0 24 | #var col = child.get_node("CollisionShape3D") 25 | #col.disabled = true 26 | 27 | self.physical_bones_start_simulation() 28 | 29 | func _physics_process(delta : float) -> void: 30 | if not _is_syncing: return 31 | 32 | for bone in self.get_children().filter(func(c): return c is PhysicalBone3D): 33 | # Get the locations of the physical and animation bones 34 | var animation_transform := _animation_skeleton.global_transform * _animation_skeleton.get_bone_global_pose(bone.get_bone_id()) 35 | var physics_transform := self.global_transform * self.get_bone_global_pose(bone.get_bone_id()) 36 | 37 | # Get the differences 38 | var position_difference := animation_transform.origin - physics_transform.origin 39 | var rotation_difference := animation_transform.basis * physics_transform.basis.inverse() 40 | 41 | # Set the linear velocity 42 | if position_difference.length_squared() <= 1.0: 43 | var force := Global.hookes_law(position_difference, bone.linear_velocity, self.linear_spring_stiffness, self.linear_spring_damping) 44 | force = force.limit_length(self.linear_force_max) 45 | bone.linear_velocity += force * delta 46 | # If the distance is too far, just use the animation position 47 | else: 48 | bone.global_position = animation_transform.origin 49 | bone.linear_velocity = Vector3.ZERO 50 | 51 | # Set the angular velocity 52 | var torque := Global.hookes_law(rotation_difference.get_euler(), bone.angular_velocity, self.angular_spring_stiffness, self.angular_spring_damping) 53 | torque = torque.limit_length(self.angular_force_max) 54 | bone.angular_velocity += torque * delta 55 | -------------------------------------------------------------------------------- /project/src/NPC/npc.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends CharacterBody3D 6 | 7 | const HP_MAX := 100.0 8 | const SPEED := 5.0 9 | const JUMP_IMPULSE := 20.0 10 | const ROTATION_SPEED := 10.0 11 | const SPEED_WALK := 1.9 12 | const SPEED_RUN := 6.0 13 | var GRAVITY : float = ProjectSettings.get_setting("physics/3d/default_gravity") 14 | 15 | signal hit_body_part(collider : Node, body_part : Global.BodyPart, origin : Vector3, angle : Vector3, force : float, bullet_type : int) 16 | 17 | @onready var _mannequin = $Pivot/Mannequin 18 | @onready var _skeleton = $"Pivot/Mannequin/Armature/PhysicsSkeleton3D" 19 | @onready var _skeleton_center = self.get_node("Pivot/Mannequin/Armature/PhysicsSkeleton3D/Physical Bone %s" % [Global.bone_names[Global.BodyPart.TorsoMiddle][0]]) 20 | @onready var _animation_player = $Pivot/Mannequin/AnimationPlayer 21 | 22 | var _is_dead := false 23 | var _hp := HP_MAX 24 | var _speed := SPEED_WALK 25 | var _path_marker := [] 26 | var _body_part_health := {} 27 | var _velocity := Vector3.ZERO 28 | var _velocity_gravity := Vector3.ZERO 29 | 30 | func _ready() -> void: 31 | _animation_player.play("idle") 32 | 33 | for part in Global.BodyPart.values(): 34 | _body_part_health[part] = 100.0 35 | 36 | func _process(_delta : float) -> void: 37 | if _is_dead: return 38 | 39 | # Update the velocity 40 | var prev_velocity := _velocity 41 | if not _path_marker.is_empty(): 42 | var direction : Vector3 = _path_marker[0] - self.global_transform.origin 43 | var direction_xz := Vector2(direction.x, direction.z) 44 | var distance_xz := absf(direction_xz.length()) 45 | var distance_y := absf(direction.y) 46 | 47 | var threshold_xz := 1.0 48 | var threshold_y := 3.0 49 | if distance_xz < threshold_xz and distance_y < threshold_y: 50 | _path_marker.pop_front() 51 | else: 52 | _velocity = direction.normalized() * _speed 53 | else: 54 | # Stop moving 55 | _velocity = Vector3.ZERO 56 | 57 | # Update the animation 58 | if prev_velocity != _velocity: 59 | if _velocity.is_equal_approx(Vector3.ZERO): 60 | _animation_player.play("idle") 61 | else: 62 | if _speed > SPEED_WALK: 63 | _animation_player.play("run") 64 | else: 65 | _animation_player.play("walk") 66 | 67 | func _physics_process(delta : float) -> void: 68 | # When ragdolling, move to skeleton location 69 | if _mannequin.is_ragdoll: 70 | self.global_transform.origin = _skeleton_center.global_transform.origin 71 | 72 | if _is_dead: return 73 | 74 | # Add the gravity 75 | if not self.is_on_floor(): 76 | _velocity_gravity.y = clampf(_velocity_gravity.y - GRAVITY * delta, -GRAVITY, 0.0) 77 | else: 78 | _velocity_gravity.y = 0.0 79 | 80 | # Rotate to direction moving in 81 | self.rotation.y = lerp_angle(self.rotation.y, atan2(_velocity.x, _velocity.z), ROTATION_SPEED * delta) 82 | 83 | # Actually move 84 | self.velocity = _velocity + _velocity_gravity 85 | self.move_and_slide() 86 | 87 | func _on_hit_body_part(collider : Node, body_part : Global.BodyPart, origin : Vector3, angle : Vector3, force : float, bullet_type : int) -> void: 88 | var can_break := true 89 | 90 | # Get power based on body part 91 | var power := 0.0 92 | var body_part_root : Global.BodyPart = -1 93 | match body_part: 94 | Global.BodyPart.Head: 95 | power = 100.0 96 | body_part_root = Global.BodyPart.Head 97 | Global.BodyPart.TorsoUpper, Global.BodyPart.TorsoMiddle, Global.BodyPart.TorsoLower: 98 | power = 20.0 99 | body_part_root = Global.BodyPart.TorsoUpper 100 | can_break = false 101 | Global.BodyPart.Pelvis: 102 | power = 20.0 103 | body_part_root = Global.BodyPart.Pelvis 104 | can_break = false 105 | Global.BodyPart.LowerArmR, Global.BodyPart.UpperArmR, Global.BodyPart.HandR: 106 | power = 20.0 107 | body_part_root = Global.BodyPart.UpperArmR 108 | Global.BodyPart.LowerArmL, Global.BodyPart.UpperArmL, Global.BodyPart.HandL: 109 | power = 20.0 110 | body_part_root = Global.BodyPart.UpperArmL 111 | Global.BodyPart.LowerLegR, Global.BodyPart.UpperLegR, Global.BodyPart.FootR: 112 | power = 20.0 113 | body_part_root = Global.BodyPart.UpperLegR 114 | Global.BodyPart.LowerLegL, Global.BodyPart.UpperLegL, Global.BodyPart.FootL: 115 | power = 20.0 116 | body_part_root = Global.BodyPart.UpperLegL 117 | _: 118 | push_error("Unexpected BodyPart: %s" % [body_part]) 119 | return 120 | 121 | collider.apply_central_impulse(angle * force) 122 | 123 | var value = Global.enum_name_from_value(Global.BodyPart, body_part_root) 124 | 125 | if can_break: 126 | var health : float = _body_part_health[body_part_root] 127 | health = clampf(health - power, 0.0, 100.0) 128 | #var zz = Global.enum_name_from_value(Global.BodyPart, body_part_root) 129 | #print("!!! hit %s, %s, %s, %s" % [value, body_part_root, zz, health]) 130 | if health > 60.0: 131 | _mannequin.set_body_part_status(body_part_root, Global.BodyPartStatus.Normal) 132 | elif health > 30.0: 133 | _mannequin.set_body_part_status(body_part_root, Global.BodyPartStatus.Crippled) 134 | else: 135 | _mannequin.set_body_part_status(body_part_root, Global.BodyPartStatus.Destroyed) 136 | _body_part_health[body_part_root] = health 137 | 138 | func set_hp(value : float) -> void: 139 | _hp = clampf(value, 0, HP_MAX) 140 | 141 | # Die if has no health 142 | if _hp == 0.0: 143 | self.die() 144 | 145 | func die() -> void: 146 | if _is_dead: return 147 | _is_dead = true 148 | 149 | $CollisionShape3D.disabled = true 150 | _mannequin._start_ragdoll() 151 | 152 | func live() -> void: 153 | if not _is_dead: return 154 | _is_dead = false 155 | 156 | $CollisionShape3D.disabled = false 157 | _mannequin._stop_ragdoll() 158 | -------------------------------------------------------------------------------- /project/src/NPC/npc.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://3m43sql38uyt"] 2 | 3 | [ext_resource type="Script" path="res://src/NPC/npc.gd" id="1_dc10r"] 4 | [ext_resource type="PackedScene" uid="uid://dpkf4sjfur2by" path="res://src/Mannequin/mannequin.tscn" id="2_he74v"] 5 | 6 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_yhvyp"] 7 | 8 | [node name="NPC" type="CharacterBody3D"] 9 | collision_layer = 8 10 | collision_mask = 65 11 | script = ExtResource("1_dc10r") 12 | 13 | [node name="Pivot" type="Node3D" parent="."] 14 | 15 | [node name="Mannequin" parent="Pivot" instance=ExtResource("2_he74v")] 16 | 17 | [node name="CollisionShape3D" type="CollisionShape3D" parent="."] 18 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) 19 | shape = SubResource("CapsuleShape3D_yhvyp") 20 | 21 | [connection signal="hit_body_part" from="." to="." method="_on_hit_body_part"] 22 | -------------------------------------------------------------------------------- /project/src/Player/player.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends CharacterBody3D 6 | 7 | 8 | const ACCELERATION_SPRINT := 100.0 9 | const ACCELERATION_WALK := 70.0 10 | const VELOCITY_SPRINT := 20.0 11 | const VELOCITY_WALK := 10.0 12 | const JUMP_IMPULSE := 20.0 13 | const ROTATION_SPEED := 10.0 14 | var GRAVITY : float = ProjectSettings.get_setting("physics/3d/default_gravity") 15 | 16 | # Get the gravity from the project settings to be synced with RigidBody nodes 17 | #var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity") 18 | var _camera_x := 0.0 19 | var _camera_y := 0.0 20 | var _camera_x_new := 0.0 21 | var _camera_y_new := 0.0 22 | var _latest_mouse_pos := Vector2.ZERO 23 | var _target_pos := Vector3.ZERO 24 | 25 | var _input_vector := Vector3.ZERO 26 | 27 | func _input(event : InputEvent) -> void: 28 | # Rotate camera with mouse 29 | if event is InputEventMouseMotion: 30 | _camera_x -= event.relative.x * Global.MOUSE_SENSITIVITY 31 | _camera_y = clampf(_camera_y - event.relative.y * Global.MOUSE_SENSITIVITY, Global.MOUSE_Y_MIN, Global.MOUSE_Y_MAX) 32 | 33 | # Update the latest mouse position 34 | if event is InputEventMouse: 35 | _latest_mouse_pos = event.position 36 | 37 | func _process(delta : float) -> void: 38 | var camera : Camera3D = $Pivot/CameraMountFirstPerson/z/Camera3D 39 | 40 | # Get new camera angles 41 | _camera_x_new = lerp(_camera_x_new, _camera_x, delta * Global.MOUSE_ACCELERATION_X) 42 | _camera_y_new = lerp(_camera_y_new, _camera_y, delta * Global.MOUSE_ACCELERATION_Y) 43 | self.rotation_degrees.y = _camera_x_new 44 | 45 | # Update camera angles 46 | #camera = $Pivot/CameraMountFirstPerson/z/Camera3D 47 | var z = $Pivot/CameraMountFirstPerson/z 48 | z.rotation_degrees.x = lerp(z.rotation_degrees.x, _camera_y, delta * Global.MOUSE_ACCELERATION_Y) 49 | 50 | # Check keyboard input 51 | _input_vector = Vector3.ZERO 52 | _input_vector.x = Input.get_action_strength("MoveRight") - Input.get_action_strength("MoveLeft") 53 | var input_y = Input.get_action_strength("MoveBack") - Input.get_action_strength("MoveForward") 54 | _input_vector.z = input_y 55 | _input_vector = _input_vector.normalized() 56 | 57 | # Get ray where camera is pointing 58 | var target := Vector3.INF 59 | var ray_length := 300 60 | var from := camera.project_ray_origin(_latest_mouse_pos) 61 | var to := from + camera.project_ray_normal(_latest_mouse_pos) * ray_length 62 | var space_state := get_world_3d().direct_space_state 63 | var collision_mask := 0 64 | collision_mask |= Global.Layers.terrain | Global.Layers.item | Global.Layers.furniture | Global.Layers.structure | Global.Layers.body_part 65 | var query := PhysicsRayQueryParameters3D.create(from, to, collision_mask) 66 | var result := space_state.intersect_ray(query) 67 | target = result.position if result else to 68 | 69 | # Make player aim where ray is pointing 70 | if target != Vector3.INF: 71 | var arm := $Pivot/RShoulder 72 | Global.safe_look_at(arm, target) 73 | _target_pos = target 74 | 75 | func _physics_process(delta : float) -> void: 76 | # Check if moving 77 | var input_direction : Vector3 = (_input_vector.x * transform.basis.x) + (_input_vector.z * transform.basis.z) 78 | var is_moving : bool = input_direction != Vector3.ZERO 79 | var is_sprinting : bool = Input.is_action_pressed("Sprint") and is_moving 80 | 81 | # Velocity 82 | var max_velocity := 0.0 83 | if is_sprinting: 84 | max_velocity = VELOCITY_SPRINT 85 | else: 86 | max_velocity = VELOCITY_WALK 87 | 88 | # Acceleration 89 | var acceleration := ACCELERATION_SPRINT if is_sprinting else ACCELERATION_WALK 90 | if is_moving: 91 | self.velocity.x = self.velocity.move_toward(input_direction * max_velocity, acceleration * delta).x 92 | self.velocity.z = self.velocity.move_toward(input_direction * max_velocity, acceleration * delta).z 93 | 94 | # Body rotation 95 | $Pivot.rotation.y = 0.0 96 | 97 | # Ground and air friction 98 | if not is_moving: 99 | if is_on_floor(): 100 | self.velocity = self.velocity.move_toward(Vector3.ZERO, Global.FLOOR_FRICTION * delta) 101 | else: 102 | self.velocity.x = self.velocity.move_toward(input_direction * max_velocity, Global.AIR_FRICTION * delta).x 103 | self.velocity.z = self.velocity.move_toward(input_direction * max_velocity, Global.AIR_FRICTION * delta).z 104 | 105 | # Gravity 106 | if not self.is_on_floor(): 107 | self.velocity.y = clampf(self.velocity.y - GRAVITY * delta, -GRAVITY, JUMP_IMPULSE) 108 | 109 | self.move_and_slide() 110 | -------------------------------------------------------------------------------- /project/src/Player/player.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=3 uid="uid://b0f33fnycivoi"] 2 | 3 | [ext_resource type="Script" path="res://src/Player/player.gd" id="1_lteki"] 4 | 5 | [sub_resource type="CylinderMesh" id="CylinderMesh_7d2us"] 6 | top_radius = 0.1 7 | bottom_radius = 0.1 8 | height = 1.0 9 | 10 | [sub_resource type="CylinderMesh" id="CylinderMesh_bfa7x"] 11 | top_radius = 0.01 12 | bottom_radius = 0.01 13 | height = 300.0 14 | 15 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_rmxfm"] 16 | 17 | [sub_resource type="CapsuleMesh" id="CapsuleMesh_a3s1l"] 18 | 19 | [node name="Player" type="CharacterBody3D"] 20 | collision_layer = 4 21 | collision_mask = 73 22 | script = ExtResource("1_lteki") 23 | 24 | [node name="HandLocation" type="Node3D" parent="."] 25 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.42455, -2.21483) 26 | 27 | [node name="ThrowAngle" type="Node3D" parent="."] 28 | transform = Transform3D(1, 0, 0, 0, 0.984808, -0.173648, 0, 0.173648, 0.984808, 0, 0, 0) 29 | 30 | [node name="Pivot" type="Node3D" parent="."] 31 | 32 | [node name="RShoulder" type="Node3D" parent="Pivot"] 33 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1.5, 0) 34 | 35 | [node name="Arm" type="MeshInstance3D" parent="Pivot/RShoulder"] 36 | transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, -0.5) 37 | mesh = SubResource("CylinderMesh_7d2us") 38 | 39 | [node name="MeshInstance3D" type="MeshInstance3D" parent="Pivot/RShoulder/Arm"] 40 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 150, 0) 41 | visible = false 42 | mesh = SubResource("CylinderMesh_bfa7x") 43 | 44 | [node name="BulletStart" type="Node3D" parent="Pivot/RShoulder/Arm"] 45 | transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.5, 0) 46 | 47 | [node name="CameraMountFirstPerson" type="Node3D" parent="Pivot"] 48 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.49611, 0) 49 | 50 | [node name="z" type="Node3D" parent="Pivot/CameraMountFirstPerson"] 51 | 52 | [node name="Camera3D" type="Camera3D" parent="Pivot/CameraMountFirstPerson/z"] 53 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.22768, -0.0646873) 54 | 55 | [node name="AimingAt" type="Node3D" parent="Pivot/CameraMountFirstPerson/z/Camera3D"] 56 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -100) 57 | 58 | [node name="CollisionShape3D" type="CollisionShape3D" parent="."] 59 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) 60 | shape = SubResource("CapsuleShape3D_rmxfm") 61 | 62 | [node name="MeshInstance3D" type="MeshInstance3D" parent="."] 63 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) 64 | mesh = SubResource("CapsuleMesh_a3s1l") 65 | -------------------------------------------------------------------------------- /project/src/Rock/Rock.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends RigidBody3D 6 | 7 | 8 | @onready var _ray : ShapeCast3D = $ShapeCast3D 9 | var _prev_origin := Vector3.INF 10 | var _is_shape_casting := true 11 | var _is_started := false 12 | 13 | func start(origin : Vector3, impulse : Vector3) -> void: 14 | self.global_transform.origin = origin 15 | _prev_origin = origin 16 | self.set_is_shape_casting(true) 17 | self.apply_central_impulse(impulse) 18 | _is_started = true 19 | 20 | func _physics_process(delta : float) -> void: 21 | if not _is_started: return 22 | 23 | var dis := self.global_transform.origin.distance_to(_prev_origin) 24 | #print([dis, self.global_transform.origin.length(), _prev_origin.length()]) 25 | #if dis >= 0.5 and _ray.enabled: 26 | if _ray.enabled: 27 | _ray.global_transform.origin = _prev_origin 28 | _ray.target_position = Vector3(0, 0, -dis) 29 | Global.safe_look_at(_ray, self.global_transform.origin) 30 | _ray.force_shapecast_update() 31 | if _ray.is_colliding(): 32 | for i in _ray.get_collision_count(): 33 | var coll := _ray.get_collider(i) 34 | var point := _ray.get_collision_point(i) 35 | var direction := point - self.global_transform.origin 36 | self.emit_signal("body_entered", coll, direction) 37 | self.global_transform.origin = point 38 | #self.freeze = true 39 | #print(coll) 40 | 41 | _prev_origin = self.global_transform.origin 42 | 43 | func set_is_shape_casting(value : bool) -> void: 44 | _is_shape_casting = value 45 | 46 | $CollisionShape3D/MeshInstance3D.visible = _is_shape_casting 47 | $CollisionShape3D/MeshInstance3D2.visible = not _is_shape_casting 48 | $CollisionShape3D.disabled = _is_shape_casting 49 | $ShapeCast3D.enabled = _is_shape_casting 50 | 51 | func _on_body_entered(body, direction := Vector3.INF) -> void: 52 | #print(["_on_body_entered", body, direction]) 53 | if direction != Vector3.INF and _is_shape_casting and body.has_method("apply_central_impulse"): 54 | #print(body) 55 | var mass := self.mass 56 | var vel := self.linear_velocity.length() 57 | var angle := -direction 58 | var force := mass * vel 59 | body.apply_central_impulse(force * angle) 60 | 61 | self.set_is_shape_casting(false) 62 | -------------------------------------------------------------------------------- /project/src/Rock/Rock.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=8 format=3 uid="uid://cbaya4s3caaxn"] 2 | 3 | [ext_resource type="Script" path="res://src/Rock/Rock.gd" id="1_gmr2c"] 4 | 5 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_k8vju"] 6 | height = 0.122 7 | radius = 0.033 8 | 9 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vohx8"] 10 | albedo_color = Color(0, 0, 1, 1) 11 | 12 | [sub_resource type="CylinderMesh" id="CylinderMesh_o86g4"] 13 | material = SubResource("StandardMaterial3D_vohx8") 14 | top_radius = 0.033 15 | bottom_radius = 0.033 16 | height = 0.122 17 | 18 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0ylg3"] 19 | albedo_color = Color(1, 0, 0, 1) 20 | 21 | [sub_resource type="CylinderMesh" id="CylinderMesh_duukx"] 22 | material = SubResource("StandardMaterial3D_0ylg3") 23 | top_radius = 0.033 24 | bottom_radius = 0.033 25 | height = 0.122 26 | 27 | [sub_resource type="CylinderShape3D" id="CylinderShape3D_n6k3s"] 28 | height = 0.122 29 | radius = 0.033 30 | 31 | [node name="Rock" type="RigidBody3D" groups=["item"]] 32 | collision_layer = 2 33 | collision_mask = 8295 34 | mass = 0.38 35 | max_contacts_reported = 3 36 | contact_monitor = true 37 | script = ExtResource("1_gmr2c") 38 | 39 | [node name="CollisionShape3D" type="CollisionShape3D" parent="."] 40 | shape = SubResource("CylinderShape3D_k8vju") 41 | disabled = true 42 | 43 | [node name="MeshInstance3D" type="MeshInstance3D" parent="CollisionShape3D"] 44 | mesh = SubResource("CylinderMesh_o86g4") 45 | 46 | [node name="MeshInstance3D2" type="MeshInstance3D" parent="CollisionShape3D"] 47 | visible = false 48 | mesh = SubResource("CylinderMesh_duukx") 49 | 50 | [node name="ShapeCast3D" type="ShapeCast3D" parent="."] 51 | shape = SubResource("CylinderShape3D_n6k3s") 52 | target_position = Vector3(0, 0, 0) 53 | collision_mask = 8295 54 | 55 | [connection signal="body_entered" from="." to="." method="_on_body_entered"] 56 | -------------------------------------------------------------------------------- /project/src/Singletons/Global.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends Node 6 | 7 | const INT32_MAX := int(int(pow(2, 31)) - 1) 8 | const INT64_MAX := int(int(pow(2, 63)) - 1) 9 | const FLOAT64_MAX := float(INT64_MAX) 10 | 11 | const AIR_FRICTION := 10.0 12 | const FLOOR_FRICTION := 60.0 13 | const MOUSE_SENSITIVITY := 0.1 14 | const MOUSE_ACCELERATION_X := 10.0 15 | const MOUSE_ACCELERATION_Y := 10.0 16 | const MOUSE_Y_MAX := 70.0 17 | const MOUSE_Y_VEHICLE_MIN := -10.0 18 | const MOUSE_Y_VEHICLE_MAX := 10.0 19 | const MOUSE_Y_MIN := -60.0 20 | 21 | @onready var _scene_bullet := ResourceLoader.load("res://src/Bullet/bullet.tscn") 22 | @onready var _scene_bullet_glow := ResourceLoader.load("res://src/BulletGlow/bullet_glow.tscn") 23 | @onready var _scene_bullet_spark := ResourceLoader.load("res://src/BulletSpark/bullet_spark.tscn") 24 | 25 | enum Layers { 26 | terrain = 1 << 0, 27 | item = 1 << 1, 28 | player = 1 << 2, 29 | npc = 1 << 3, 30 | position_trigger = 1 << 4, 31 | furniture = 1 << 5, 32 | structure = 1 << 6, 33 | interact_point = 1 << 7, 34 | vehicle = 1 << 8, 35 | destructible = 1 << 9, 36 | smell = 1 << 10, 37 | sun = 1 << 11, 38 | liquid = 1 << 12, 39 | body_part = 1 << 13, 40 | animal = 1 << 14, 41 | label = 1 << 15, 42 | temperature = 1 << 16, 43 | } 44 | 45 | enum BodyPart { 46 | Head = 1 << 0, 47 | TorsoUpper = 1 << 1, 48 | TorsoMiddle = 1 << 2, 49 | TorsoLower = 1 << 3, 50 | Pelvis = 1 << 4, 51 | UpperArmL = 1 << 5, 52 | UpperArmR = 1 << 6, 53 | LowerArmL = 1 << 7, 54 | LowerArmR = 1 << 8, 55 | HandL = 1 << 9, 56 | HandR = 1 << 10, 57 | UpperLegL = 1 << 11, 58 | UpperLegR = 1 << 12, 59 | LowerLegL = 1 << 13, 60 | LowerLegR = 1 << 14, 61 | FootL = 1 << 15, 62 | FootR = 1 << 16, 63 | } 64 | 65 | enum BodyPartStatus { 66 | Normal, 67 | Crippled, 68 | Destroyed 69 | } 70 | 71 | enum BulletType { 72 | _50BMG, 73 | _308, 74 | _556, 75 | _45, 76 | _9MM, 77 | _22LR, 78 | _12Gauge, 79 | } 80 | 81 | const DB = { 82 | "Bullets" : { 83 | BulletType._50BMG : { 84 | "mass" : 0.023, 85 | "speed" : 1219.0, 86 | "max_distance" : 5000.0, 87 | }, 88 | BulletType._308 : { 89 | "mass" : 0.018, 90 | "speed" : 1219.0, 91 | "max_distance" : 5000.0, 92 | }, 93 | BulletType._556 : { 94 | "mass" : 0.016, 95 | "speed" : 1219.0, 96 | "max_distance" : 5000.0, 97 | }, 98 | BulletType._45 : { 99 | "mass" : 0.0099, 100 | "speed" : 300.0, 101 | "max_distance" : 2000.0, 102 | }, 103 | BulletType._9MM : { 104 | "mass" : 0.0075, 105 | "speed" : 400.0, 106 | "max_distance" : 2000.0, 107 | }, 108 | BulletType._22LR : { 109 | "mass" : 0.0050, 110 | "speed" : 300.0, 111 | "max_distance" : 2000.0, 112 | }, 113 | BulletType._12Gauge : { 114 | "mass" : 0.0025, 115 | "speed" : 200.0, 116 | "max_distance" : 500.0, 117 | }, 118 | } 119 | } 120 | 121 | # Scales a transform without affecting the origin 122 | func transform_shrink(tran : Transform3D, percent : float) -> Transform3D: 123 | var origin := tran.origin 124 | tran = tran.scaled(Vector3.ONE * percent) 125 | tran.origin = origin 126 | return tran 127 | 128 | func rand_vector(min_val : float, max_val : float) -> Vector3: 129 | return Vector3( 130 | randf_range(min_val, max_val), 131 | randf_range(min_val, max_val), 132 | randf_range(min_val, max_val) 133 | ) 134 | 135 | func array_random_index(array : Array) -> int: 136 | var i : int = randi_range(0, array.size() - 1) 137 | return i 138 | 139 | func array_random_value(array : Array): 140 | var i : int = array_random_index(array) 141 | return array[i] 142 | 143 | func enum_all_values(the_enum : Dictionary) -> int: 144 | var retval := 0 145 | for values in the_enum.values(): 146 | retval += values 147 | return retval 148 | 149 | func enum_name_from_value(the_enum : Dictionary, enum_value : int) -> String: 150 | for entry in the_enum: 151 | var value = the_enum[entry] 152 | if value == enum_value: 153 | return entry 154 | 155 | return "" 156 | 157 | func enum_max_value(the_enum : Dictionary) -> int: 158 | var max_value := -1 159 | for value in the_enum.values(): 160 | if value > max_value: 161 | max_value = value 162 | 163 | return max_value 164 | 165 | func recursively_get_all_children(target : Node) -> Array: 166 | var matches := [] 167 | var to_search := [target] 168 | while not to_search.is_empty(): 169 | var entry = to_search.pop_front() 170 | 171 | for child in entry.get_children(): 172 | to_search.append(child) 173 | 174 | matches.append(entry) 175 | 176 | return matches 177 | 178 | func recursively_get_all_children_in_filter(target : Node, filter_cb : Callable) -> Array: 179 | var matches := [] 180 | var to_search := [target] 181 | while not to_search.is_empty(): 182 | var entry = to_search.pop_front() 183 | 184 | for child in entry.get_children(): 185 | to_search.append(child) 186 | 187 | if filter_cb.call(entry): 188 | matches.append(entry) 189 | 190 | return matches 191 | 192 | func recursively_get_all_children_in_group(target : Node, group_name : String) -> Array: 193 | var matches := [] 194 | var to_search := [target] 195 | while not to_search.is_empty(): 196 | var entry = to_search.pop_front() 197 | 198 | for child in entry.get_children(): 199 | to_search.append(child) 200 | 201 | if entry.is_in_group(group_name): 202 | matches.append(entry) 203 | 204 | return matches 205 | 206 | func get_input_action_name(event : InputEvent) -> String: 207 | # Get the action name for the key pressed 208 | #print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") 209 | for action in InputMap.get_actions(): 210 | for entry in InputMap.action_get_events(action): 211 | if entry is InputEventKey and event is InputEventKey: 212 | if event.physical_keycode == entry.physical_keycode: 213 | return action 214 | elif entry is InputEventMouseButton and event is InputEventMouseButton: 215 | return action 216 | 217 | #print("###################################") 218 | return "" 219 | 220 | const bone_names := { 221 | BodyPart.Head : [ 222 | "mixamorig_Neck", 223 | "mixamorig_Head", 224 | ], 225 | BodyPart.TorsoUpper : [ 226 | "mixamorig_Spine2", 227 | "mixamorig_LeftShoulder", 228 | "mixamorig_RightShoulder", 229 | ], 230 | BodyPart.TorsoMiddle : [ 231 | "mixamorig_Spine1", 232 | ], 233 | BodyPart.TorsoLower : [ 234 | "mixamorig_Spine", 235 | ], 236 | BodyPart.Pelvis : [ 237 | "mixamorig_Hips", 238 | ], 239 | BodyPart.UpperArmL : [ 240 | "mixamorig_LeftArm", 241 | ], 242 | BodyPart.UpperArmR : [ 243 | "mixamorig_RightArm", 244 | ], 245 | BodyPart.LowerArmL : [ 246 | "mixamorig_LeftForeArm", 247 | ], 248 | BodyPart.LowerArmR : [ 249 | "mixamorig_RightForeArm", 250 | ], 251 | BodyPart.HandL : [ 252 | "mixamorig_LeftHand", 253 | "mixamorig_LeftHandThumb1", 254 | "mixamorig_LeftHandThumb2", 255 | "mixamorig_LeftHandThumb3", 256 | "mixamorig_LeftHandIndex1", 257 | "mixamorig_LeftHandIndex2", 258 | "mixamorig_LeftHandIndex3", 259 | "mixamorig_LeftHandMiddle1", 260 | "mixamorig_LeftHandMiddle2", 261 | "mixamorig_LeftHandMiddle3", 262 | "mixamorig_LeftHandRing1", 263 | "mixamorig_LeftHandRing2", 264 | "mixamorig_LeftHandRing3", 265 | "mixamorig_LeftHandPinky1", 266 | "mixamorig_LeftHandPinky2", 267 | "mixamorig_LeftHandPinky3", 268 | ], 269 | BodyPart.HandR : [ 270 | "mixamorig_RightHand", 271 | "mixamorig_RightHandThumb1", 272 | "mixamorig_RightHandThumb2", 273 | "mixamorig_RightHandThumb3", 274 | "mixamorig_RightHandIndex1", 275 | "mixamorig_RightHandIndex2", 276 | "mixamorig_RightHandIndex3", 277 | "mixamorig_RightHandMiddle1", 278 | "mixamorig_RightHandMiddle2", 279 | "mixamorig_RightHandMiddle3", 280 | "mixamorig_RightHandRing1", 281 | "mixamorig_RightHandRing2", 282 | "mixamorig_RightHandRing3", 283 | "mixamorig_RightHandPinky1", 284 | "mixamorig_RightHandPinky2", 285 | "mixamorig_RightHandPinky3", 286 | ], 287 | BodyPart.UpperLegL : [ 288 | "mixamorig_LeftUpLeg", 289 | ], 290 | BodyPart.UpperLegR : [ 291 | "mixamorig_RightUpLeg", 292 | ], 293 | BodyPart.LowerLegL : [ 294 | "mixamorig_LeftLeg", 295 | ], 296 | BodyPart.LowerLegR : [ 297 | "mixamorig_RightLeg", 298 | ], 299 | BodyPart.FootL : [ 300 | "mixamorig_LeftFoot", 301 | "mixamorig_LeftToeBase", 302 | ], 303 | BodyPart.FootR : [ 304 | "mixamorig_RightFoot", 305 | "mixamorig_RightToeBase", 306 | ], 307 | } 308 | 309 | func body_parts_2_animation_bones(body_parts : int) -> Array: 310 | var values := [] 311 | 312 | for key in BodyPart.values(): 313 | if body_parts & key > 0: 314 | for entry in bone_names[key]: 315 | values.append(entry) 316 | 317 | return values 318 | 319 | func physical_bone_2_body_part(entry : String) -> int: 320 | for body_part_value in bone_names: 321 | #print(body_part_value) 322 | var animations = bone_names[body_part_value] 323 | for animation in animations: 324 | if entry == animation: 325 | return body_part_value 326 | return -1 327 | 328 | func get_skeleton_mount_bone(skeleton : Skeleton3D, body_part : Global.BodyPart) -> PhysicalBone3D: 329 | var mount_bone : PhysicalBone3D = null 330 | 331 | match body_part: 332 | Global.BodyPart.Head: 333 | var entry = Global.body_parts_2_animation_bones(Global.BodyPart.Head)[0] 334 | mount_bone = skeleton.get_node("Physical Bone %s" % [entry]) 335 | Global.BodyPart.TorsoUpper, Global.BodyPart.TorsoMiddle, Global.BodyPart.TorsoLower: 336 | pass 337 | Global.BodyPart.Pelvis: 338 | pass 339 | Global.BodyPart.UpperArmR, Global.BodyPart.LowerArmR, Global.BodyPart.HandR: 340 | var entry = Global.body_parts_2_animation_bones(Global.BodyPart.UpperArmR)[0] 341 | mount_bone = skeleton.get_node("Physical Bone %s" % [entry]) 342 | Global.BodyPart.UpperArmL, Global.BodyPart.LowerArmL, Global.BodyPart.HandL: 343 | var entry = Global.body_parts_2_animation_bones(Global.BodyPart.UpperArmL)[0] 344 | mount_bone = skeleton.get_node("Physical Bone %s" % [entry]) 345 | Global.BodyPart.UpperLegR, Global.BodyPart.LowerLegR, Global.BodyPart.FootR: 346 | var entry = Global.body_parts_2_animation_bones(Global.BodyPart.UpperLegR)[0] 347 | mount_bone = skeleton.get_node("Physical Bone %s" % [entry]) 348 | Global.BodyPart.UpperLegL, Global.BodyPart.LowerLegL, Global.BodyPart.FootL: 349 | var entry = Global.body_parts_2_animation_bones(Global.BodyPart.UpperLegL)[0] 350 | mount_bone = skeleton.get_node("Physical Bone %s" % [entry]) 351 | _: 352 | push_error("Unexpected Global.BodyPart: %s" % [body_part]) 353 | 354 | return mount_bone 355 | 356 | func get_skeleton_animation_bones(skeleton : Skeleton3D, body_part : Global.BodyPart) -> Array: 357 | var animation_bones := [] 358 | 359 | match body_part: 360 | Global.BodyPart.Head: 361 | animation_bones = Global.body_parts_2_animation_bones(Global.BodyPart.Head) 362 | Global.BodyPart.TorsoUpper, Global.BodyPart.TorsoMiddle, Global.BodyPart.TorsoLower: 363 | pass 364 | Global.BodyPart.Pelvis: 365 | pass 366 | Global.BodyPart.UpperArmR, Global.BodyPart.LowerArmR, Global.BodyPart.HandR: 367 | animation_bones = Global.body_parts_2_animation_bones(Global.BodyPart.UpperArmR | Global.BodyPart.LowerArmR | Global.BodyPart.HandR) 368 | Global.BodyPart.UpperArmL, Global.BodyPart.LowerArmL, Global.BodyPart.HandL: 369 | animation_bones = Global.body_parts_2_animation_bones(Global.BodyPart.UpperArmL | Global.BodyPart.LowerArmL | Global.BodyPart.HandL) 370 | Global.BodyPart.UpperLegR, Global.BodyPart.LowerLegR, Global.BodyPart.FootR: 371 | animation_bones = Global.body_parts_2_animation_bones(Global.BodyPart.UpperLegR | Global.BodyPart.LowerLegR | Global.BodyPart.FootR) 372 | Global.BodyPart.UpperLegL, Global.BodyPart.LowerLegL, Global.BodyPart.FootL: 373 | animation_bones = Global.body_parts_2_animation_bones(Global.BodyPart.UpperLegL | Global.BodyPart.LowerLegL | Global.BodyPart.FootL) 374 | _: 375 | push_error("Unexpected Global.BodyPart: %s" % [body_part]) 376 | 377 | return animation_bones 378 | 379 | func get_skeleton_tuck_bone(skeleton : Skeleton3D, body_part : Global.BodyPart) -> int: 380 | var tuck_bone_id := -1 381 | match body_part: 382 | Global.BodyPart.Head: 383 | tuck_bone_id = skeleton.find_bone(Global.bone_names[Global.BodyPart.TorsoUpper][0]) 384 | Global.BodyPart.TorsoUpper, Global.BodyPart.TorsoMiddle, Global.BodyPart.TorsoLower: 385 | pass 386 | Global.BodyPart.Pelvis: 387 | pass 388 | Global.BodyPart.UpperArmR, Global.BodyPart.LowerArmR, Global.BodyPart.HandR: 389 | tuck_bone_id = skeleton.find_bone(Global.bone_names[Global.BodyPart.TorsoMiddle][0]) 390 | Global.BodyPart.UpperArmL, Global.BodyPart.LowerArmL, Global.BodyPart.HandL: 391 | tuck_bone_id = skeleton.find_bone(Global.bone_names[Global.BodyPart.TorsoMiddle][0]) 392 | Global.BodyPart.UpperLegR, Global.BodyPart.LowerLegR, Global.BodyPart.FootR: 393 | tuck_bone_id = skeleton.find_bone(Global.bone_names[Global.BodyPart.Pelvis][0]) 394 | Global.BodyPart.UpperLegL, Global.BodyPart.LowerLegL, Global.BodyPart.FootL: 395 | tuck_bone_id = skeleton.find_bone(Global.bone_names[Global.BodyPart.Pelvis][0]) 396 | _: 397 | push_error("Unexpected Global.BodyPart: %s" % [body_part]) 398 | 399 | return tuck_bone_id 400 | 401 | func hookes_law(displacement : Vector3, current_velocity : Vector3, stiffness : float, damping : float) -> Vector3: 402 | return (stiffness * displacement) - (damping * current_velocity) 403 | 404 | func safe_look_at(spatial : Node3D, target: Vector3) -> void: 405 | var origin : Vector3 = spatial.global_transform.origin 406 | var v_z := (origin - target).normalized() 407 | 408 | # Just return if at same position 409 | if origin == target: 410 | return 411 | 412 | # Find an up vector that we can rotate around 413 | var up := Vector3.ZERO 414 | for entry in [Vector3.UP, Vector3.RIGHT, Vector3.BACK]: 415 | var v_x : Vector3 = entry.cross(v_z).normalized() 416 | if v_x.length() != 0: 417 | up = entry 418 | break 419 | 420 | # Look at the target 421 | if up != Vector3.ZERO: 422 | spatial.look_at(target, up) 423 | 424 | func create_bullet_spark(pos : Vector3) -> void: 425 | var spark = _scene_bullet_spark.instantiate() 426 | Global._world.add_child(spark) 427 | spark.global_transform.origin = pos 428 | 429 | func create_bullet(parent : Node, start_pos : Vector3, target_pos : Vector3, bullet_type : BulletType, spread : float) -> void: 430 | var bullet = _scene_bullet.instantiate() 431 | parent.add_child(bullet) 432 | bullet.global_transform.origin = start_pos 433 | Global.safe_look_at(bullet, target_pos) 434 | 435 | var rand = Global.rand_vector(-spread, spread) 436 | #print(rand) 437 | bullet.rotate_x(deg_to_rad(rand.x)) 438 | bullet.rotate_y(deg_to_rad(rand.y)) 439 | bullet.rotate_z(deg_to_rad(rand.z)) 440 | 441 | bullet.start(bullet_type) 442 | 443 | var _world : Node = null 444 | -------------------------------------------------------------------------------- /project/src/Structures/Building/building.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=3 uid="uid://xndqc8p275ut"] 2 | 3 | [sub_resource type="BoxShape3D" id="BoxShape3D_iymip"] 4 | size = Vector3(20, 20, 20) 5 | 6 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_adt8r"] 7 | albedo_color = Color(0.984314, 1, 0, 1) 8 | 9 | [sub_resource type="BoxMesh" id="BoxMesh_7mvy7"] 10 | material = SubResource("StandardMaterial3D_adt8r") 11 | size = Vector3(20, 20, 20) 12 | 13 | [node name="Building" type="StaticBody3D"] 14 | collision_layer = 64 15 | collision_mask = 0 16 | 17 | [node name="CollisionShape3D" type="CollisionShape3D" parent="."] 18 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0) 19 | shape = SubResource("BoxShape3D_iymip") 20 | 21 | [node name="MeshInstance3D" type="MeshInstance3D" parent="CollisionShape3D"] 22 | mesh = SubResource("BoxMesh_7mvy7") 23 | -------------------------------------------------------------------------------- /project/src/Structures/Floor/floor.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=3 uid="uid://c5hdi8jbrguk3"] 2 | 3 | [ext_resource type="Texture2D" uid="uid://du2fgctptabbl" path="res://assets/sand.png" id="1_33eu6"] 4 | 5 | [sub_resource type="BoxShape3D" id="BoxShape3D_3fbxs"] 6 | size = Vector3(1000, 2, 1000) 7 | 8 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gc774"] 9 | albedo_texture = ExtResource("1_33eu6") 10 | uv1_triplanar = true 11 | 12 | [sub_resource type="BoxMesh" id="BoxMesh_xbutq"] 13 | material = SubResource("StandardMaterial3D_gc774") 14 | size = Vector3(1000, 2, 1000) 15 | 16 | [node name="Floor" type="StaticBody3D"] 17 | collision_mask = 0 18 | 19 | [node name="CollisionShape3D" type="CollisionShape3D" parent="."] 20 | shape = SubResource("BoxShape3D_3fbxs") 21 | 22 | [node name="MeshInstance3D" type="MeshInstance3D" parent="."] 23 | mesh = SubResource("BoxMesh_xbutq") 24 | -------------------------------------------------------------------------------- /project/src/World/world.gd: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021-2023 Matthew Brennan Jones 2 | # This file is licensed under the MIT License 3 | # https://github.com/ImmersiveRPG/ExampleRagdoll 4 | 5 | extends Node3D 6 | 7 | # TODO: 8 | #. rename branch v1 and v2 to part1_godot3 and part2_godot3 9 | #. Add 2 NPCs to make sure they are separate. 10 | #. _duplicate_body_part_into_own_skeleton calls BrokenBodyPart.start. Combine both into one function. 11 | #. Make broken off limbs so they can be grabbed, thrown, and used as a melee weapon 12 | #. Fix gaps between floppy limb joints 13 | #. Blood splatter and decals 14 | #. Add animation for NPC: 15 | # . Getting up off ground 16 | # . Walking with injured leg 17 | # . Holding injured arm 18 | # Add dragging bodies like in Deus Ex 19 | 20 | 21 | func _init() -> void: 22 | Global._world = self 23 | 24 | func _ready() -> void: 25 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) 26 | 27 | func _input(event : InputEvent) -> void: 28 | # Just return if it is a keypress release or echo 29 | var key_event := event as InputEventKey 30 | if key_event and (not key_event.pressed or key_event.echo): 31 | return 32 | 33 | # Just return if it is a mouse button release 34 | var mouse_event := event as InputEventMouseButton 35 | if mouse_event and not mouse_event.pressed: 36 | return 37 | 38 | # Get the action name for the input pressed 39 | var man = $NPC._mannequin 40 | var force := 5.0 41 | match Global.get_input_action_name(event): 42 | "ThrowCola": 43 | #Engine.time_scale = 0.1 44 | var cb := func(org : Vector3, angle : Vector3, force : float): 45 | var rock_scene : PackedScene = ResourceLoader.load("res://src/Rock/Rock.tscn") 46 | var rock := rock_scene.instantiate() 47 | Global._world.add_child(rock) 48 | rock.start(org, angle * force) 49 | 50 | var org : Vector3 = $Player/HandLocation.global_transform.origin 51 | var angle : Vector3 = -$Player/Pivot/CameraMountFirstPerson/z.global_transform.basis.z 52 | for i in 10: 53 | cb.call(org, angle, 5.0) 54 | "ShootBullet": 55 | var cb := func(start_pos : Vector3, target_pos : Vector3): 56 | # Create bullet 57 | var spread := 0.0 58 | var bullet_type := Global.BulletType._308 59 | Global.create_bullet(Global._world, start_pos, target_pos, bullet_type, spread) 60 | 61 | var start_pos = $Player/Pivot/RShoulder/Arm/BulletStart.global_transform.origin 62 | var target_pos = $Player._target_pos 63 | for i in 1: 64 | cb.call(start_pos, target_pos) 65 | "ThrowNPC": 66 | $NPC.die() 67 | var angle = -$Player/ThrowAngle.global_transform.basis.z 68 | man.push_at_angle(angle, 500.0) 69 | "NpcDie": 70 | if not $NPC._is_dead: 71 | $NPC.die() 72 | else: 73 | $NPC.live() 74 | "NPCMove": 75 | $NPC._path_marker = [Vector3(0, 0, 10), Vector3(10, 0, 0), Vector3(0, 0, -10), Vector3(-10, 0, 0)] 76 | "BreakEverything": 77 | var breaks := [ 78 | Global.BodyPart.UpperArmR, 79 | Global.BodyPart.UpperArmL, 80 | Global.BodyPart.UpperLegR, 81 | Global.BodyPart.UpperLegL, 82 | Global.BodyPart.Head, 83 | ] 84 | for body_part in breaks: 85 | var status = man._body_part_status[body_part] 86 | status = clampi(status + 1, 0, Global.enum_max_value(Global.BodyPartStatus)) 87 | man.set_body_part_status(body_part, status) 88 | "BreakRightArm": 89 | var status = man._body_part_status[Global.BodyPart.UpperArmR] 90 | status = clampi(status + 1, 0, Global.enum_max_value(Global.BodyPartStatus)) 91 | man.set_body_part_status(Global.BodyPart.UpperArmR, status) 92 | "BreakLeftArm": 93 | var status = man._body_part_status[Global.BodyPart.UpperArmL] 94 | status = clampi(status + 1, 0, Global.enum_max_value(Global.BodyPartStatus)) 95 | man.set_body_part_status(Global.BodyPart.UpperArmL, status) 96 | "BreakRightLeg": 97 | var status = man._body_part_status[Global.BodyPart.UpperLegR] 98 | status = clampi(status + 1, 0, Global.enum_max_value(Global.BodyPartStatus)) 99 | man.set_body_part_status(Global.BodyPart.UpperLegR, status) 100 | "BreakLeftLeg": 101 | var status = man._body_part_status[Global.BodyPart.UpperLegL] 102 | status = clampi(status + 1, 0, Global.enum_max_value(Global.BodyPartStatus)) 103 | man.set_body_part_status(Global.BodyPart.UpperLegL, status) 104 | "BreakHead": 105 | var status = man._body_part_status[Global.BodyPart.Head] 106 | status = clampi(status + 1, 0, Global.enum_max_value(Global.BodyPartStatus)) 107 | man.set_body_part_status(Global.BodyPart.Head, status) 108 | "ToggleMouseCapture": 109 | if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: 110 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) 111 | else: 112 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) 113 | "ToggleFullScreen": 114 | if DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_FULLSCREEN: 115 | DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) 116 | else: 117 | DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) 118 | "Quit": 119 | self.get_tree().root.propagate_notification(NOTIFICATION_WM_CLOSE_REQUEST) 120 | self.get_tree().quit() 121 | 122 | func _on_timer_fps_timeout() -> void: 123 | $LabelFPS.text = "FPS: %s" % [Engine.get_frames_per_second()] 124 | -------------------------------------------------------------------------------- /project/src/World/world.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=15 format=3 uid="uid://bc2abgm8k46u5"] 2 | 3 | [ext_resource type="PackedScene" uid="uid://c5hdi8jbrguk3" path="res://src/Structures/Floor/floor.tscn" id="1_h1x00"] 4 | [ext_resource type="Script" path="res://src/World/world.gd" id="1_tpmoq"] 5 | [ext_resource type="Texture2D" uid="uid://bhtx5f5lxr5l8" path="res://assets/cross_hairs.png" id="2_1r4t1"] 6 | [ext_resource type="PackedScene" uid="uid://xndqc8p275ut" path="res://src/Structures/Building/building.tscn" id="2_kwael"] 7 | [ext_resource type="PackedScene" uid="uid://b0f33fnycivoi" path="res://src/Player/player.tscn" id="4_44sfq"] 8 | [ext_resource type="PackedScene" uid="uid://3m43sql38uyt" path="res://src/NPC/npc.tscn" id="4_obtq5"] 9 | [ext_resource type="PackedScene" uid="uid://uryxar8xt0rv" path="res://src/ShootingDisplayOfCans/shooting_display_of_cans.tscn" id="7_wan5n"] 10 | 11 | [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_o6jpc"] 12 | 13 | [sub_resource type="Sky" id="Sky_3qumk"] 14 | sky_material = SubResource("ProceduralSkyMaterial_o6jpc") 15 | 16 | [sub_resource type="Environment" id="Environment_obw8q"] 17 | background_mode = 2 18 | background_color = Color(0, 0.607843, 0, 1) 19 | sky = SubResource("Sky_3qumk") 20 | ambient_light_source = 3 21 | reflected_light_source = 2 22 | volumetric_fog_enabled = true 23 | volumetric_fog_density = 0.0 24 | 25 | [sub_resource type="BoxShape3D" id="BoxShape3D_do5bf"] 26 | 27 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bui7f"] 28 | albedo_color = Color(0.941176, 0.568627, 0, 1) 29 | 30 | [sub_resource type="BoxMesh" id="BoxMesh_0ly1q"] 31 | material = SubResource("StandardMaterial3D_bui7f") 32 | 33 | [sub_resource type="FogMaterial" id="FogMaterial_dsst4"] 34 | 35 | [node name="World" type="Node3D"] 36 | script = ExtResource("1_tpmoq") 37 | 38 | [node name="WorldEnvironment" type="WorldEnvironment" parent="."] 39 | environment = SubResource("Environment_obw8q") 40 | 41 | [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] 42 | transform = Transform3D(0.771811, -0.433013, 0.465626, -0.224144, 0.5, 0.836516, -0.595035, -0.75, 0.288849, 0, 21.7168, 0) 43 | shadow_enabled = true 44 | 45 | [node name="LabelFPS" type="Label" parent="."] 46 | offset_right = 87.0 47 | offset_bottom = 38.0 48 | theme_override_colors/font_color = Color(0.901961, 1, 0, 1) 49 | theme_override_colors/font_shadow_color = Color(0, 0, 0, 1) 50 | text = "FPS: ?" 51 | 52 | [node name="CenterContainer" type="CenterContainer" parent="."] 53 | anchors_preset = 8 54 | anchor_left = 0.5 55 | anchor_top = 0.5 56 | anchor_right = 0.5 57 | anchor_bottom = 0.5 58 | grow_horizontal = 2 59 | grow_vertical = 2 60 | 61 | [node name="CrossHairs" type="Sprite2D" parent="CenterContainer"] 62 | texture = ExtResource("2_1r4t1") 63 | 64 | [node name="TimerFPS" type="Timer" parent="."] 65 | autostart = true 66 | 67 | [node name="Block" type="StaticBody3D" parent="."] 68 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0742674, -0.44283, -6.503) 69 | 70 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Block"] 71 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) 72 | shape = SubResource("BoxShape3D_do5bf") 73 | 74 | [node name="MeshInstance3D" type="MeshInstance3D" parent="Block/CollisionShape3D"] 75 | mesh = SubResource("BoxMesh_0ly1q") 76 | 77 | [node name="Building" parent="." instance=ExtResource("2_kwael")] 78 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.159599, 0, -23.6081) 79 | 80 | [node name="Floor" parent="." instance=ExtResource("1_h1x00")] 81 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) 82 | 83 | [node name="NPC" parent="." instance=ExtResource("4_obtq5")] 84 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -5) 85 | 86 | [node name="Player" parent="." instance=ExtResource("4_44sfq")] 87 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.019, 0, 6.242) 88 | 89 | [node name="FogVolume" type="FogVolume" parent="."] 90 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -34, 1, -22.276) 91 | size = Vector3(20, 5, 20) 92 | shape = 2 93 | material = SubResource("FogMaterial_dsst4") 94 | 95 | [node name="Label" type="Label" parent="."] 96 | offset_left = 20.0 97 | offset_top = 40.0 98 | offset_right = 213.0 99 | offset_bottom = 135.0 100 | text = "ESC - Exit 101 | F11 - Toggle full screen 102 | Q - Toggle mouse lock" 103 | 104 | [node name="Label2" type="Label" parent="."] 105 | offset_left = 20.0 106 | offset_top = 200.0 107 | offset_right = 149.0 108 | offset_bottom = 304.0 109 | text = "Player: 110 | WASD - Move 111 | Left Click - Shoot 112 | F - Throw soda 113 | " 114 | 115 | [node name="Label3" type="Label" parent="."] 116 | anchors_preset = 1 117 | anchor_left = 1.0 118 | anchor_right = 1.0 119 | offset_left = -268.0 120 | offset_top = 20.0 121 | offset_right = -57.0 122 | offset_bottom = 236.0 123 | grow_horizontal = 0 124 | text = "NPC: 125 | M - Add new destinations 126 | P - Push NPC 127 | E - Toggle NPC Dead/Alive 128 | 129 | R - Break right arm 130 | T - Break left arm 131 | Y - Break right leg 132 | U - Break left leg 133 | I - Break head 134 | O - Break everything" 135 | 136 | [node name="ShootingDisplayOfCans" parent="." instance=ExtResource("7_wan5n")] 137 | 138 | [connection signal="timeout" from="TimerFPS" to="." method="_on_timer_fps_timeout"] 139 | --------------------------------------------------------------------------------