Kinematic character controller (#11)
This commit is contained in:
250
Cargo.lock
generated
250
Cargo.lock
generated
@@ -94,7 +94,7 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"version_check",
|
"version_check",
|
||||||
"zerocopy",
|
"zerocopy 0.7.35",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -428,37 +428,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bevy-tnua"
|
|
||||||
version = "0.21.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a8a5783db12b6f927e7cc9976c15e23fd5b107319a9c1be8b92622fa10b94a62"
|
|
||||||
dependencies = [
|
|
||||||
"bevy",
|
|
||||||
"bevy-tnua-physics-integration-layer",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bevy-tnua-avian3d"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fb3348f84267ced2c4535bd3415b384df84d49b9d04824442aef7f3b6b3af37c"
|
|
||||||
dependencies = [
|
|
||||||
"avian3d",
|
|
||||||
"bevy",
|
|
||||||
"bevy-tnua-physics-integration-layer",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bevy-tnua-physics-integration-layer"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fbe99d25b7253cb99a00f69fe9accc875645b4ecf9910bb5f24459835ff177e"
|
|
||||||
dependencies = [
|
|
||||||
"bevy",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_a11y"
|
name = "bevy_a11y"
|
||||||
version = "0.15.3"
|
version = "0.15.3"
|
||||||
@@ -996,9 +965,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_materialize"
|
name = "bevy_materialize"
|
||||||
version = "0.4.1"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20040879c95d5f3210eafd7fc00d64e9e75b5cc7eddbedfc752bd9c73b8b12e2"
|
checksum = "9b7309299cf4caf0bf915582a2e3dd5fbd1b564c72611a5f464e6c85ca7f2d23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy",
|
"bevy",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1589,9 +1558,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blake3"
|
name = "blake3"
|
||||||
version = "1.6.1"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "675f87afced0413c9bb02843499dbbd3882a237645883f71a2b59644a6d2f753"
|
checksum = "b17679a8d69b6d7fd9cd9801a536cec9fa5e5970b69f9d4747f70b39b031f5e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
@@ -1645,9 +1614,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck_derive"
|
name = "bytemuck_derive"
|
||||||
version = "1.8.1"
|
version = "1.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a"
|
checksum = "2ff22c2722516255d1823ce3cc4bc0b154dbc9364be5c905d6baa6eccbbc8774"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -2424,9 +2393,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "font-types"
|
name = "font-types"
|
||||||
@@ -2577,9 +2546,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gilrs-core"
|
name = "gilrs-core"
|
||||||
version = "0.6.2"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4ed3920aa2e2a5b02fb67182e269b7c988ffbba86e1278bb9f9bbe1815e3ae1"
|
checksum = "0383b9f5df02975b56f25775330ba2f70ff181fe1091f698c8737868696eb856"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation 0.10.0",
|
"core-foundation 0.10.0",
|
||||||
"inotify",
|
"inotify",
|
||||||
@@ -2593,7 +2562,7 @@ dependencies = [
|
|||||||
"vec_map",
|
"vec_map",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"windows 0.59.0",
|
"windows 0.60.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2802,8 +2771,6 @@ dependencies = [
|
|||||||
"avian3d",
|
"avian3d",
|
||||||
"bevy",
|
"bevy",
|
||||||
"bevy-inspector-egui",
|
"bevy-inspector-egui",
|
||||||
"bevy-tnua",
|
|
||||||
"bevy-tnua-avian3d",
|
|
||||||
"bevy_asset_loader",
|
"bevy_asset_loader",
|
||||||
"bevy_sprite3d",
|
"bevy_sprite3d",
|
||||||
"bevy_trenchbroom",
|
"bevy_trenchbroom",
|
||||||
@@ -2864,9 +2831,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.7.1"
|
version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
|
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.15.2",
|
"hashbrown 0.15.2",
|
||||||
@@ -3039,9 +3006,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.170"
|
version = "0.2.171"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
@@ -3724,9 +3691,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.3"
|
version = "1.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orbclient"
|
name = "orbclient"
|
||||||
@@ -3956,11 +3923,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy",
|
"zerocopy 0.8.23",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3971,9 +3938,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prettyplease"
|
name = "prettyplease"
|
||||||
version = "0.2.30"
|
version = "0.2.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1ccf34da56fc294e7d4ccf69a85992b7dfb826b7cf57bac6a70bba3494cc08a"
|
checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"syn",
|
"syn",
|
||||||
@@ -4074,9 +4041,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.39"
|
version = "1.0.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -4421,18 +4388,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.218"
|
version = "1.0.219"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
|
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.218"
|
version = "1.0.219"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
|
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -4668,9 +4635,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.99"
|
version = "2.0.100"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
|
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -5490,12 +5457,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows"
|
name = "windows"
|
||||||
version = "0.59.0"
|
version = "0.60.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
|
checksum = "ddf874e74c7a99773e62b1c671427abf01a425e77c3d3fb9fb1e4883ea934529"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.59.0",
|
"windows-collections",
|
||||||
"windows-targets 0.53.0",
|
"windows-core 0.60.1",
|
||||||
|
"windows-future",
|
||||||
|
"windows-link",
|
||||||
|
"windows-numerics",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-collections"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5467f79cc1ba3f52ebb2ed41dbb459b8e7db636cc3429458d9a852e15bc24dec"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core 0.60.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5535,15 +5514,25 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.59.0"
|
version = "0.60.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
|
checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement 0.59.0",
|
"windows-implement 0.59.0",
|
||||||
"windows-interface 0.59.0",
|
"windows-interface 0.59.1",
|
||||||
"windows-result 0.3.1",
|
"windows-link",
|
||||||
|
"windows-result 0.3.2",
|
||||||
"windows-strings 0.3.1",
|
"windows-strings 0.3.1",
|
||||||
"windows-targets 0.53.0",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-future"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a787db4595e7eb80239b74ce8babfb1363d8e343ab072f2ffe901400c03349f0"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core 0.60.1",
|
||||||
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5603,9 +5592,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-interface"
|
name = "windows-interface"
|
||||||
version = "0.59.0"
|
version = "0.59.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01"
|
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -5614,9 +5603,19 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3"
|
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-numerics"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "005dea54e2f6499f2cee279b8f703b3cf3b5734a2d8d21867c8f44003182eeed"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core 0.60.1",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
@@ -5638,9 +5637,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189"
|
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
@@ -5739,29 +5738,13 @@ dependencies = [
|
|||||||
"windows_aarch64_gnullvm 0.52.6",
|
"windows_aarch64_gnullvm 0.52.6",
|
||||||
"windows_aarch64_msvc 0.52.6",
|
"windows_aarch64_msvc 0.52.6",
|
||||||
"windows_i686_gnu 0.52.6",
|
"windows_i686_gnu 0.52.6",
|
||||||
"windows_i686_gnullvm 0.52.6",
|
"windows_i686_gnullvm",
|
||||||
"windows_i686_msvc 0.52.6",
|
"windows_i686_msvc 0.52.6",
|
||||||
"windows_x86_64_gnu 0.52.6",
|
"windows_x86_64_gnu 0.52.6",
|
||||||
"windows_x86_64_gnullvm 0.52.6",
|
"windows_x86_64_gnullvm 0.52.6",
|
||||||
"windows_x86_64_msvc 0.52.6",
|
"windows_x86_64_msvc 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.53.0",
|
|
||||||
"windows_aarch64_msvc 0.53.0",
|
|
||||||
"windows_i686_gnu 0.53.0",
|
|
||||||
"windows_i686_gnullvm 0.53.0",
|
|
||||||
"windows_i686_msvc 0.53.0",
|
|
||||||
"windows_x86_64_gnu 0.53.0",
|
|
||||||
"windows_x86_64_gnullvm 0.53.0",
|
|
||||||
"windows_x86_64_msvc 0.53.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
@@ -5780,12 +5763,6 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
@@ -5804,12 +5781,6 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
@@ -5828,24 +5799,12 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnullvm"
|
name = "windows_i686_gnullvm"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
@@ -5864,12 +5823,6 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
@@ -5888,12 +5841,6 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
@@ -5912,12 +5859,6 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
@@ -5936,12 +5877,6 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winit"
|
name = "winit"
|
||||||
version = "0.30.9"
|
version = "0.30.9"
|
||||||
@@ -5996,9 +5931,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.7.3"
|
version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1"
|
checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@@ -6084,8 +6019,16 @@ version = "0.7.35"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"zerocopy-derive 0.7.35",
|
||||||
"zerocopy-derive",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.8.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive 0.8.23",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -6098,3 +6041,14 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.8.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ bevy = "0.15.3"
|
|||||||
bevy_trenchbroom = { version = "0.6.5", features = ["auto_register", "avian"] }
|
bevy_trenchbroom = { version = "0.6.5", features = ["auto_register", "avian"] }
|
||||||
nil = "0.14.0"
|
nil = "0.14.0"
|
||||||
bevy-inspector-egui = "0.29.1"
|
bevy-inspector-egui = "0.29.1"
|
||||||
bevy-tnua = "0.21.0"
|
|
||||||
bevy-tnua-avian3d = "0.2.0"
|
|
||||||
bevy_asset_loader = "0.22.0"
|
bevy_asset_loader = "0.22.0"
|
||||||
bevy_sprite3d = "4.0.0"
|
bevy_sprite3d = "4.0.0"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use avian3d::prelude::*;
|
use avian3d::prelude::*;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{controls::Controls, physics_layers::GameLayer, player::PlayerMovement};
|
use crate::{controller::PlayerMovement, controls::Controls, physics_layers::GameLayer};
|
||||||
|
|
||||||
#[derive(Component, Reflect, Debug)]
|
#[derive(Component, Reflect, Debug)]
|
||||||
pub struct CameraTarget;
|
pub struct CameraTarget;
|
||||||
|
|||||||
539
src/controller.rs
Normal file
539
src/controller.rs
Normal file
@@ -0,0 +1,539 @@
|
|||||||
|
use avian3d::{math::*, prelude::*};
|
||||||
|
use bevy::{ecs::query::Has, prelude::*};
|
||||||
|
|
||||||
|
use crate::player::PlayerRig;
|
||||||
|
|
||||||
|
pub struct CharacterControllerPlugin;
|
||||||
|
|
||||||
|
impl Plugin for CharacterControllerPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.init_resource::<PlayerMovement>();
|
||||||
|
app.init_resource::<MovementSettings>();
|
||||||
|
app.register_type::<MovementSettings>();
|
||||||
|
app.register_type::<MovementDampingFactor>();
|
||||||
|
app.register_type::<JumpImpulse>();
|
||||||
|
app.register_type::<ControllerGravity>();
|
||||||
|
app.register_type::<MovementAcceleration>();
|
||||||
|
|
||||||
|
app.add_event::<MovementAction>();
|
||||||
|
app.add_systems(
|
||||||
|
Update,
|
||||||
|
(
|
||||||
|
keyboard_input,
|
||||||
|
gamepad_input,
|
||||||
|
clear_movement_flag,
|
||||||
|
brake_on_release,
|
||||||
|
update_grounded,
|
||||||
|
apply_gravity,
|
||||||
|
movement,
|
||||||
|
apply_movement_damping,
|
||||||
|
)
|
||||||
|
.chain(),
|
||||||
|
);
|
||||||
|
app.add_systems(
|
||||||
|
// Run collision handling after collision detection.
|
||||||
|
//
|
||||||
|
// NOTE: The collision implementation here is very basic and a bit buggy.
|
||||||
|
// A collide-and-slide algorithm would likely work better.
|
||||||
|
PostProcessCollisions,
|
||||||
|
kinematic_controller_collisions,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An event sent for a movement input action.
|
||||||
|
#[derive(Event)]
|
||||||
|
pub enum MovementAction {
|
||||||
|
Move(Vector2),
|
||||||
|
Jump,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A marker component indicating that an entity is using a character controller.
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct CharacterController;
|
||||||
|
|
||||||
|
/// A marker component indicating that an entity is on the ground.
|
||||||
|
#[derive(Component)]
|
||||||
|
#[component(storage = "SparseSet")]
|
||||||
|
pub struct Grounded;
|
||||||
|
|
||||||
|
#[derive(Resource, Default)]
|
||||||
|
pub struct PlayerMovement {
|
||||||
|
pub any_direction: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Resource, Reflect)]
|
||||||
|
#[reflect(Resource)]
|
||||||
|
struct MovementSettings {
|
||||||
|
damping_normal: f32,
|
||||||
|
damping_brake: f32,
|
||||||
|
damping_brake_air: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo some duplicate with player.rs settings
|
||||||
|
impl Default for MovementSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
damping_normal: 1.0,
|
||||||
|
damping_brake: 30.0,
|
||||||
|
damping_brake_air: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The acceleration used for character movement.
|
||||||
|
#[derive(Component, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct MovementAcceleration(Scalar);
|
||||||
|
|
||||||
|
/// The damping factor used for slowing down movement.
|
||||||
|
#[derive(Component, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct MovementDampingFactor(Scalar);
|
||||||
|
|
||||||
|
/// The strength of a jump.
|
||||||
|
#[derive(Component, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct JumpImpulse(Scalar);
|
||||||
|
|
||||||
|
/// The gravitational acceleration used for a character controller.
|
||||||
|
#[derive(Component, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct ControllerGravity(Vector);
|
||||||
|
|
||||||
|
/// The maximum angle a slope can have for a character controller
|
||||||
|
/// to be able to climb and jump. If the slope is steeper than this angle,
|
||||||
|
/// the character will slide down.
|
||||||
|
#[derive(Component, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct MaxSlopeAngle(Scalar);
|
||||||
|
|
||||||
|
/// A bundle that contains the components needed for a basic
|
||||||
|
/// kinematic character controller.
|
||||||
|
#[derive(Bundle)]
|
||||||
|
pub struct CharacterControllerBundle {
|
||||||
|
character_controller: CharacterController,
|
||||||
|
rigid_body: RigidBody,
|
||||||
|
collider: Collider,
|
||||||
|
ground_caster: ShapeCaster,
|
||||||
|
gravity: ControllerGravity,
|
||||||
|
movement: MovementBundle,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A bundle that contains components for character movement.
|
||||||
|
#[derive(Bundle)]
|
||||||
|
pub struct MovementBundle {
|
||||||
|
acceleration: MovementAcceleration,
|
||||||
|
damping: MovementDampingFactor,
|
||||||
|
jump_impulse: JumpImpulse,
|
||||||
|
max_slope_angle: MaxSlopeAngle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MovementBundle {
|
||||||
|
pub const fn new(
|
||||||
|
acceleration: Scalar,
|
||||||
|
damping: Scalar,
|
||||||
|
jump_impulse: Scalar,
|
||||||
|
max_slope_angle: Scalar,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
acceleration: MovementAcceleration(acceleration),
|
||||||
|
damping: MovementDampingFactor(damping),
|
||||||
|
jump_impulse: JumpImpulse(jump_impulse),
|
||||||
|
max_slope_angle: MaxSlopeAngle(max_slope_angle),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MovementBundle {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(30.0, 0.9, 7.0, PI * 0.45)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CharacterControllerBundle {
|
||||||
|
pub fn new(collider: Collider, gravity: Vector) -> Self {
|
||||||
|
// Create shape caster as a slightly smaller version of collider
|
||||||
|
let mut caster_shape = collider.clone();
|
||||||
|
caster_shape.set_scale(Vector::ONE * 0.98, 10);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
character_controller: CharacterController,
|
||||||
|
rigid_body: RigidBody::Kinematic,
|
||||||
|
collider,
|
||||||
|
ground_caster: ShapeCaster::new(
|
||||||
|
caster_shape,
|
||||||
|
Vector::ZERO,
|
||||||
|
Quaternion::default(),
|
||||||
|
Dir3::NEG_Y,
|
||||||
|
)
|
||||||
|
.with_max_distance(0.2),
|
||||||
|
gravity: ControllerGravity(gravity),
|
||||||
|
movement: MovementBundle::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_movement(
|
||||||
|
mut self,
|
||||||
|
acceleration: Scalar,
|
||||||
|
damping: Scalar,
|
||||||
|
jump_impulse: Scalar,
|
||||||
|
max_slope_angle: Scalar,
|
||||||
|
) -> Self {
|
||||||
|
self.movement = MovementBundle::new(acceleration, damping, jump_impulse, max_slope_angle);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends [`MovementAction`] events based on keyboard input.
|
||||||
|
fn keyboard_input(
|
||||||
|
mut movement_event_writer: EventWriter<MovementAction>,
|
||||||
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
|
) {
|
||||||
|
let up_binds = [KeyCode::KeyW, KeyCode::ArrowUp];
|
||||||
|
let down_binds = [KeyCode::KeyS, KeyCode::ArrowDown];
|
||||||
|
let left_binds = [KeyCode::KeyA, KeyCode::ArrowLeft];
|
||||||
|
let right_binds = [KeyCode::KeyD, KeyCode::ArrowRight];
|
||||||
|
|
||||||
|
let up = keyboard_input.any_pressed(up_binds);
|
||||||
|
let down = keyboard_input.any_pressed(down_binds);
|
||||||
|
let left = keyboard_input.any_pressed(left_binds);
|
||||||
|
let right = keyboard_input.any_pressed(right_binds);
|
||||||
|
|
||||||
|
let horizontal = right as i8 - left as i8;
|
||||||
|
let vertical = up as i8 - down as i8;
|
||||||
|
let direction = Vector2::new(horizontal as Scalar, vertical as Scalar).clamp_length_max(1.0);
|
||||||
|
|
||||||
|
if direction != Vector2::ZERO {
|
||||||
|
movement_event_writer.send(MovementAction::Move(direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
if keyboard_input.just_pressed(KeyCode::Space) {
|
||||||
|
movement_event_writer.send(MovementAction::Jump);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends [`MovementAction`] events based on gamepad input.
|
||||||
|
fn gamepad_input(
|
||||||
|
mut movement_event_writer: EventWriter<MovementAction>,
|
||||||
|
gamepads: Query<&Gamepad>,
|
||||||
|
) {
|
||||||
|
for gamepad in gamepads.iter() {
|
||||||
|
if let (Some(x), Some(y)) = (
|
||||||
|
gamepad.get(GamepadAxis::LeftStickX),
|
||||||
|
gamepad.get(GamepadAxis::LeftStickY),
|
||||||
|
) {
|
||||||
|
let deadzone = 0.01;
|
||||||
|
let dir = Vector2::new(x as Scalar, y as Scalar).clamp_length_max(1.0);
|
||||||
|
|
||||||
|
if dir.length_squared() > deadzone {
|
||||||
|
movement_event_writer.send(MovementAction::Move(dir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if gamepad.just_pressed(GamepadButton::South) {
|
||||||
|
movement_event_writer.send(MovementAction::Jump);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply extra friction when no movement input is given
|
||||||
|
/// In the original you stop instantly in this case
|
||||||
|
fn brake_on_release(
|
||||||
|
player_movement: Res<PlayerMovement>,
|
||||||
|
movement_settings: Res<MovementSettings>,
|
||||||
|
mut damping_q: Query<(Entity, &mut MovementDampingFactor)>,
|
||||||
|
grounded_q: Query<&Grounded>,
|
||||||
|
) {
|
||||||
|
for (entity, mut damping) in &mut damping_q {
|
||||||
|
let is_grounded = grounded_q.get(entity).is_ok();
|
||||||
|
|
||||||
|
if !player_movement.any_direction && is_grounded {
|
||||||
|
damping.0 = movement_settings.damping_brake;
|
||||||
|
} else if !player_movement.any_direction && !is_grounded {
|
||||||
|
damping.0 = movement_settings.damping_brake_air;
|
||||||
|
} else {
|
||||||
|
damping.0 = movement_settings.damping_normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates the [`Grounded`] status for character controllers.
|
||||||
|
fn update_grounded(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut query: Query<
|
||||||
|
(Entity, &ShapeHits, &Rotation, Option<&MaxSlopeAngle>),
|
||||||
|
With<CharacterController>,
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
for (entity, hits, rotation, max_slope_angle) in &mut query {
|
||||||
|
// The character is grounded if the shape caster has a hit with a normal
|
||||||
|
// that isn't too steep.
|
||||||
|
let is_grounded = hits.iter().any(|hit| {
|
||||||
|
if let Some(angle) = max_slope_angle {
|
||||||
|
(rotation * -hit.normal2).angle_between(Vector::Y).abs() <= angle.0
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if is_grounded {
|
||||||
|
commands.entity(entity).insert(Grounded);
|
||||||
|
} else {
|
||||||
|
commands.entity(entity).remove::<Grounded>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_movement_flag(
|
||||||
|
mut player_movement: ResMut<PlayerMovement>,
|
||||||
|
movement_event_reader: EventReader<MovementAction>,
|
||||||
|
) {
|
||||||
|
if movement_event_reader.is_empty() {
|
||||||
|
player_movement.any_direction = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Responds to [`MovementAction`] events and moves character controllers accordingly.
|
||||||
|
fn movement(
|
||||||
|
time: Res<Time>,
|
||||||
|
mut movement_event_reader: EventReader<MovementAction>,
|
||||||
|
mut controllers: Query<(
|
||||||
|
&MovementAcceleration,
|
||||||
|
&JumpImpulse,
|
||||||
|
&mut LinearVelocity,
|
||||||
|
Has<Grounded>,
|
||||||
|
)>,
|
||||||
|
rig_transform_q: Option<Single<&GlobalTransform, With<PlayerRig>>>,
|
||||||
|
mut player_movement: ResMut<PlayerMovement>,
|
||||||
|
) {
|
||||||
|
let delta_time = time.delta_secs();
|
||||||
|
|
||||||
|
for event in movement_event_reader.read() {
|
||||||
|
for (movement_acceleration, jump_impulse, mut linear_velocity, is_grounded) in
|
||||||
|
&mut controllers
|
||||||
|
{
|
||||||
|
match event {
|
||||||
|
MovementAction::Move(direction) => {
|
||||||
|
let mut direction = direction.extend(0.0).xzy();
|
||||||
|
|
||||||
|
if let Some(ref rig_transform) = rig_transform_q {
|
||||||
|
direction = (rig_transform.forward() * direction.z)
|
||||||
|
+ (rig_transform.right() * direction.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
linear_velocity.x -= direction.x * movement_acceleration.0 * delta_time;
|
||||||
|
linear_velocity.z -= direction.z * movement_acceleration.0 * delta_time;
|
||||||
|
|
||||||
|
// Update movement flag
|
||||||
|
let deadzone = 0.2;
|
||||||
|
|
||||||
|
// todo this is probably not necessary
|
||||||
|
if player_movement.any_direction && direction.length_squared() < deadzone {
|
||||||
|
player_movement.any_direction = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !player_movement.any_direction && direction.length_squared() > deadzone {
|
||||||
|
player_movement.any_direction = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MovementAction::Jump => {
|
||||||
|
if is_grounded {
|
||||||
|
linear_velocity.y = jump_impulse.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Applies [`ControllerGravity`] to character controllers.
|
||||||
|
fn apply_gravity(
|
||||||
|
time: Res<Time>,
|
||||||
|
mut controllers: Query<(&ControllerGravity, &mut LinearVelocity)>,
|
||||||
|
) {
|
||||||
|
let delta_time = time.delta_secs();
|
||||||
|
|
||||||
|
for (gravity, mut linear_velocity) in &mut controllers {
|
||||||
|
linear_velocity.0 += gravity.0 * delta_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Slows down movement in the XZ plane.
|
||||||
|
fn apply_movement_damping(
|
||||||
|
time: Res<Time>,
|
||||||
|
mut query: Query<(&MovementDampingFactor, &mut LinearVelocity)>,
|
||||||
|
) {
|
||||||
|
let delta_time = time.delta_secs();
|
||||||
|
|
||||||
|
for (damping_factor, mut linear_velocity) in &mut query {
|
||||||
|
// We could use `LinearDamping`, but we don't want to dampen movement along the Y axis
|
||||||
|
linear_velocity.x *= 1.0 - damping_factor.0 * delta_time;
|
||||||
|
linear_velocity.z *= 1.0 - damping_factor.0 * delta_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Kinematic bodies do not get pushed by collisions by default,
|
||||||
|
/// so it needs to be done manually.
|
||||||
|
///
|
||||||
|
/// This system handles collision response for kinematic character controllers
|
||||||
|
/// by pushing them along their contact normals by the current penetration depth,
|
||||||
|
/// and applying velocity corrections in order to snap to slopes, slide along walls,
|
||||||
|
/// and predict collisions using speculative contacts.
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
fn kinematic_controller_collisions(
|
||||||
|
collisions: Res<Collisions>,
|
||||||
|
bodies: Query<&RigidBody>,
|
||||||
|
collider_parents: Query<&ColliderParent, Without<Sensor>>,
|
||||||
|
mut character_controllers: Query<
|
||||||
|
(
|
||||||
|
&mut Position,
|
||||||
|
&Rotation,
|
||||||
|
&mut LinearVelocity,
|
||||||
|
Option<&MaxSlopeAngle>,
|
||||||
|
),
|
||||||
|
(With<RigidBody>, With<CharacterController>),
|
||||||
|
>,
|
||||||
|
time: Res<Time>,
|
||||||
|
) {
|
||||||
|
// Iterate through collisions and move the kinematic body to resolve penetration
|
||||||
|
for contacts in collisions.iter() {
|
||||||
|
// Get the rigid body entities of the colliders (colliders could be children)
|
||||||
|
let Ok([collider_parent1, collider_parent2]) =
|
||||||
|
collider_parents.get_many([contacts.entity1, contacts.entity2])
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the body of the character controller and whether it is the first
|
||||||
|
// or second entity in the collision.
|
||||||
|
let is_first: bool;
|
||||||
|
|
||||||
|
let character_rb: RigidBody;
|
||||||
|
let is_other_dynamic: bool;
|
||||||
|
|
||||||
|
let (mut position, rotation, mut linear_velocity, max_slope_angle) =
|
||||||
|
if let Ok(character) = character_controllers.get_mut(collider_parent1.get()) {
|
||||||
|
is_first = true;
|
||||||
|
character_rb = *bodies.get(collider_parent1.get()).unwrap();
|
||||||
|
is_other_dynamic = bodies
|
||||||
|
.get(collider_parent2.get())
|
||||||
|
.is_ok_and(|rb| rb.is_dynamic());
|
||||||
|
character
|
||||||
|
} else if let Ok(character) = character_controllers.get_mut(collider_parent2.get()) {
|
||||||
|
is_first = false;
|
||||||
|
character_rb = *bodies.get(collider_parent2.get()).unwrap();
|
||||||
|
is_other_dynamic = bodies
|
||||||
|
.get(collider_parent1.get())
|
||||||
|
.is_ok_and(|rb| rb.is_dynamic());
|
||||||
|
character
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This system only handles collision response for kinematic character controllers.
|
||||||
|
if !character_rb.is_kinematic() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through contact manifolds and their contacts.
|
||||||
|
// Each contact in a single manifold shares the same contact normal.
|
||||||
|
for manifold in contacts.manifolds.iter() {
|
||||||
|
let normal = if is_first {
|
||||||
|
-manifold.global_normal1(rotation)
|
||||||
|
} else {
|
||||||
|
-manifold.global_normal2(rotation)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut deepest_penetration: Scalar = Scalar::MIN;
|
||||||
|
|
||||||
|
// Solve each penetrating contact in the manifold.
|
||||||
|
for contact in manifold.contacts.iter() {
|
||||||
|
if contact.penetration > 0.0 {
|
||||||
|
position.0 += normal * contact.penetration;
|
||||||
|
}
|
||||||
|
deepest_penetration = deepest_penetration.max(contact.penetration);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now, this system only handles velocity corrections for collisions against static geometry.
|
||||||
|
if is_other_dynamic {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if the slope is climbable or if it's too steep to walk on.
|
||||||
|
let slope_angle = normal.angle_between(Vector::Y);
|
||||||
|
let climbable = max_slope_angle.is_some_and(|angle| slope_angle.abs() <= angle.0);
|
||||||
|
|
||||||
|
if deepest_penetration > 0.0 {
|
||||||
|
// If the slope is climbable, snap the velocity so that the character
|
||||||
|
// up and down the surface smoothly.
|
||||||
|
if climbable {
|
||||||
|
// Points in the normal's direction in the XZ plane.
|
||||||
|
let normal_direction_xz =
|
||||||
|
normal.reject_from_normalized(Vector::Y).normalize_or_zero();
|
||||||
|
|
||||||
|
// The movement speed along the direction above.
|
||||||
|
let linear_velocity_xz = linear_velocity.dot(normal_direction_xz);
|
||||||
|
|
||||||
|
// Snap the Y speed based on the speed at which the character is moving
|
||||||
|
// up or down the slope, and how steep the slope is.
|
||||||
|
//
|
||||||
|
// A 2D visualization of the slope, the contact normal, and the velocity components:
|
||||||
|
//
|
||||||
|
// ╱
|
||||||
|
// normal ╱
|
||||||
|
// * ╱
|
||||||
|
// │ * ╱ velocity_x
|
||||||
|
// │ * - - - - - -
|
||||||
|
// │ * | velocity_y
|
||||||
|
// │ * |
|
||||||
|
// *───────────────────*
|
||||||
|
|
||||||
|
let max_y_speed = -linear_velocity_xz * slope_angle.tan();
|
||||||
|
linear_velocity.y = linear_velocity.y.max(max_y_speed);
|
||||||
|
} else {
|
||||||
|
// The character is intersecting an unclimbable object, like a wall.
|
||||||
|
// We want the character to slide along the surface, similarly to
|
||||||
|
// a collide-and-slide algorithm.
|
||||||
|
|
||||||
|
// Don't apply an impulse if the character is moving away from the surface.
|
||||||
|
if linear_velocity.dot(normal) > 0.0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slide along the surface, rejecting the velocity along the contact normal.
|
||||||
|
let impulse = linear_velocity.reject_from_normalized(normal);
|
||||||
|
linear_velocity.0 = impulse;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The character is not yet intersecting the other object,
|
||||||
|
// but the narrow phase detected a speculative collision.
|
||||||
|
//
|
||||||
|
// We need to push back the part of the velocity
|
||||||
|
// that would cause penetration within the next frame.
|
||||||
|
|
||||||
|
let normal_speed = linear_velocity.dot(normal);
|
||||||
|
|
||||||
|
// Don't apply an impulse if the character is moving away from the surface.
|
||||||
|
if normal_speed > 0.0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the impulse to apply.
|
||||||
|
let impulse_magnitude =
|
||||||
|
normal_speed - (deepest_penetration / time.delta_secs_f64().adjust_precision());
|
||||||
|
let mut impulse = impulse_magnitude * normal;
|
||||||
|
|
||||||
|
// Apply the impulse differently depending on the slope angle.
|
||||||
|
if climbable {
|
||||||
|
// Avoid sliding down slopes.
|
||||||
|
linear_velocity.y -= impulse.y.min(0.0);
|
||||||
|
} else {
|
||||||
|
// Avoid climbing up walls.
|
||||||
|
impulse.y = impulse.y.max(0.0);
|
||||||
|
linear_velocity.0 -= impulse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ mod alien;
|
|||||||
mod billboards;
|
mod billboards;
|
||||||
mod camera;
|
mod camera;
|
||||||
mod cash;
|
mod cash;
|
||||||
|
mod controller;
|
||||||
mod controls;
|
mod controls;
|
||||||
mod cutscene;
|
mod cutscene;
|
||||||
mod gates;
|
mod gates;
|
||||||
@@ -26,9 +27,8 @@ use bevy::core_pipeline::tonemapping::Tonemapping;
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::render::view::ColorGrading;
|
use bevy::render::view::ColorGrading;
|
||||||
use bevy::scene::SceneInstanceReady;
|
use bevy::scene::SceneInstanceReady;
|
||||||
use bevy_tnua::prelude::TnuaControllerPlugin;
|
|
||||||
use bevy_tnua_avian3d::TnuaAvian3dPlugin;
|
|
||||||
use bevy_trenchbroom::prelude::*;
|
use bevy_trenchbroom::prelude::*;
|
||||||
|
use controller::CharacterControllerPlugin;
|
||||||
use physics_layers::GameLayer;
|
use physics_layers::GameLayer;
|
||||||
|
|
||||||
#[derive(Resource, Reflect, Debug)]
|
#[derive(Resource, Reflect, Debug)]
|
||||||
@@ -69,10 +69,7 @@ fn main() {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
app.add_plugins(PhysicsPlugins::default());
|
app.add_plugins(PhysicsPlugins::default());
|
||||||
app.add_plugins((
|
app.add_plugins(CharacterControllerPlugin);
|
||||||
TnuaControllerPlugin::new(FixedUpdate),
|
|
||||||
TnuaAvian3dPlugin::new(FixedUpdate),
|
|
||||||
));
|
|
||||||
|
|
||||||
// app.add_plugins(PhysicsDebugPlugin::default());
|
// app.add_plugins(PhysicsDebugPlugin::default());
|
||||||
// app.add_plugins(bevy_inspector_egui::quick::WorldInspectorPlugin::default());
|
// app.add_plugins(bevy_inspector_egui::quick::WorldInspectorPlugin::default());
|
||||||
|
|||||||
@@ -2,18 +2,21 @@ use crate::{
|
|||||||
alien::{ALIEN_ASSET_PATH, Animations},
|
alien::{ALIEN_ASSET_PATH, Animations},
|
||||||
camera::{CameraArmRotation, CameraTarget},
|
camera::{CameraArmRotation, CameraTarget},
|
||||||
cash::{Cash, CashCollectEvent},
|
cash::{Cash, CashCollectEvent},
|
||||||
|
controller::{CharacterControllerBundle, PlayerMovement},
|
||||||
controls::Controls,
|
controls::Controls,
|
||||||
heads_ui::HeadChanged,
|
heads_ui::HeadChanged,
|
||||||
physics_layers::GameLayer,
|
physics_layers::GameLayer,
|
||||||
tb_entities::SpawnPoint,
|
tb_entities::SpawnPoint,
|
||||||
};
|
};
|
||||||
use avian3d::prelude::*;
|
use avian3d::{
|
||||||
|
math::{Scalar, Vector},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
use bevy::{
|
use bevy::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
window::{CursorGrabMode, PrimaryWindow},
|
window::{CursorGrabMode, PrimaryWindow},
|
||||||
};
|
};
|
||||||
use bevy_tnua::{TnuaUserControlsSystemSet, prelude::*};
|
|
||||||
use bevy_tnua_avian3d::TnuaAvian3dSensorShape;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[derive(Component, Default)]
|
#[derive(Component, Default)]
|
||||||
@@ -33,14 +36,8 @@ struct PlayerSpawned {
|
|||||||
spawned: bool,
|
spawned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource, Default)]
|
|
||||||
pub struct PlayerMovement {
|
|
||||||
pub any_direction: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn plugin(app: &mut App) {
|
pub fn plugin(app: &mut App) {
|
||||||
app.init_resource::<PlayerSpawned>();
|
app.init_resource::<PlayerSpawned>();
|
||||||
app.init_resource::<PlayerMovement>();
|
|
||||||
app.add_systems(Startup, (initial_grab_cursor, cursor_recenter));
|
app.add_systems(Startup, (initial_grab_cursor, cursor_recenter));
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
Update,
|
Update,
|
||||||
@@ -51,10 +48,6 @@ pub fn plugin(app: &mut App) {
|
|||||||
setup_animations_marker_for_player,
|
setup_animations_marker_for_player,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
app.add_systems(
|
|
||||||
FixedUpdate,
|
|
||||||
apply_controls.in_set(TnuaUserControlsSystemSet),
|
|
||||||
);
|
|
||||||
|
|
||||||
app.add_systems(Update, (rotate_view_keyboard, rotate_view_gamepad));
|
app.add_systems(Update, (rotate_view_keyboard, rotate_view_gamepad));
|
||||||
|
|
||||||
@@ -80,21 +73,28 @@ fn spawn(
|
|||||||
let mesh = asset_server
|
let mesh = asset_server
|
||||||
.load(GltfAssetLabel::Scene(0).from_asset("models/heads/angry demonstrator.glb"));
|
.load(GltfAssetLabel::Scene(0).from_asset("models/heads/angry demonstrator.glb"));
|
||||||
|
|
||||||
|
let gravity = Vector::NEG_Y * 40.0;
|
||||||
|
let collider = Collider::capsule(0.9, 1.2);
|
||||||
|
let acceleration = 30.0;
|
||||||
|
let damping = 0.95;
|
||||||
|
let jump_impulse = 18.0;
|
||||||
|
let max_slope_angle = (60.0 as Scalar).to_radians();
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Name::from("player"),
|
Name::from("player"),
|
||||||
Player,
|
Player,
|
||||||
CameraTarget,
|
CameraTarget,
|
||||||
transform,
|
transform,
|
||||||
TransformInterpolation,
|
|
||||||
TransformExtrapolation,
|
|
||||||
Visibility::default(),
|
Visibility::default(),
|
||||||
RigidBody::Dynamic,
|
// LockedAxes::ROTATION_LOCKED, todo
|
||||||
Collider::capsule(1.2, 1.5),
|
|
||||||
CollisionLayers::new(LayerMask(GameLayer::Player.to_bits()), LayerMask::ALL),
|
CollisionLayers::new(LayerMask(GameLayer::Player.to_bits()), LayerMask::ALL),
|
||||||
LockedAxes::ROTATION_LOCKED,
|
CharacterControllerBundle::new(collider, gravity).with_movement(
|
||||||
TnuaController::default(),
|
acceleration,
|
||||||
TnuaAvian3dSensorShape(Collider::cylinder(0.8, 0.0)),
|
damping,
|
||||||
|
jump_impulse,
|
||||||
|
max_slope_angle,
|
||||||
|
),
|
||||||
))
|
))
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent
|
parent
|
||||||
@@ -102,7 +102,7 @@ fn spawn(
|
|||||||
Name::from("body rig"),
|
Name::from("body rig"),
|
||||||
PlayerRig,
|
PlayerRig,
|
||||||
CameraArmRotation,
|
CameraArmRotation,
|
||||||
Transform::from_translation(Vec3::new(0., -3., 0.))
|
Transform::from_translation(Vec3::new(0., -1.45, 0.))
|
||||||
.with_rotation(Quat::from_rotation_y(std::f32::consts::PI))
|
.with_rotation(Quat::from_rotation_y(std::f32::consts::PI))
|
||||||
.with_scale(Vec3::splat(1.4)),
|
.with_scale(Vec3::splat(1.4)),
|
||||||
SceneRoot(
|
SceneRoot(
|
||||||
@@ -187,57 +187,6 @@ fn initial_grab_cursor(mut primary_window: Query<&mut Window, With<PrimaryWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_controls(
|
|
||||||
controls: Res<Controls>,
|
|
||||||
mut query: Query<&mut TnuaController>,
|
|
||||||
player: Query<&Transform, With<PlayerRig>>,
|
|
||||||
mut movement: ResMut<PlayerMovement>,
|
|
||||||
) {
|
|
||||||
let Ok(mut controller) = query.get_single_mut() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Ok(player) = player.get_single() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut direction = player.forward().as_vec3() * -controls.keyboard_state.move_dir.y;
|
|
||||||
direction += player.right().as_vec3() * -controls.keyboard_state.move_dir.x;
|
|
||||||
|
|
||||||
if let Some(gamepad) = controls.gamepad_state {
|
|
||||||
direction += player.forward().as_vec3() * -gamepad.move_dir.y;
|
|
||||||
direction += player.right().as_vec3() * -gamepad.move_dir.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if movement.any_direction != (direction != Vec3::ZERO) {
|
|
||||||
movement.any_direction = direction != Vec3::ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.basis(TnuaBuiltinWalk {
|
|
||||||
// The `desired_velocity` determines how the character will move.
|
|
||||||
desired_velocity: direction.normalize_or_zero() * 15.0,
|
|
||||||
spring_strengh: 1000.,
|
|
||||||
spring_dampening: 0.5,
|
|
||||||
// The `float_height` must be greater (even if by little) from the distance between the
|
|
||||||
// character's center and the lowest point of its collider.
|
|
||||||
float_height: 3.0,
|
|
||||||
// `TnuaBuiltinWalk` has many other fields for customizing the movement - but they have
|
|
||||||
// sensible defaults. Refer to the `TnuaBuiltinWalk`'s documentation to learn what they do.
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
|
|
||||||
// Feed the jump action every frame as long as the player holds the jump button. If the player
|
|
||||||
// stops holding the jump button, simply stop feeding the action.
|
|
||||||
if controls.keyboard_state.jump || controls.gamepad_state.map(|gp| gp.jump).unwrap_or(false) {
|
|
||||||
controller.action(TnuaBuiltinJump {
|
|
||||||
// The height is the only mandatory field of the jump button.
|
|
||||||
height: 4.0,
|
|
||||||
// `TnuaBuiltinJump` also has customization fields with sensible defaults.
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collect_cash(
|
fn collect_cash(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut collision_event_reader: EventReader<CollisionStarted>,
|
mut collision_event_reader: EventReader<CollisionStarted>,
|
||||||
@@ -264,7 +213,7 @@ fn setup_animations_marker_for_player(
|
|||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
animation_handles: Query<Entity, Added<AnimationGraphHandle>>,
|
animation_handles: Query<Entity, Added<AnimationGraphHandle>>,
|
||||||
parent_query: Query<&Parent>,
|
parent_query: Query<&Parent>,
|
||||||
player: Query<&Player>,
|
player: Query<&PlayerRig>,
|
||||||
) {
|
) {
|
||||||
for entity in animation_handles.iter() {
|
for entity in animation_handles.iter() {
|
||||||
for ancestor in parent_query.iter_ancestors(entity) {
|
for ancestor in parent_query.iter_ancestors(entity) {
|
||||||
|
|||||||
@@ -43,19 +43,19 @@ impl SpawnPoint {
|
|||||||
|
|
||||||
#[derive(SolidClass, Component, Reflect, Default)]
|
#[derive(SolidClass, Component, Reflect, Default)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
#[geometry(GeometryProvider::new().trimesh_collider().render())]
|
#[geometry(GeometryProvider::new().convex_collider().render())]
|
||||||
pub struct Worldspawn;
|
pub struct Worldspawn;
|
||||||
|
|
||||||
#[derive(SolidClass, Component, Reflect, Default)]
|
#[derive(SolidClass, Component, Reflect, Default)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
#[require(Transform)]
|
#[require(Transform)]
|
||||||
#[geometry(GeometryProvider::new().trimesh_collider().render())]
|
#[geometry(GeometryProvider::new().convex_collider().render())]
|
||||||
pub struct Crates;
|
pub struct Crates;
|
||||||
|
|
||||||
#[derive(SolidClass, Component, Reflect, Default)]
|
#[derive(SolidClass, Component, Reflect, Default)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
#[require(Transform)]
|
#[require(Transform)]
|
||||||
#[geometry(GeometryProvider::new().trimesh_collider().render())]
|
#[geometry(GeometryProvider::new().convex_collider().render())]
|
||||||
pub struct NamedEntity {
|
pub struct NamedEntity {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ pub struct NamedEntity {
|
|||||||
#[derive(SolidClass, Component, Reflect, Default)]
|
#[derive(SolidClass, Component, Reflect, Default)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
#[require(Transform, Target)]
|
#[require(Transform, Target)]
|
||||||
#[geometry(GeometryProvider::new().trimesh_collider().render())]
|
#[geometry(GeometryProvider::new().convex_collider().render())]
|
||||||
pub struct Platform;
|
pub struct Platform;
|
||||||
|
|
||||||
#[derive(PointClass, Component, Reflect, Default)]
|
#[derive(PointClass, Component, Reflect, Default)]
|
||||||
@@ -76,7 +76,7 @@ pub struct PlatformTarget {
|
|||||||
#[derive(SolidClass, Component, Reflect, Default)]
|
#[derive(SolidClass, Component, Reflect, Default)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
#[require(Transform, Target)]
|
#[require(Transform, Target)]
|
||||||
#[geometry(GeometryProvider::new().trimesh_collider().render())]
|
#[geometry(GeometryProvider::new().convex_collider().render())]
|
||||||
pub struct Movable {
|
pub struct Movable {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user