Right now Android support on Bevy is not as great as in Unity. But it is improving and it is possible to use Bevy on Android.
In case of the issues with touch input on Android check out my note on touch input in Android.
I also recommend listening to Bevy meetup where Marco Meijer describes how he uses Bevy on Android already: YouTube
Basic setup
Check out Bevy's mobile example. It provides a sample project that lets you build game for Android in different ways. Be aware that:
android_basicis using a deprecatedcargo-apk, so I would not recommend it.android_example_nativeis usingNativeActivitywhich is replaced byGameActivityin Android, so I would rather not use it.android_exampleis the one that usesGameActivityand I would recommended this one.
Before building android_example install Android SDK and NDK first, then install cargo-ndk following the guide on repo: cargo-ndk. Then you would be able to build the game as a library that will be loaded by GameActivity. To do that run:
cargo ndk -t arm64-v8a -o android_example/app/src/main/jniLibs build --package bevy_mobile_example
After that in the CLI go to the android_example directory and run:
./gradlew build
You should now have the APK file in the android_example/app/build/outputs/apk/debug directory.
GLES3 setup
While Vulkan is already supported on most of the Android devices, going with GLES3 is still a good choice that lets cover more devices.
Setup the RenderPlugin in the DefaultPlugins:
// ...
use bevy::render::RenderPlugin;
use bevy::render::settings::{Backends, RenderCreation, WgpuLimits, WgpuSettings};
app.add_plugins(DefaultPlugins
.set(RenderPlugin {
render_creation: RenderCreation::Automatic(WgpuSettings {
backends: Some(Backends::GL),
limits: WgpuLimits::downlevel_webgl2_defaults(),
instance_flags: InstanceFlags::default(),
features: WgpuFeatures::empty(),
..default()
}),
..default()
}))
// ...
In the AndroidManifest.xml file, add the following line before the <application> tag:
<uses-feature android:glEsVersion="0x00030002" android:required="true" />
<uses-feature android:name="android.hardware.vulkan.version" android:required="false" />
<!-- ... -->
<application
android:icon="@mipmap/ic_launcher"
Since Bevy 0.17 OpenGL is not enabled by default. To enable it, you need to add the following to your Cargo.toml file:
[target.'cfg(target_os = "android")'.dependencies.bevy_render]
version = "0.17"
features = ["gles"]
I learned it the hard way. On game startup on Android I was getting error:
Unable to find a GPU! Make sure you have installed required drivers!.
Too weak device for PBR
If on startup of Bevy game on Android you get the following error:
Device::create_bind_group_layout, label = 'mesh_view_layout_oit'
Too many bindings of type StorageBuffers in Stage ShaderStages(FRAGMENT), limit is 4, count was 5.
Check the limit `max_storage_buffers_per_shader_stage` passed to `Adapter::request_device`
Good chance is that your device is too weak to run PBR. Make sure that you have bevy_pbr disabled in your Cargo.toml file. Or you can disable it by hand while doing setup for DefaultPlugins:
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins
.set(LogPlugin {
// This will show some log events from Bevy to the native logger.
level: Level::INFO,
filter: "wgpu=error".to_string(),
..Default::default()
})
.disable::<PbrPlugin>())
.run();
}
Other notes
I also recommend checking out:
This work is licensed under CC BY-NC-SA 4.0.
Piotr Siuszko
GameDev tool engineer, C#/C++ at day, Rust at night.