使用Bevy开发2048游戏:如何将主菜单实体居中显示?
问题:Bevy引擎中主菜单Node无法居中,始终显示在左上角
我正在用Rust结合Bevy引擎开发2048游戏来学习引擎用法,现在做主菜单场景时遇到了Transform的问题,可能是对Bevy的工作机制理解有误。
负责创建主菜单的函数代码如下:
pub fn main_menu(mut commands: Commands, asset_server: Res<AssetServer>) { commands .spawn(NodeBundle { style: Style { size: Size { width: Val::Percent(60.0), height: Val::Percent(60.0), }, ..default() }, transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)), // 尝试设置Transform但无效 background_color: Color::rgba_u8(92, 64, 64, 35).into(), ..default() }) .with_children(|parent| { // 文本 parent.spawn(TextBundle { text: Text { sections: vec![TextSection { value: "2048".to_string(), style: TextStyle { font: asset_server .load("font/Inconsolata-VariableFont_wdth,wght.ttf"), font_size: 50.0, color: Color::rgba_u8(168, 168, 168, 255).into(), }, }], ..Default::default() }, ..Default::default() }); }); println!("Hello from main menu!!"); }
我试过用GlobalTransform和Transform,但没区别;也怀疑是百分比尺寸的问题,改成像素尺寸后依然无效,矩形始终显示在屏幕左上角。

请问正确的实现方法是什么?
解决方法
在Bevy的UI系统中,Transform不是用来控制UI元素布局的,UI的位置和对齐完全通过Style组件实现,Transform主要服务于3D场景或非UI的2D元素,对UI的布局逻辑几乎没有影响。
要让主菜单Node居中,有两种标准实现方式:
直接给菜单Node设置绝对定位:修改
Style,添加绝对定位属性,通过计算剩余空间设置偏移量。代码示例:style: Style { size: Size { width: Val::Percent(60.0), height: Val::Percent(60.0), }, position_type: PositionType::Absolute, left: Val::Percent(20.0), // 宽度占60%,左右各留20% top: Val::Percent(20.0), // 高度占60%,上下各留20% // 若需内部文本也居中,可追加以下属性 justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..default() },通过父容器的Flex布局实现居中:先创建一个全屏的根Node,利用Flex属性开启全局居中,再将菜单Node作为其子节点。代码示例:
// 先创建全屏根容器 commands.spawn(NodeBundle { style: Style { size: Size::new(Val::Percent(100.0), Val::Percent(100.0)), justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..default() }, ..default() }).with_children(|parent| { // 在根容器内创建你的菜单Node parent.spawn(NodeBundle { style: Style { size: Size { width: Val::Percent(60.0), height: Val::Percent(60.0), }, // 若需内部文本居中,追加以下属性 justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..default() }, background_color: Color::rgba_u8(92, 64, 64, 35).into(), ..default() }).with_children(|menu_parent| { // 文本节点代码保持不变 menu_parent.spawn(TextBundle { text: Text { sections: vec![TextSection { value: "2048".to_string(), style: TextStyle { font: asset_server.load("font/Inconsolata-VariableFont_wdth,wght.ttf"), font_size: 50.0, color: Color::rgba_u8(168, 168, 168, 255).into(), }, }], ..Default::default() }, ..Default::default() }); }); });
Bevy的UI系统基于Flexbox布局,逻辑和网页CSS Flexbox一致,所有布局调整都应该通过Style组件完成,不要依赖Transform来控制UI位置。
内容的提问来源于stack exchange,提问作者Ruben Villalvazo Manríquez
相关产品推荐
相关产品推荐

