CesiumGS / cesium-unity

Bringing the 3D geospatial ecosystem to Unity
https://cesium.com/platform/cesium-for-unity/
Apache License 2.0
347 stars 83 forks source link

Support for arbitrary input methods for `CesiumCameraController` #414

Closed azrogers closed 7 months ago

azrogers commented 7 months ago

Currently, CesiumCameraController is set up to use a hardcoded InputActionMap that provides bindings for keyboard, mouse, and gamepad. If a user wants to support a new input method - for example, an XR controller - they have to copy the class and make their own modifications.

I think we should try to find a way to support arbitrary input methods. While CesiumCameraController isn't a "core" part of Cesium's technology by any means, it is one of the first things people interact with when starting a new project with Cesium for Unity, and making it easier to integrate new input methods would make it easier for people to make new AR and VR projects with Cesium.

I can think of two ways we can go about this:

  1. Using Unity's Input System

We're currently using Unity's Input System package in CesiumCameraController, falling back to the old UnityEngine.Input class when it's not available. Though we currently hardcode an InputActionMap for use with the camera controller, we could simply expose this as a property to the inspector, so that a user who wants to support a new controller can simply make a new Input Actions asset that defines the mapping.

This would be the simplest way to support new inputs, with only a few code changes needed. The disadvantage of this approach is that it makes it more difficult to do anything more complex than simply read a value from an input source and pass it on to the program. For example, specifying that you want the camera to move in the direction that the controller is pointed rather than the forward vector would require writing a custom input processor. But this is doable.

  1. Using an Additional Component

The other way to support new input methods would be to entirely detach input from CesiumCameraController using an interface and an additional component. This interface would have methods for things like GetMovementVector(), GetSpeedChange(), etc. We would provide a component out of the box implementing this interface that would use the hardcoded mapping we currently have, and then new input methods could be specified by writing a new implementation of the interface.

The advantage of this approach is that it would support pretty much every input method and scenario imaginable. Things like, for example, performing a raycast to get the movement vector, would be a lot easier to implement in this method than using an InputActionMap. This, of course, comes at the cost of accessibility to the end user.

csciguy8 commented 7 months ago

I like your chosen direction of 1). Seems like a natural evolution of CesiumCameraController.

I suppose we can always go 2) later should we find a compelling need.