stargazing-dino / cosmic-junkyard

A space game
MIT License
1 stars 0 forks source link

Do we need `keep_upright`? Why not just lower center of gravity #27

Closed stargazing-dino closed 11 months ago

stargazing-dino commented 11 months ago

Would I need a keep_upright function if I instead moved the center of gravity of every body to somewhere lower? We have this explicit function that handles keeping the player upright but I'm not sure if this is the best way? Like, wouldn't things naturally try to balance themselves based on the center of mass of any entity?

#[derive(Component)]
pub struct Upright;

const ROTATION_SPEED: f32 = 0.3; // Adjust this value for faster/slower rotation correction

const ROTATION_THRESHOLD: f32 = 60.0; // Angle in degrees. Adjust based on desired gameplay.

pub fn keep_upright(mut gravity_bound_query: Query<(&mut Rotation, &GravityBound), With<Upright>>) {
    for (mut rotation, gravity_bound) in &mut gravity_bound_query {
        let gravity_force = gravity_bound.gravity_force;
        if gravity_force == Vec3::ZERO {
            continue;
        }

        let gravity_up = -gravity_force.normalize();
        let player_up = rotation.0 * Vec3::Y;

        // Calculate the rotation from the player's up vector to the gravity up vector
        let rotation_angle = player_up.angle_between(gravity_up).to_degrees();

        // If the angle exceeds the threshold, don't try to correct
        if rotation_angle > ROTATION_THRESHOLD {
            continue;
        }

        let rotation_axis = player_up.cross(gravity_up);

        if rotation_axis != Vec3::ZERO {
            let rotation_axis = rotation_axis.normalize();
            let rotation_diff = Quat::from_axis_angle(rotation_axis, rotation_angle.to_radians());

            let target_rotation = rotation_diff * rotation.0;

            // Gradually rotate the player to align with the gravity direction
            rotation.0 = rotation.0.lerp(target_rotation, ROTATION_SPEED);
        }
    }
}
stargazing-dino commented 11 months ago

AI:

The script you've shared is a function to keep a game entity (such as a player character) upright relative to a source of gravity in a gameplay style reminiscent of "Super Mario Galaxy". This "Upright" component and the associated system you've written are a valid approach to achieving this. The script basically checks for the difference between the current orientation of the player and the desired orientation based on the gravity direction and then smoothly rotates the player to align with the desired orientation.

Regarding your question about moving the center of gravity to somewhere lower, let's clarify a few things:

  1. Physics vs. Aesthetics: Adjusting the center of gravity of an object affects its physical behavior. For example, a toy with a lower center of gravity is less likely to tip over than one with a higher center. In game physics, shifting the center of gravity lower could make the character or entity more stable. However, simply adjusting the center of gravity won't inherently "correct" the orientation of the player to be upright. That would still require some logic like the one you've provided.

  2. Gameplay Feel: Changing the center of gravity might alter the overall feel of the player's movement. In some cases, this might be desirable as it could give a more "grounded" feel to the character. However, it might also make certain movements or actions feel heavier or more sluggish. It's important to playtest these changes to ensure they provide the desired gameplay experience.

  3. Complexity and Maintainability: Using a dedicated system (like your keep_upright function) to handle player orientation can be beneficial because it centralizes the logic. This can make it easier to tweak, debug, and extend in the future. Adjusting physical properties might give you the desired outcome, but it could introduce unforeseen side effects in other areas of your game.

  4. Performance: Both approaches would have some computational overhead, but in most game scenarios, the difference would likely be negligible. The code you've written should run efficiently for typical numbers of player entities.

In conclusion, while adjusting the center of gravity can influence the physical behavior of your entities in the game, it won't inherently make them align upright with the gravity source. If you want that behavior, a function like the one you've written is still necessary.

However, adjusting the center of gravity could complement your existing solution, potentially making the upright behavior feel more natural. If you're curious, I'd recommend trying both methods (individually and combined) and playtesting to see which provides the desired feel for your game.