Skip to content

Conversation

alice-i-cecile
Copy link
Member

@alice-i-cecile alice-i-cecile commented Jul 21, 2025

Objective

Moving the camera around is really important to validate that our scenes are rendered correctly.

Bevy engine devs currently do this via a fairly cursed "library example" which includes a basic freecam controller (which is technically distinct from a flycam apparently). This has three problems:

  1. Oh god why are we taking pseudo-dependencies on other examples.
  2. Something like this would be useful for debugging for users.
  3. Something like this would be useful for the editor and other tooling.

Solution

Create a new bevy_camera_controllers crate, and move the existing freecam implementation into it, nearly verbatim.

This cleans up some ugly tech debt in how we do this, makes it easier to add a camera controller to other examples, and also gives us a scaffold for future camera controllers.

This PR has been marked X-Blessed, as I went over this plan with @cart in a meeting on 2025-06-23, and we both agreed that this was the right first step.

Testing

I've tested the examples that rely on this camera controller: they work just like before.

Notes for reviewers

  • I don't intend to land this in Bevy 0.17: the existing example code is not high enough quality for me to be happy shipping this
    • we're also soft feature-frozen; I was just in the mood to do this today
  • this PR has some minimal cleanup: just enough naming and docs work to make this code not an active liability. Any more will risk derailing this PR and making it harder to review
  • I've opted to expose top-level feature flags for the various camera controllers. This is a bit noisy, but it was the only sensible way I could see to both have "no camera controllers by default" and "still easy to use these controllers in examples"
  • this will not be the only camera controller in this crate, or the Bevy Editor
    • this is not the place to discuss "what should the default camera controller for the Bevy Editor be"
    • if you think this crate, or this particular move is the wrong strategy for some other reason though, please do speak up :)
  • my personal (unblessed) hope is that we continue to add camera controllers to this crate as needed for various first-party tooling. I will probably largely push-back on adding camera controllers that we do not actively use to this crate, since I don't think they make great libraries in general (much better to copy-paste)

TODO

  • add release note. I'm waiting until after Bevy 0.17 ships to do this
  • update the examples/README.md file. I was lazy and didn't want to constantly resolve merge conflicts on that while this PR sits
  • change to singular crate name

Future work

  • split apart the giant camera controller component
  • make keybinding better, either with or without a real input manager solution
  • split apart the system to make it more modular
  • make the system handle fixed timesteps better
  • use the camera controller in more examples for debugging
  • add more camera controllers!

Module docs

Hook up new crate to bevy_internal
Stub for fly_cam camera controller

Steal existing free-cam controller
@alice-i-cecile alice-i-cecile added this to the 0.18 milestone Jul 21, 2025
@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible C-Code-Quality A section of code that is hard to understand or change S-Blocked This cannot move forward until something else changes M-Needs-Release-Note Work that should be called out in the blog due to impact X-Blessed Has a large architectural impact or tradeoffs, but the design has been endorsed by decision makers A-Camera User-facing camera APIs and controllers. labels Jul 21, 2025

This comment was marked as duplicate.

@alice-i-cecile alice-i-cecile changed the title Bevy camera controllers Add bevy_camera_controllers crate and move freecam implementation into it Jul 21, 2025
@atlv24
Copy link
Contributor

atlv24 commented Jul 21, 2025

i worry a bit about the added friction of having to run some examples with --features "free_cam" now

This comment was marked as duplicate.

@Aceeri
Copy link
Member

Aceeri commented Jul 21, 2025

i worry a bit about the added friction of having to run some examples with --features "free_cam" now

I think it's ok, there is some minor friction but the required-features should prompt people well enough and may add to discoverability of how to add FreeCam for your own project.

@alice-i-cecile
Copy link
Member Author

Yeah, the prompt is very helpful. I don't like having to add it, but the alternative is to add it to the default features. Since 99% of games won't want to ship with this in production, the only way to reclaim that binary size / compile speed will be to turn off Bevy's default features and slowly build it back up.

Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@BigWingBeat
Copy link
Contributor

I have some feedback and improvements in mind for this code, but as per the "notes for reviewers", I think it would mostly be out of scope for this initial PR. Should I wait until this PR is merged to follow-up on it, or is there an appropriate way to share the feedback immediately?

@alice-i-cecile
Copy link
Member Author

Leave your feedback here for now, and then we can come back to this thread for notes when merged :)

@BigWingBeat
Copy link
Contributor

BigWingBeat commented Jul 21, 2025

On line 183 (Github won't let me comment on that line directly because it's outside of the diff), the scroll delta is divided by 16 if the unit is pixels, and not if the unit is lines. This seems odd to me, both because it's undocumented, and because no other use of mouse scrolling I could find in Bevy cares about the scroll units.

The PR that added this was #11921, and reading the comments there reveals that the choice of 16 as the divisor was both arbitrary and untested.

Someone should actually test pixel scrolling, and either confirm that 16 is fine, or update it to something better (and also document it either way). Alternatively, the special-casing based on the units could just be removed entirely.

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Oct 7, 2025
@alice-i-cecile alice-i-cecile force-pushed the bevy-camera-controllers branch from 4282ae6 to b61287a Compare October 7, 2025 19:09
//! A camera controller that allows the user to move freely around the scene.
//!
//! Unlike other examples, which demonstrate an application, this demonstrates a plugin library.
//! Free cams are helpful for exploring large scenes, level editors and for debugging.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These docs are gone now from docs.rs due to the module not being pub, FYI

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, that's so sad. Reverting.

@alice-i-cecile alice-i-cecile dismissed janhohenheim’s stale review October 7, 2025 19:09

Schedule was changed

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Oct 7, 2025
Merged via the queue into bevyengine:main with commit 66e8232 Oct 7, 2025
40 checks passed
github-merge-queue bot pushed a commit that referenced this pull request Oct 8, 2025
…ler (#21450)

# Objective

As noted in
#20215 (comment) by
@BigWingBeat, the conversion factor used in the free cam camera
controller code that was added in #11921 arbitrary and untested.

This is a problem that users have stumbled across elsewhere, including
in #21140 and myself when writing leafwing-input-manager!

## Solution

1. Define a constant with the correct conversion factor, at least as
reported in #21140. This goes in `bevy_input` as it's broadly useful.
2. Use that constant in bevy_camera_controller::free_cam.
3. Approximately scale the default value on the camera controller to
compensate.

## Testing

We use this controller in a number of our examples. I chose `3d_gizmos`,
which worked just about the same before and after. The scroll wheel
controls your "walking speed".
github-merge-queue bot pushed a commit that referenced this pull request Oct 8, 2025
# Objective

As pointed out by @BigWingBeat in 
#20215 (comment)
the default mouse sensitivity of the free_cam controller is crazy high.

## Solution

Divide the sensitivity value by 5. 10 was too much, but 5 feels about
right for a "careful and controlled scene editor".

## Testing

`cargo run --example 3d_gizmos --features="free_cam"`
github-merge-queue bot pushed a commit that referenced this pull request Oct 9, 2025
# Objective

The `solari` example does not compile when run with the
required-features following #20215.

## Solution

Require the new free_cam feature.

## Testing

`cargo build --example solari --features="bevy_solari https free_cam"`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Camera User-facing camera APIs and controllers. C-Code-Quality A section of code that is hard to understand or change C-Feature A new feature, making something new possible M-Needs-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Blessed Has a large architectural impact or tradeoffs, but the design has been endorsed by decision makers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants