Skip to content

Conversation

@aaronfranke
Copy link
Contributor

@aaronfranke aaronfranke commented Dec 11, 2025

This PR adds vehicles to Basis. Not just any vehicle system, the specific choice here matters a lot. Existing games often have extremely complex systems, where the minimum complexity is very high, and they are usually a mess of spaghetti code that is not very well thought through. Not through lack of effort, I'm sure - these are hard to do, and it genuinely took me a long time to make this PR with the quality bar I set for myself of a clean, minimal, extensible, well-abstracted solution. Therefore, my goal is specifically not to just copy an existing system like SaccFlightAndVehicles, but engineer a new standard.

I am developing this standard in the context of glTF extensions, and working under the OMI group umbrella. You can find the glTF extensions here and the prototype/reference Godot implementation here. Which means, yes, the same thing is implemented in 2 engines/frameworks, Godot, and Unity+Basis.

Right now Basis does not support glTF files, but it may in the future, and the intention here is that a vehicle can be set up once in your preferred content creation tool of choice (such as Blender, Godot, Unity, etc, even a Unity project that isn't Basis), and then use that same vehicle anywhere.

These vehicle extensions are designed as building blocks with layers of complexity. There is no "Car", a car is just a vehicle with wheels and no wings. There is no "SaccAirVehicle", an air vehicle would just be a vehicle body with airplane stuff attached, like wings. And so on and so on. You can compose these parts in any way you wish, to make a car-boat or whatever else. Think of it like Space Engineers or Kerbal Space Program style of assembling vehicles.

vehicle_piloting.mp4

The control of vehicles is fully abstracted. Pilot seats tell vehicles how to activate, vehicles read this input and turn it into general-purpose part controls based on handling characteristics, and the parts do what they can to follow the inputs they are given to work to propel the vehicle in the desired direction. In fact, the existence of a pilot seat at all is entirely optional. Vehicles can be directly controlled through script, providing endless possibilities for in-world scripting of NPC or custom-controlled vehicles with stuff like CILbox. Here is a demo of what it looks like to set the activation values manually in the Unity inspector:

vehicle_inspector_movement.mp4

Additionally, here is an example of a 6DoF spacecraft controlled via the inspector and piloting:

vehicle_spaceship.mp4

All of these examples are included in the PR. I am aware that these are very simple assets, I'm a programmer, not an artist, so I just grabbed these where I could (see copyrights.json for credits and licenses).

Note that this is specifically not intended as me coming in and saying "you have to do it this way". I did a lot of research into existing vehicle systems before making the initial versions of the standards a year ago, which you can find here in a file named mappings.md. The intention here is to be general and extensible. Also, making this PR was a good opportunity to carefully look over every detail of the specification and Godot implementation, and so I opened PRs to improve those as well: omigroup/gltf-extensions#255 and omigroup/omi-godot#19

The current PR is missing many features found in other vehicle systems, especially anything to do with airplane wings, flaps and other control surfaces, helicopter blades, boats/buoyancy, tank tracks, train tracks, damage, fuel consumption, air intakes, drag, diegetic controls, and more. The intent is to develop a lot more on top of this, and create a feature-rich vehicle system. Within this PR I am only including the things I am confident about: wheels, thrusters, hover thrusters, gyroscope torque, bodies, and pilot seats. When more things are developed, like those I listed, all future work should ideally have research and thought put into them, and be developed simultaneously as Unity C# code, Godot GDScript code, and importantly, glTF extension specifications.

@mriise
Copy link
Contributor

mriise commented Dec 11, 2025

🔥 There is no "Car", a car is just a vehicle with wheels and no wings. 🔥

masterpiece of a statement.

@aaronfranke aaronfranke marked this pull request as ready for review December 12, 2025 21:29
"initialStateCheck": true
},
{
"name": "RotateRoll",
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is clearly outside of the frameworks base use we need a way to wire this up without requring now that we need to support ThrottleZero, RotateRoll, ToggleAngularDampeners and ToggleLinearDampeners believe we could create the required data at runtime and wire up and destroy when exiting a vehicle.

Copy link
Collaborator

Choose a reason for hiding this comment

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

i would prefer to not include any textures, 3D models materials that are not apart of the framework in this manner, i would instead throw those up as a pulled in package for now to allow easily removal

{
return false; // Pitch is allowed if not seated.
}
if (_seat is Vehicles.BasisVehiclePilotSeat pilotSeat)
Copy link
Collaborator

Choose a reason for hiding this comment

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

this means we have logic that only works if a seat is of the varient pilot seat, i feel like thats going to cause frustration when someone else implements a pilot seat, can we check somehow if its not just a direct class reference but a interface, enum or other way?

Copy link
Contributor Author

@aaronfranke aaronfranke Dec 24, 2025

Choose a reason for hiding this comment

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

A custom class could extend BasisVehiclePilotSeat. If it didn't, and this checked for an interface instead, then a custom class would still need to extend that interface, so I don't see how that's better.

EDIT: Dooly said to rework this into a system where pilot seats can lock input into a generic pluggable way.

Copy link
Collaborator

Choose a reason for hiding this comment

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

BasisLocks.GetContext(BasisLocks.Crouching);

{
return false; // Pitch is allowed if not seated.
}
if (_seat is Vehicles.BasisVehiclePilotSeat pilotSeat)
Copy link
Collaborator

Choose a reason for hiding this comment

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

BasisLocks.GetContext(BasisLocks.Crouching);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants