Car controller for Bevy and Avian3d 0.6.1
3

Configure Feed

Select the types of activity you want to include in your feed.

Update dependencies and tune car physics in examples; Add hot reloading support under feature flag; Add a crude ramp

Matthew Blair (May 18, 2026, 1:26 PM +1000) 328951d1 6bb7cf1b

+402 -37
+11 -1
.zed/settings.json
··· 2 2 // 3 3 // For a full list of overridable settings, and general information on folder-specific settings, 4 4 // see the documentation: https://zed.dev/docs/configuring-zed#settings-files 5 - {} 5 + { 6 + "lsp": { 7 + "rust-analyzer": { 8 + "initialization_options": { 9 + "cargo": { 10 + "features": "all", 11 + }, 12 + }, 13 + }, 14 + }, 15 + }
+335 -1
Cargo.lock
··· 364 364 "bevy_asset_loader", 365 365 "bevy_common_assets", 366 366 "bevy_enhanced_input", 367 + "bevy_hotpatching_experiments", 367 368 "bevy_rand", 368 369 "noisy_bevy", 369 370 "rand", ··· 1027 1028 "bevy_math", 1028 1029 "bevy_reflect", 1029 1030 "glam_matrix_extras", 1031 + ] 1032 + 1033 + [[package]] 1034 + name = "bevy_hotpatching_experiments" 1035 + version = "0.4.0" 1036 + source = "registry+https://github.com/rust-lang/crates.io-index" 1037 + checksum = "8b64bacf563bc4b37cbc3365b44389bb24991c678749c351ebc670e403469701" 1038 + dependencies = [ 1039 + "bevy_app", 1040 + "bevy_derive", 1041 + "bevy_ecs", 1042 + "bevy_ecs_macros", 1043 + "bevy_hotpatching_experiments_macros", 1044 + "bevy_internal", 1045 + "bevy_log", 1046 + "bevy_platform", 1047 + "bevy_reflect", 1048 + "bevy_utils", 1049 + "crossbeam-channel", 1050 + "dioxus-cli-config", 1051 + "dioxus-devtools", 1052 + "send_wrapper", 1053 + "serde_json", 1054 + "web-sys", 1055 + ] 1056 + 1057 + [[package]] 1058 + name = "bevy_hotpatching_experiments_macros" 1059 + version = "0.1.9" 1060 + source = "registry+https://github.com/rust-lang/crates.io-index" 1061 + checksum = "2a9f46960e68fb02e19f02483d438eb5d3c35f8f39a19531b25610e32ab5f4f7" 1062 + dependencies = [ 1063 + "proc-macro2", 1064 + "quote", 1065 + "syn", 1030 1066 ] 1031 1067 1032 1068 [[package]] ··· 1922 1958 "cc", 1923 1959 "cfg-if", 1924 1960 "constant_time_eq", 1925 - "cpufeatures", 1961 + "cpufeatures 0.3.0", 1926 1962 ] 1927 1963 1928 1964 [[package]] ··· 1932 1968 checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 1933 1969 1934 1970 [[package]] 1971 + name = "block-buffer" 1972 + version = "0.10.4" 1973 + source = "registry+https://github.com/rust-lang/crates.io-index" 1974 + checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 1975 + dependencies = [ 1976 + "generic-array", 1977 + ] 1978 + 1979 + [[package]] 1935 1980 name = "block-pseudorand" 1936 1981 version = "0.1.2" 1937 1982 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2207 2252 checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" 2208 2253 2209 2254 [[package]] 2255 + name = "const_format" 2256 + version = "0.2.36" 2257 + source = "registry+https://github.com/rust-lang/crates.io-index" 2258 + checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" 2259 + dependencies = [ 2260 + "const_format_proc_macros", 2261 + "konst", 2262 + ] 2263 + 2264 + [[package]] 2265 + name = "const_format_proc_macros" 2266 + version = "0.2.34" 2267 + source = "registry+https://github.com/rust-lang/crates.io-index" 2268 + checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" 2269 + dependencies = [ 2270 + "proc-macro2", 2271 + "quote", 2272 + "unicode-xid", 2273 + ] 2274 + 2275 + [[package]] 2210 2276 name = "const_panic" 2211 2277 version = "0.2.15" 2212 2278 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2384 2450 2385 2451 [[package]] 2386 2452 name = "cpufeatures" 2453 + version = "0.2.17" 2454 + source = "registry+https://github.com/rust-lang/crates.io-index" 2455 + checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 2456 + dependencies = [ 2457 + "libc", 2458 + ] 2459 + 2460 + [[package]] 2461 + name = "cpufeatures" 2387 2462 version = "0.3.0" 2388 2463 source = "registry+https://github.com/rust-lang/crates.io-index" 2389 2464 checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" ··· 2492 2567 checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" 2493 2568 2494 2569 [[package]] 2570 + name = "crypto-common" 2571 + version = "0.1.7" 2572 + source = "registry+https://github.com/rust-lang/crates.io-index" 2573 + checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" 2574 + dependencies = [ 2575 + "generic-array", 2576 + "typenum", 2577 + ] 2578 + 2579 + [[package]] 2495 2580 name = "ctrlc" 2496 2581 version = "3.5.2" 2497 2582 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2544 2629 ] 2545 2630 2546 2631 [[package]] 2632 + name = "digest" 2633 + version = "0.10.7" 2634 + source = "registry+https://github.com/rust-lang/crates.io-index" 2635 + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 2636 + dependencies = [ 2637 + "block-buffer", 2638 + "crypto-common", 2639 + ] 2640 + 2641 + [[package]] 2642 + name = "dioxus-cli-config" 2643 + version = "0.7.9" 2644 + source = "registry+https://github.com/rust-lang/crates.io-index" 2645 + checksum = "c000f584ddf608e2b272b3074bf11512a474eeeb2eb85a1915f276ce5c4a8615" 2646 + dependencies = [ 2647 + "wasm-bindgen", 2648 + ] 2649 + 2650 + [[package]] 2651 + name = "dioxus-core" 2652 + version = "0.7.9" 2653 + source = "registry+https://github.com/rust-lang/crates.io-index" 2654 + checksum = "45887100ff0cf89abeb8b659808294fda48cd53f3b424e36407dedffcfea830b" 2655 + dependencies = [ 2656 + "anyhow", 2657 + "const_format", 2658 + "dioxus-core-types", 2659 + "futures-channel", 2660 + "futures-util", 2661 + "generational-box", 2662 + "longest-increasing-subsequence", 2663 + "rustc-hash 2.1.2", 2664 + "rustversion", 2665 + "serde", 2666 + "slab", 2667 + "slotmap", 2668 + "subsecond", 2669 + "tracing", 2670 + ] 2671 + 2672 + [[package]] 2673 + name = "dioxus-core-types" 2674 + version = "0.7.9" 2675 + source = "registry+https://github.com/rust-lang/crates.io-index" 2676 + checksum = "36963eab106b169737762f9cd5ee5fd97f585989dcb2d8e30a596e97a6999009" 2677 + 2678 + [[package]] 2679 + name = "dioxus-devtools" 2680 + version = "0.7.9" 2681 + source = "registry+https://github.com/rust-lang/crates.io-index" 2682 + checksum = "2349cedbdf1b429df1f1bea61fdee0ad3dae7b2548eedfbeca82710122a57da0" 2683 + dependencies = [ 2684 + "dioxus-cli-config", 2685 + "dioxus-core", 2686 + "dioxus-devtools-types", 2687 + "dioxus-signals", 2688 + "serde", 2689 + "serde_json", 2690 + "subsecond", 2691 + "thiserror 2.0.18", 2692 + "tracing", 2693 + "tungstenite", 2694 + ] 2695 + 2696 + [[package]] 2697 + name = "dioxus-devtools-types" 2698 + version = "0.7.9" 2699 + source = "registry+https://github.com/rust-lang/crates.io-index" 2700 + checksum = "0ab9b0f7565d1916b70915f59b89ea8054ef0a9d67a364a32bbee68ef5f3818d" 2701 + dependencies = [ 2702 + "dioxus-core", 2703 + "serde", 2704 + "subsecond-types", 2705 + ] 2706 + 2707 + [[package]] 2708 + name = "dioxus-signals" 2709 + version = "0.7.9" 2710 + source = "registry+https://github.com/rust-lang/crates.io-index" 2711 + checksum = "3705754f5e043deec9fc7af0d159f18e5b21c02c47d255c7e477f31368f0b6d2" 2712 + dependencies = [ 2713 + "dioxus-core", 2714 + "futures-channel", 2715 + "futures-util", 2716 + "generational-box", 2717 + "parking_lot", 2718 + "rustc-hash 2.1.2", 2719 + "tracing", 2720 + "warnings", 2721 + ] 2722 + 2723 + [[package]] 2547 2724 name = "dispatch" 2548 2725 version = "0.2.0" 2549 2726 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2912 3089 ] 2913 3090 2914 3091 [[package]] 3092 + name = "generational-box" 3093 + version = "0.7.9" 3094 + source = "registry+https://github.com/rust-lang/crates.io-index" 3095 + checksum = "8cd0d825b8d339701ad330dbcd6399519ced4d143484954daf6e3185dace4f77" 3096 + dependencies = [ 3097 + "parking_lot", 3098 + "tracing", 3099 + ] 3100 + 3101 + [[package]] 3102 + name = "generic-array" 3103 + version = "0.14.7" 3104 + source = "registry+https://github.com/rust-lang/crates.io-index" 3105 + checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 3106 + dependencies = [ 3107 + "typenum", 3108 + "version_check", 3109 + ] 3110 + 3111 + [[package]] 2915 3112 name = "gethostname" 2916 3113 version = "1.1.0" 2917 3114 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3279 3476 checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" 3280 3477 3281 3478 [[package]] 3479 + name = "http" 3480 + version = "1.4.0" 3481 + source = "registry+https://github.com/rust-lang/crates.io-index" 3482 + checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" 3483 + dependencies = [ 3484 + "bytes", 3485 + "itoa", 3486 + ] 3487 + 3488 + [[package]] 3489 + name = "httparse" 3490 + version = "1.10.1" 3491 + source = "registry+https://github.com/rust-lang/crates.io-index" 3492 + checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 3493 + 3494 + [[package]] 3282 3495 name = "id-arena" 3283 3496 version = "2.3.0" 3284 3497 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3518 3731 checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" 3519 3732 3520 3733 [[package]] 3734 + name = "konst" 3735 + version = "0.2.20" 3736 + source = "registry+https://github.com/rust-lang/crates.io-index" 3737 + checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" 3738 + dependencies = [ 3739 + "konst_macro_rules", 3740 + ] 3741 + 3742 + [[package]] 3743 + name = "konst_macro_rules" 3744 + version = "0.2.19" 3745 + source = "registry+https://github.com/rust-lang/crates.io-index" 3746 + checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" 3747 + 3748 + [[package]] 3521 3749 name = "kqueue" 3522 3750 version = "1.1.1" 3523 3751 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3653 3881 checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" 3654 3882 3655 3883 [[package]] 3884 + name = "longest-increasing-subsequence" 3885 + version = "0.1.0" 3886 + source = "registry+https://github.com/rust-lang/crates.io-index" 3887 + checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" 3888 + 3889 + [[package]] 3656 3890 name = "mach2" 3657 3891 version = "0.4.3" 3658 3892 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3684 3918 version = "2.8.0" 3685 3919 source = "registry+https://github.com/rust-lang/crates.io-index" 3686 3920 checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" 3921 + 3922 + [[package]] 3923 + name = "memfd" 3924 + version = "0.6.5" 3925 + source = "registry+https://github.com/rust-lang/crates.io-index" 3926 + checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" 3927 + dependencies = [ 3928 + "rustix 1.1.4", 3929 + ] 3687 3930 3688 3931 [[package]] 3689 3932 name = "memmap2" ··· 5138 5381 ] 5139 5382 5140 5383 [[package]] 5384 + name = "sha1" 5385 + version = "0.10.6" 5386 + source = "registry+https://github.com/rust-lang/crates.io-index" 5387 + checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 5388 + dependencies = [ 5389 + "cfg-if", 5390 + "cpufeatures 0.2.17", 5391 + "digest", 5392 + ] 5393 + 5394 + [[package]] 5141 5395 name = "sharded-slab" 5142 5396 version = "0.1.7" 5143 5397 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5219 5473 source = "registry+https://github.com/rust-lang/crates.io-index" 5220 5474 checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" 5221 5475 dependencies = [ 5476 + "serde", 5222 5477 "version_check", 5223 5478 ] 5224 5479 ··· 5318 5573 version = "0.1.1" 5319 5574 source = "registry+https://github.com/rust-lang/crates.io-index" 5320 5575 checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" 5576 + 5577 + [[package]] 5578 + name = "subsecond" 5579 + version = "0.7.9" 5580 + source = "registry+https://github.com/rust-lang/crates.io-index" 5581 + checksum = "9cc79674bd55726e6b123204403389400229a95fe4a3b2c5453dada70b06ca95" 5582 + dependencies = [ 5583 + "js-sys", 5584 + "libc", 5585 + "libloading", 5586 + "memfd", 5587 + "memmap2", 5588 + "serde", 5589 + "subsecond-types", 5590 + "thiserror 2.0.18", 5591 + "wasm-bindgen", 5592 + "wasm-bindgen-futures", 5593 + "web-sys", 5594 + ] 5595 + 5596 + [[package]] 5597 + name = "subsecond-types" 5598 + version = "0.7.9" 5599 + source = "registry+https://github.com/rust-lang/crates.io-index" 5600 + checksum = "e9798bfed58797aed51c672aa99810aac30a50d3120ecfdcf28c13784e9a8f1c" 5601 + dependencies = [ 5602 + "serde", 5603 + ] 5321 5604 5322 5605 [[package]] 5323 5606 name = "svg_fmt" ··· 5655 5938 ] 5656 5939 5657 5940 [[package]] 5941 + name = "tungstenite" 5942 + version = "0.28.0" 5943 + source = "registry+https://github.com/rust-lang/crates.io-index" 5944 + checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" 5945 + dependencies = [ 5946 + "bytes", 5947 + "data-encoding", 5948 + "http", 5949 + "httparse", 5950 + "log", 5951 + "rand", 5952 + "sha1", 5953 + "thiserror 2.0.18", 5954 + "utf-8", 5955 + ] 5956 + 5957 + [[package]] 5658 5958 name = "twox-hash" 5659 5959 version = "2.1.2" 5660 5960 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5667 5967 checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" 5668 5968 5669 5969 [[package]] 5970 + name = "typenum" 5971 + version = "1.20.0" 5972 + source = "registry+https://github.com/rust-lang/crates.io-index" 5973 + checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" 5974 + 5975 + [[package]] 5670 5976 name = "typewit" 5671 5977 version = "1.15.2" 5672 5978 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5713 6019 version = "0.2.6" 5714 6020 source = "registry+https://github.com/rust-lang/crates.io-index" 5715 6021 checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 6022 + 6023 + [[package]] 6024 + name = "utf-8" 6025 + version = "0.7.6" 6026 + source = "registry+https://github.com/rust-lang/crates.io-index" 6027 + checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 5716 6028 5717 6029 [[package]] 5718 6030 name = "uuid" ··· 5772 6084 dependencies = [ 5773 6085 "same-file", 5774 6086 "winapi-util", 6087 + ] 6088 + 6089 + [[package]] 6090 + name = "warnings" 6091 + version = "0.2.1" 6092 + source = "registry+https://github.com/rust-lang/crates.io-index" 6093 + checksum = "64f68998838dab65727c9b30465595c6f7c953313559371ca8bf31759b3680ad" 6094 + dependencies = [ 6095 + "pin-project", 6096 + "tracing", 6097 + "warnings-macro", 6098 + ] 6099 + 6100 + [[package]] 6101 + name = "warnings-macro" 6102 + version = "0.2.0" 6103 + source = "registry+https://github.com/rust-lang/crates.io-index" 6104 + checksum = "59195a1db0e95b920366d949ba5e0d3fc0e70b67c09be15ce5abb790106b0571" 6105 + dependencies = [ 6106 + "proc-macro2", 6107 + "quote", 6108 + "syn", 5775 6109 ] 5776 6110 5777 6111 [[package]]
+3
Cargo.toml
··· 5 5 6 6 [features] 7 7 debug_physics = [] 8 + hot = [] # sub-second 8 9 9 10 [dependencies] 10 11 bevy = { version = "^0.18", features = ["file_watcher", "embedded_watcher", "free_camera", "jpeg", "experimental_bevy_ui_widgets"] } ··· 16 17 noisy_bevy = { branch = "main", git = "https://github.com/johanhelsing/noisy_bevy" } 17 18 rand = "0.9" 18 19 rand_chacha = "0.9" 20 + # bevy_simple_subsecond_system = "0.2.0" 21 + bevy_hotpatching_experiments = "0.4.0"
+52 -32
examples/two.rs
··· 1 1 #[cfg(feature = "debug_physics")] 2 2 use avian3d::prelude::PhysicsDebugPlugin; 3 + #[cfg(feature = "hot")] 4 + use bevy_hotpatching_experiments::prelude::*; 5 + 3 6 use avian3d::prelude::{ 4 - Collider, Forces, RayHitData, ReadRigidBodyForces, RigidBody, RigidBodyForces, 5 - RigidBodyQueryReadOnly, SpatialQuery, SpatialQueryFilter, WriteRigidBodyForces, 7 + Collider, Forces, RayHitData, ReadRigidBodyForces, RigidBody, RigidBodyQueryReadOnly, 8 + SpatialQuery, SpatialQueryFilter, WriteRigidBodyForces, 6 9 }; 7 10 use bevy::{ 11 + asset::RenderAssetUsages, 8 12 color::palettes::css::*, 9 13 image::{ImageAddressMode, ImageLoaderSettings, ImageSampler, ImageSamplerDescriptor}, 10 14 input::common_conditions::input_just_released, 11 15 light::NotShadowCaster, 12 16 math::Affine2, 17 + mesh::{Extrudable, Indices, PerimeterSegment, PrimitiveTopology, VertexAttributeValues}, 13 18 prelude::*, 14 19 }; 15 20 ··· 44 49 .add_systems(FixedUpdate, update_debug_text) 45 50 .add_systems( 46 51 FixedUpdate, 47 - ( 48 - // _debug_texture_samplers, 49 - player_off_the_ground, 50 - player_move, 51 - car_gizmo_render, 52 - ) 53 - .chain(), 52 + (player_off_the_ground, player_move, car_gizmo_render).chain(), 54 53 ) 55 54 .add_systems(Update, toggle_system) 56 55 .add_observer(flip_car); 57 56 57 + #[cfg(feature = "hot")] 58 + app.add_plugins(SimpleSubsecondPlugin::default()); 58 59 #[cfg(feature = "debug_physics")] 59 60 app.add_plugins(PhysicsDebugPlugin); 60 61 ··· 106 107 ) 107 108 } 108 109 110 + #[cfg(feature = "hot")] 111 + #[hot] 109 112 fn setup_two( 110 113 mut commands: Commands, 111 114 mut meshes: ResMut<Assets<Mesh>>, ··· 116 119 117 120 commands.spawn(debug_text_bundle()); 118 121 119 - // cube left 122 + // cube big flat 120 123 commands.spawn(( 121 - Mesh3d(meshes.add(Cuboid::new(10.0, 2.0, 10.0))), 124 + Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))), 122 125 MeshMaterial3d(materials.add(StandardMaterial { 123 126 base_color: rand_color(&mut rng), 124 127 base_color_texture: Some(asset_server.load_with_settings( ··· 126 129 |s: &mut _| { 127 130 *s = ImageLoaderSettings { 128 131 sampler: ImageSampler::Descriptor(ImageSamplerDescriptor { 129 - // rewriting mode to repeat image, 130 132 address_mode_u: ImageAddressMode::Repeat, 131 133 address_mode_v: ImageAddressMode::Repeat, 132 134 ..default() ··· 135 137 } 136 138 }, 137 139 )), 138 - 139 - // uv_transform used here for proportions only, but it is full Affine2 140 - // that's why you can use rotation and shift also 141 140 uv_transform: Affine2::from_scale(Vec2::new(10.0, 10.0)), 142 141 unlit: true, 143 142 ..default() 144 143 })), 145 - Transform::from_xyz(-10.0, 1.0, 0.0), 144 + Transform::from_xyz(-10.0, 1.0, 0.0).with_scale(Vec3::new(10.0, 2.0, 10.0)), 146 145 NotShadowCaster, 146 + Collider::cuboid(1.0, 1.0, 1.0), 147 + RigidBody::Static, 147 148 )); 148 149 149 - // cube right 150 + // cube bumps 150 151 for i in 0..5 { 151 152 commands.spawn(( 152 153 Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))), ··· 173 174 unlit: true, 174 175 ..default() 175 176 })), 176 - Transform::from_xyz(0.0, 0.7, 5.0 + i as f32 + 0.1) 177 - .with_scale(Vec3::new(3.0, 1.0, 0.5)), 177 + Transform::from_xyz(0.0, 0.7, 5.0 + i as f32 + 0.1).with_scale(Vec3::new( 178 + 3.0, 179 + 1.0 + (i as f32 * 0.1), 180 + 0.5, 181 + )), 178 182 NotShadowCaster, 179 183 Collider::cuboid(1.0, 1.0, 1.0), 180 184 RigidBody::Static, 181 185 )); 182 186 } 183 187 188 + let vertices = vec![ 189 + Vec2::new(0.0, 0.0), // Right angle corner at origin 190 + Vec2::new(2.0, 0.0), // Base corner 191 + Vec2::new(0.0, 1.5), // Top corner 192 + ]; 193 + 194 + // Create a convex polygon from the vertices 195 + let triangle = ConvexPolygon::new(vertices).expect("Triangle is convex"); 196 + let extrusion = Extrusion::new(triangle, 2.5); 197 + let ramp_collider = Collider::convex_decomposition_from_mesh(&extrusion.mesh().build()) 198 + .expect("unable to build ramp collider"); 199 + 184 200 commands.spawn(( 185 - Mesh3d(meshes.add(Cuboid::new(1.0, 3.5, 1.0))), 186 - // Mesh3d(meshes.add(Cylinder::default())), 201 + Mesh3d(meshes.add(extrusion)), 187 202 MeshMaterial3d(materials.add(StandardMaterial { 188 203 base_color: rand_color(&mut rng), 189 204 base_color_texture: Some(asset_server.load(PROTOTYPE_TEXTURE)), ··· 191 206 ..default() 192 207 })), 193 208 Transform::default() 194 - .with_scale(Vec3::splat(2.0)) 195 - .with_translation(Vec3::ZERO.with_x(-10.0)), 209 + .with_scale(Vec3::new(1.4, 1.0, 5.0)) 210 + .with_translation(Vec3::ZERO.with_x(-4.0)), 211 + ramp_collider, 212 + RigidBody::Static, 196 213 )); 197 214 } 198 215 ··· 229 246 movement: Query<&Action<Steer>>, 230 247 throttle: Query<&Action<Throttle>>, 231 248 mut camera_transform: Single<&mut Transform, With<CarCamera>>, 232 - mut forces: Single<Forces, With<Car>>, 249 + car: Single<Forces, With<Car>>, 233 250 mut car_gizmos: Gizmos<CarGizmos>, 234 251 ) { 235 252 let steering = movement ··· 239 256 .unwrap_or(Vec2::splat(0.0)); 240 257 let throttle = throttle.iter().next().map(|t| **t).unwrap_or(0.0); 241 258 259 + let mut car = car.into_inner(); 260 + 242 261 const SPEED: f32 = 12.0; 243 262 // move and steer the player car 244 263 let rotation = Quat::from_rotation_y(-steering.x * 0.05); 245 264 camera_transform.rotate_around(Vec3::ZERO, rotation); 246 265 let forward = (camera_transform.rotation * Vec3::NEG_Z).with_y(0.0); 247 - car_gizmos.ray(camera_transform.translation, forward, WHITE); 248 - forces.apply_force(forward * SPEED * throttle); 266 + car_gizmos.ray(car.position().0, forward, WHITE); 267 + car.apply_force(forward * SPEED * throttle); 249 268 } 250 269 251 270 pub fn car_gizmo_render( ··· 265 284 car_gizmos.axes(**player_transform, 2.0); 266 285 } 267 286 287 + #[cfg(feature = "hot")] 288 + #[hot] 268 289 pub fn player_off_the_ground( 269 290 player: Single<&mut Transform, With<Car>>, 270 291 spatial_query: SpatialQuery, ··· 272 293 mut car_gizmos: Gizmos<CarGizmos>, 273 294 forces_q: Single<Forces, With<Car>>, 274 295 ) { 275 - const REST_LENGTH: f32 = 0.95; 296 + const REST_LENGTH: f32 = 0.85; 276 297 const STRENGTH: f32 = 5.0; 277 - const DAMPING: f32 = 4.0; 298 + const DAMPING: f32 = 1.0; 278 299 279 300 let world_pos = player.translation; 280 301 let mut forces = forces_q.into_inner(); ··· 297 318 let spring_d = REST_LENGTH - hit.distance; 298 319 299 320 // only push up, never pull down — remove this clamp if you want a 2-sided spring 300 - if spring_d < 0.0 { 301 - continue; 302 - } 321 + // if spring_d < 0.0 { 322 + // continue; 323 + // } 303 324 304 325 let force_magnitude = (spring_d * STRENGTH) - (rel_vel * DAMPING); 305 326 ··· 332 353 ) -> Option<RayHitData> { 333 354 const RAYCAST_Z_DISTANCE: f32 = 10.0; 334 355 335 - // Raycast to find terrain 336 356 let filter = SpatialQueryFilter::DEFAULT; //SpatialQueryFilter::from_mask(FILTER_MASK_GROUND_PLACEMENT); 337 357 spatial_query.cast_ray(ray_origin, ray_dir, RAYCAST_Z_DISTANCE, true, &filter) 338 358 }
+1 -3
src/cars.rs
··· 1 - use avian3d::prelude::{ 2 - AngularDamping, Collider, ConstantForce, LinearDamping, LinearVelocity, RigidBody, 3 - }; 1 + use avian3d::prelude::{AngularDamping, Collider, LinearDamping, LinearVelocity, RigidBody}; 4 2 use bevy::{color::palettes::css::RED, prelude::*}; 5 3 6 4 use crate::{