【rust/bevy】从game template开始

这篇具有很好参考价值的文章主要介绍了【rust/bevy】从game template开始。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说在前面

  • 操作系统:win11
  • rust版本:rustc 1.77.0-nightly
  • bevy版本:0.12

步骤

  • rust安装
    这里
    windows下建议使用msvc版本
  • bevy安装
    这里
  • clone代码
    git clone https://github.com/NiklasEi/bevy_game_template.git
    
  • 运行
    cargo run
    
  • 结果
    【rust/bevy】从game template开始,Rust,rust,开发语言,bevy,游戏引擎

进入3D

  • template中的例子是2d的,我们稍微修改下
  • 首先增加一个CameraController,代码在bevy的例程中也可以找到
    //! A freecam-style camera controller plugin.
    //! To use in your own application:
    //! - Copy the code for the [`CameraControllerPlugin`] and add the plugin to your App.
    //! - Attach the [`CameraController`] component to an entity with a [`Camera3dBundle`].
    
    use bevy::window::CursorGrabMode;
    use bevy::{input::mouse::MouseMotion, prelude::*};
    
    use std::f32::consts::*;
    use std::fmt;
    
    /// Based on Valorant's default sensitivity, not entirely sure why it is exactly 1.0 / 180.0,
    /// but I'm guessing it is a misunderstanding between degrees/radians and then sticking with
    /// it because it felt nice.
    pub const RADIANS_PER_DOT: f32 = 1.0 / 180.0;
    
    #[derive(Component)]
    pub struct CameraController {
        pub enabled: bool,
        pub initialized: bool,
        pub sensitivity: f32,
        pub key_forward: KeyCode,
        pub key_back: KeyCode,
        pub key_left: KeyCode,
        pub key_right: KeyCode,
        pub key_up: KeyCode,
        pub key_down: KeyCode,
        pub key_run: KeyCode,
        pub mouse_key_enable_mouse: MouseButton,
        pub keyboard_key_enable_mouse: KeyCode,
        pub walk_speed: f32,
        pub run_speed: f32,
        pub friction: f32,
        pub pitch: f32,
        pub yaw: f32,
        pub velocity: Vec3,
    }
    
    impl Default for CameraController {
        fn default() -> Self {
            Self {
                enabled: true,
                initialized: false,
                sensitivity: 1.0,
                key_forward: KeyCode::W,
                key_back: KeyCode::S,
                key_left: KeyCode::A,
                key_right: KeyCode::D,
                key_up: KeyCode::E,
                key_down: KeyCode::Q,
                key_run: KeyCode::ShiftLeft,
                mouse_key_enable_mouse: MouseButton::Left,
                keyboard_key_enable_mouse: KeyCode::M,
                walk_speed: 5.0,
                run_speed: 15.0,
                friction: 0.5,
                pitch: 0.0,
                yaw: 0.0,
                velocity: Vec3::ZERO,
            }
        }
    }
    
    impl fmt::Display for CameraController {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(
                f,
                "
    Freecam Controls:
        MOUSE\t- Move camera orientation
        {:?}/{:?}\t- Enable mouse movement
        {:?}{:?}\t- forward/backward
        {:?}{:?}\t- strafe left/right
        {:?}\t- 'run'
        {:?}\t- up
        {:?}\t- down",
                self.mouse_key_enable_mouse,
                self.keyboard_key_enable_mouse,
                self.key_forward,
                self.key_back,
                self.key_left,
                self.key_right,
                self.key_run,
                self.key_up,
                self.key_down
            )
        }
    }
    
    pub struct CameraControllerPlugin;
    
    impl Plugin for CameraControllerPlugin {
        fn build(&self, app: &mut App) {
            app.add_systems(Update, camera_controller);
        }
    }
    
    fn camera_controller(
        time: Res<Time>,
        mut windows: Query<&mut Window>,
        mut mouse_events: EventReader<MouseMotion>,
        mouse_button_input: Res<Input<MouseButton>>,
        key_input: Res<Input<KeyCode>>,
        mut move_toggled: Local<bool>,
        mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
    ) {
        let dt = time.delta_seconds();
    
        if let Ok((mut transform, mut options)) = query.get_single_mut() {
            if !options.initialized {
                let (yaw, pitch, _roll) = transform.rotation.to_euler(EulerRot::YXZ);
                options.yaw = yaw;
                options.pitch = pitch;
                options.initialized = true;
            }
            if !options.enabled {
                return;
            }
    
            // Handle key input
            let mut axis_input = Vec3::ZERO;
            if key_input.pressed(options.key_forward) {
                axis_input.z += 1.0;
            }
            if key_input.pressed(options.key_back) {
                axis_input.z -= 1.0;
            }
            if key_input.pressed(options.key_right) {
                axis_input.x += 1.0;
            }
            if key_input.pressed(options.key_left) {
                axis_input.x -= 1.0;
            }
            if key_input.pressed(options.key_up) {
                axis_input.y += 1.0;
            }
            if key_input.pressed(options.key_down) {
                axis_input.y -= 1.0;
            }
            if key_input.just_pressed(options.keyboard_key_enable_mouse) {
                *move_toggled = !*move_toggled;
            }
    
            // Apply movement update
            if axis_input != Vec3::ZERO {
                let max_speed = if key_input.pressed(options.key_run) {
                    options.run_speed
                } else {
                    options.walk_speed
                };
                options.velocity = axis_input.normalize() * max_speed;
            } else {
                let friction = options.friction.clamp(0.0, 1.0);
                options.velocity *= 1.0 - friction;
                if options.velocity.length_squared() < 1e-6 {
                    options.velocity = Vec3::ZERO;
                }
            }
            let forward = transform.forward();
            let right = transform.right();
            transform.translation += options.velocity.x * dt * right
                + options.velocity.y * dt * Vec3::Y
                + options.velocity.z * dt * forward;
    
            // Handle mouse input
            let mut mouse_delta = Vec2::ZERO;
            if mouse_button_input.pressed(options.mouse_key_enable_mouse) || *move_toggled {
                for mut window in &mut windows {
                    if !window.focused {
                        continue;
                    }
    
                    window.cursor.grab_mode = CursorGrabMode::Locked;
                    window.cursor.visible = false;
                }
    
                for mouse_event in mouse_events.read() {
                    mouse_delta += mouse_event.delta;
                }
            }
            if mouse_button_input.just_released(options.mouse_key_enable_mouse) {
                for mut window in &mut windows {
                    window.cursor.grab_mode = CursorGrabMode::None;
                    window.cursor.visible = true;
                }
            }
    
            if mouse_delta != Vec2::ZERO {
                // Apply look update
                options.pitch = (options.pitch - mouse_delta.y * RADIANS_PER_DOT * options.sensitivity)
                    .clamp(-PI / 2., PI / 2.);
                options.yaw -= mouse_delta.x * RADIANS_PER_DOT * options.sensitivity;
                transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, options.yaw, options.pitch);
            }
        }
    }
    
  • 再添加一个SceneSetup,用于初始化场景和相机
    use bevy::prelude::*;
    use bevy::app::{Plugin, App, Startup};
    
    use crate::camera::CameraController;
    
    pub struct SceneSetupPlugin;
    
    impl Plugin for SceneSetupPlugin {
        fn build(&self, app: &mut App) {
            app.add_systems(Startup, setup);
        }
    }
    
    /// set up a simple 3D scene
    fn setup(
        mut commands: Commands,
        mut meshes: ResMut<Assets<Mesh>>,
        mut materials: ResMut<Assets<StandardMaterial>>,
    ) {
        // circular base
        commands.spawn(PbrBundle {
            mesh: meshes.add(shape::Circle::new(4.0).into()),
            material: materials.add(Color::WHITE.into()),
            transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
            ..default()
        });
        // cube
        commands.spawn(PbrBundle {
            mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
            material: materials.add(Color::rgb_u8(124, 144, 255).into()),
            transform: Transform::from_xyz(0.0, 0.5, 0.0),
            ..default()
        });
        // light
        commands.spawn(PointLightBundle {
            point_light: PointLight {
                intensity: 1500.0,
                shadows_enabled: true,
                ..default()
            },
            transform: Transform::from_xyz(4.0, 8.0, 4.0),
            ..default()
        });
        let camera_controller = CameraController::default();
        // camera
        commands.spawn((Camera3dBundle {
            transform: Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
            ..default()
        },camera_controller));
    }
    
  • 将GamePlugin中的代码修改下进行测试
    impl Plugin for GamePlugin {
        fn build(&self, app: &mut App) {
            app.add_state::<GameState>().add_plugins((
                // LoadingPlugin,
                // MenuPlugin,
                SceneSetupPlugin,
                // ActionsPlugin,
                // InternalAudioPlugin,
                // PlayerPlugin,
                CameraControllerPlugin
            ));
    
            #[cfg(debug_assertions)]
            {
                app.add_plugins((FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin::default()));
            }
        }
    }
    
  • 结果
    【rust/bevy】从game template开始,Rust,rust,开发语言,bevy,游戏引擎

控制方块

  • 上面的测试中我们将游戏流程注释掉了,现在我们尝试加回来,并将方块作为我们的Player
  • 首先将player设置为方块(不要忘记将上面场景中的方块去掉)
    fn spawn_player(mut commands: Commands, 
        mut meshes: ResMut<Assets<Mesh>>,
        mut materials: ResMut<Assets<StandardMaterial>>) {
        commands.spawn(PbrBundle {
            mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
            material: materials.add(Color::rgb_u8(124, 144, 255).into()),
            transform: Transform::from_xyz(0.0, 1., 0.0),
            ..default()
        })
        .insert(Player);
    }
    
  • 然后将actions中的相机改为3d
    pub fn set_movement_actions(
        mut actions: ResMut<Actions>,
        keyboard_input: Res<Input<KeyCode>>,
        touch_input: Res<Touches>,
        player: Query<&Transform, With<Player>>,
        camera: Query<(&Camera, &GlobalTransform), With<Camera3d>>,
    ) {
        // ...
    }
    
  • 然后我们先去掉menu中的相机
    fn setup_menu(mut commands: Commands, textures: Res<TextureAssets>) {
        info!("menu");
        // commands.spawn(Camera2dBundle::default());
        // ...
    
  • 结果(将move_player中的速度调低点)
    【rust/bevy】从game template开始,Rust,rust,开发语言,bevy,游戏引擎
  • 不过这里我们的ui和场景显示到一块了,后面再看看怎么处理

问题

  • note: LINK : fatal error LNK1189: 超过 65535 对象的库限制
    参考这个解决

文章来源地址https://www.toymoban.com/news/detail-800082.html

到了这里,关于【rust/bevy】从game template开始的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【从零开始的rust web开发之路 一】axum学习使用

    第一章 axum学习使用 本职java开发,兼架构设计。空闲时间学习了rust,目前还不熟练掌握。想着用urst开发个web服务,正好熟悉一下rust语言开发。 目前rust 语言web开发相关的框架已经有很多,但还是和java,go语言比不了。 这个系列想完整走一遍web开发,后续有时间就出orm,还

    2024年02月12日
    浏览(52)
  • 【从零开始的rust web开发之路 二】axum中间件和共享状态使用

    第一章 axum学习使用 第二章 axum中间件使用 上篇文件讲了路由和参数相应相关的。axum还有个关键的地方是中间件的使用,这篇文件就来说说。 这个概念跟gin框架的中间件概念一样,类似于springboot项目当中的请求过滤器,在请求过来的时候链式执行一些操作。例如鉴权,日志

    2024年02月11日
    浏览(50)
  • Rust语言从入门到入坑——(2)Rust在windows上搭建开发环境

    开始搭建一个适合在windows上运行的Rust环境。 Rust支持的程序语言很多:可详见官网介绍 本文章主要是在windowns下搭建开发环境 首先,需要安装最新版的 Rust 编译工具和 Visual Studio Code。 Rust 编译工具:https://www.rust-lang.org/zh-CN/tools/install Visual Studio Code:https://code.visualstudio.com

    2024年02月09日
    浏览(50)
  • 【rust/egui】(六)看看template的app.rs:TextEdit

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 文本编辑框 其定义为: 用起来可能是个简单的东西,但是实际上很是复杂,首先我们来看看它的外观以及用法 在 app.rs 中,我们是通

    2024年02月11日
    浏览(54)
  • 【rust/egui】(七)看看template的app.rs:Slider

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 滑块,如下图 定义: 我们可以通过 ui.add() 的方式进行添加: 其 new 方法的定义为: 参数 value 为可变借用类型,且使用 Numeric 特性进

    2024年02月10日
    浏览(38)
  • Rust软件外包开发语言的特点

    Rust 是一种系统级编程语言,强调性能、安全性和并发性的编程语言,适用于广泛的应用领域,特别是那些需要高度可靠性和高性能的场景。下面和大家分享 Rust 语言的一些主要特点以及适用的场合,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公

    2024年02月12日
    浏览(47)
  • 【rust/egui】(三)看看template的app.rs:序列化、持久化存储

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 app.rs 中首先定义了我们的 TemplateApp 结构体 在定义 TemplateApp 时,我们让其继承了 serde::Deserialize, serde::Serialize 。 serde 是rust中用于序列

    2024年02月11日
    浏览(37)
  • 【rust/egui】(五)看看template的app.rs:SidePanel、CentralPanel以及heading

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 侧边栏,如下图 其定义为: 通过 right() 或 left() 方法生成: 方法实现与 TopBottomPanel::top() 类似: 生成时的默认属性值为: 我们可以将

    2024年02月11日
    浏览(40)
  • 【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 update 实际上还是 eframe::App 的特征,并非 egui 的内容。其官方注解如下: update 函数会在需要重绘ui(或者其他)的时候被调用,一秒可能

    2024年02月11日
    浏览(44)
  • 【rust/egui】(二)看看template的main函数:日志输出以及eframe run_native

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 首先让我们看看 main.rs 中有些什么 在 eframe 中使用的日志库为 log 以及 env_logger ,其日志等级有5个: 我们可以在main函数中添加测试一

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包