Back to Main Page


This is a short overview of the quickly developed airbag proof of concept mod I created.

It's not a very complex mod, so I have taken the chance to explain more about the code involved this time, to give people a better insight into what goes on under the hood, in case they want to create their own version.

Download:
Airbags Test VS2015 Project File

I am providing this project in good faith. You can do whatever you like with this project, make any mods you like from it, take any code from it etc...

The only thing I ask for, is that you provide a simple credit with any project or mod you create, that acknowledges where the code came from. Please credit as LeeC2202

Please Note: This is a barebones project. That means that it provides basic functionality, whilst offering the opportunity to expand it to include additional features, if required.

Additional checking will need to be added to cater for the vehicle being destroyed, disappearing etc... This airbag system has been integrated into my DIS mod and that provides all the required checking, which is why I haven't added it here.

Airbags are meant to deploy in a fire, so there is scope for additional functionality there. Or you could make an airbag collection and place them around the vehicle. There are other options if you really want to expand the possibilities of this project.

Airbags - Markers to the Rescue... again.


Whilst browsing the 2 GTA V modding sites I visit, I noticed someone posted a request for airbags. It seemed an interesting challenge and it got my brain thinking. So a couple of days later, my brain kicked into gear and I started thinking about how it could be done. I knew that the idea probably wouldn't last for long, so I had to move quickly. Over the next couple of hours, I had something in place that proved it was a doable option, albeit not a perfect one.

There are two ways that you can approach this idea.

1) Create a set of airbag props that you animate between.

Pros:
Accurately shaped.
Fully textured.
Responds to the light and shadow in the game properly.

Cons:
The number of props you create dictates how smoothly changes take place. 1 prop per animation frame.
Cannot be scaled to cater for different sized cars.
Needs additional dlc.rpf to hold all the prop metadata, model data and textures.
Props have to be loaded which could cause animation irregularities. (unconfirmed)

I was thinking about this method last night, because loading and deleting props to animate them would be impractical, you would have to load all props and then make them invisible, then the animation code would make them visible in turn. I must confess, presuming a 3 state inflate and maybe 5 state deflate, that's a lot of props to carry round in the inside of a vehicle. You'd have to move them out of sight to be safe and then move them into place when it was their turn to display. I'm not sure if that's a guaranteed glitch-free way to be manipulating props. This more than anything, would make me hesitant to do this using this method.

2) Use a Sphere marker

Pros:
Scales independently in all 3 axes for smooth animation.
Can be scaled to any size dependent on car size.
Needs no additional files to work.

Cons:
Markers have no texture, so they always look flat.
Doesn't respond to light and shadow properly.
Has some translucency issues in certain lighting conditions.

Based on those pros and cons, I opted for the marker option. I felt the flexibility with size and the smoothness of animations meant it was something I felt happier with... plus no additional files required, always a bonus.

So the first task was "How to decide where the airbag will be?". All cars have a "steeringwheel" dummy and you can get the location of this dummy but you can't get its orientation. That was a problem because you need to align the airbag with the steering wheel. So my first thought was to create a pseudo-joint on the front axle, where the steering column would meet the axle. That's not how cars work now but it was an option and as you can see from this image, it seemed a good choice...

However, as you can probably guess, it didn't take long to expose the flaw with this method...

Any cars that had the steering wheel any closer to the front axle, or higher above the axle, were going to cause more problems. There are no other usable points of reference in the car, however, there is one that gets into the car... the player.

So the solution was to wait until the player is in the car, then get the position of two bones SKEL_Head and SKEL_Neck_1. I did try using just one of them but it wasn't ideal under different circumstances. So I got the two bone Z & Y positions and picked a point between those two locations, that gave me a target to aim at and that dictates the direction the airbag is pointed in. The X position was used from the steering wheel location, to make sure it was directly in-line.

That seems to work as well as any other method... so far at least.

// Get the position of the steering wheel dummy as an offset
SteeringWheelCentre = AirbagVehicle.GetOffsetFromWorldCoords(AirbagVehicle.GetBoneCoord("steeringwheel"));

// Get the SKEL_Head as the upper target point
Vector3 upperTarget = AirbagVehicle.GetOffsetFromWorldCoords(Game.Player.Character.GetBoneCoord(Bone.SKEL_Head));

// Set the airbag target to to the SKEL_Neck_1 dummy, then modify that location to get the final target position
AirbagTarget = AirbagVehicle.GetOffsetFromWorldCoords(Game.Player.Character.GetBoneCoord(Bone.SKEL_Neck_1));
AirbagTarget.X = SteeringWheelCentre.X;
AirbagTarget.Z += (upperTarget.Z - AirbagTarget.Z) / 2f;

As you are driving about, the direction is constantly updated based on those positions.

// Get the position and direction of the steering wheel
Vector3 steeringWheelPos = AirbagVehicle.GetOffsetInWorldCoords(SteeringWheelCentre);
Vector3 airbagTarget = AirbagVehicle.GetOffsetInWorldCoords(AirbagTarget);
SteeringColumnDirection = (airbagTarget - steeringWheelPos).Normalized;

So now I had the position and I had the direction, onto the process of managing the airbag deployment and transitions. I'm still not convinced that the method I am using is the right way, it's just the only way I could do it, based on my lack of ability with maths and physics.

Just before I move onto that, one other thing I did have to consider and that's which vehicles this would apply to and for that, I used a small validation function. It's probably over-simplified and it possibly misses some valid vehicles and includes some that are unsuitable but it works for the cars I use.

if (PlayerVehicle.Model.IsCar && PlayerVehicle.GetBoneIndex("steeringwheel") != -1)
{
    switch (PlayerVehicle.ClassType)
    {
        case VehicleClass.Compacts:
        case VehicleClass.Coupes:
        case VehicleClass.Muscle:
        case VehicleClass.Sedans:
        case VehicleClass.Sports:
        case VehicleClass.Super:
        case VehicleClass.SUVs:
        case VehicleClass.Vans:
            VehicleAirBag = new Airbag(PlayerVehicle);
            VehicleAirBag.InitialiseAirbag();
            IsValidVehicle = true;
            break;
        default:
            IsValidVehicle = false;
            break;
    }
}
else
{
    IsValidVehicle = false;
}

It checks to make sure the vehicle actually has a steering wheel, then includes a selection of the vehicle class types. Anyone using the project file from this page would probably need to extend this validation process. A hash based LUT is the most reliable way but not the most memory efficient way.

Next Page: Core Code