Upgrading from v13 to v14
Migration guide for NWH Vehicle Physics 2 v13 to v14, covering breaking changes, API mapping, and upgrade procedures.
Quick Reference
Requirements
- Unity 6000 (Unity 6) is now required
- URP is now a package dependency (can be converted to Built-in if needed)
- Clean import is strongly recommended
Migration Difficulty
| Area | Difficulty | Impact |
|---|---|---|
| Infrastructure | Medium | Project restructure |
| WheelController | Medium | Component changes |
| VehicleComponent API | Low | Method signatures |
| Powertrain | Low | New features, mostly backward compatible |
| Force Feedback | Medium | Complete API replacement |
| Serialized Data | None | Prefabs should work |
Infrastructure Changes
| Aspect | v13 | v14 |
|---|---|---|
| Unity Version | 2022.x | 6000 (Unity 6) |
| Render Pipeline | Built-in RP | URP (default) |
| Package Format | Assets folder | UPM Package Manager |
| Force Feedback | LogitechGSDK | DirectInput |
| .NET Version | 4.x | 4.x / Standard 2.1 |
Package Structure
v14 uses Unity Package Manager format:
Packages/
├── com.nwh.vehiclephysics/
├── com.nwh.wheelcontroller/
├── com.nwh.common/
├── com.nwh.dynamicwaterphysics/ (if installed)
└── com.nwh.aerodynamics/ (if installed)
Render Pipeline Conversion
If you need Built-in RP instead of URP:
- Use the included conversion tool: NWH > Convert Folder URP to Built-in
- Or manually convert materials using Unity's render pipeline converter
Breaking API Changes
VehicleComponent Method Signatures
All VehicleComponent lifecycle methods now require a DeltaTime parameter:
// v13 - No delta time parameter
public override void VC_FixedUpdate()
{
base.VC_FixedUpdate();
// Physics code
}
public override void VC_Update()
{
base.VC_Update();
// Visual code
}
// v14 - Delta time required
public override void VC_FixedUpdate(float DeltaTime)
{
base.VC_FixedUpdate(DeltaTime);
// Physics code using DeltaTime
}
public override void VC_Update(float DeltaTime)
{
base.VC_Update(DeltaTime);
// Visual code using DeltaTime
}
Migration: Find and replace all VC_FixedUpdate() and VC_Update() overrides to include the parameter.
Delegate Signatures
Powertrain delegates now include delta time:
// v13 - No delta time
engine.powerModifier += () => CalculateBoost();
transmission.shiftDelegate = (vc) => CustomShift(vc);
// v14 - Delta time included
engine.powerModifier += (float dt) => CalculateBoost(dt);
transmission.shiftDelegate = (vc, dt) => CustomShift(vc, dt);
WheelController Changes
Friction System Refactored
The friction system has been extracted to a separate StandardFriction component with new static friction capabilities:
// v13 - Friction properties on WheelController
wheelController.forwardFriction.stiffness = 1.5f;
wheelController.sideFriction.stiffness = 1.2f;
wheelController.forwardFriction.grip = 1.0f;
wheelController.sideFriction.grip = 0.95f;
// v14 - Friction on StandardFriction component
StandardFriction friction = wheelController.GetComponent<StandardFriction>();
friction.stiffness = new Vector2(1.5f, 1.2f); // (longitudinal, lateral)
friction.grip = new Vector2(1.0f, 0.95f);
friction.staticFrictionEnabled = true; // New: Static friction for low-speed stability
Migration: The StandardFriction component is auto-added if missing. Transfer any custom friction settings.
New Static Friction System: v14 introduces static friction anchoring with critical damping for improved low-speed stability and realistic parking behavior. Key parameters:
staticFrictionEnabled- Enable/disable static frictionstaticFrictionStrength- Master switch for holding force (0-1)staticFrictionSpeedThreshold- Speed below which static mode activatesstaticBreakThreshold- Force required to break static friction
Wheel API Mapping
Complete mapping from v13 WheelUAPI to v14 WheelController:
| v13 (WheelUAPI) | v14 (WheelController) | Notes |
|---|---|---|
wheelUAPI |
wheelController |
Reference name change |
.MotorTorque |
.motorTorque |
Property case change |
.BrakeTorque |
.brakeTorque |
Property case change |
.SteerAngle |
.steerAngle |
Property case change |
.Radius |
.wheel.radius |
Moved to wheel struct |
.Width |
.wheel.width |
Moved to wheel struct |
.Mass |
.wheel.mass |
Moved to wheel struct |
.RPM |
.wheel.rpm |
Moved to wheel struct |
.AngularVelocity |
.wheel.angularVelocity |
Moved to wheel struct |
.Inertia |
.wheel.inertia |
Moved to wheel struct |
.IsGrounded |
.isGrounded |
Direct property |
.Load |
.load |
Direct property |
.HitPoint |
.wheelHit.point |
Moved to wheelHit struct |
.HitNormal |
.wheelHit.normal |
Moved to wheelHit struct |
.HitCollider |
.wheelHit.collider |
Moved to wheelHit struct |
.NormalizedLongitudinalSlip |
.normalizedSlip.x |
Vector2 component |
.NormalizedLateralSlip |
.normalizedSlip.y |
Vector2 component |
.SpringCompression |
.spring.compression |
Moved to spring struct |
.SpringLength |
.spring.length |
Moved to spring struct |
.SpringMaxLength |
.spring.maxLength |
Moved to spring struct |
.SpringForce |
.spring.force |
Moved to spring struct |
.DamperForce |
.damper.force |
Moved to damper struct |
Step() Method Change
// v13 - Simple Step
wheelController.Step();
// v14 - Step with parameters
wheelController.Step(float deltaTime, Matrix4x4 vehicleMatrix);
Note: When using with VehicleController, this is handled automatically via the substepping system.
New Properties in v14
| Property | Type | Description |
|---|---|---|
arbStiffness |
float | Anti-roll bar stiffness (N/m) |
arbDamping |
float | Anti-roll bar damping (Ns/m) |
implicitDamping |
float | Stability for low physics rates |
aligningMoment |
float | Force feedback data |
tireScrub |
float | Force feedback data |
camberCurve |
AnimationCurve | Camber vs suspension compression |
WheelControllerManager
New singleton manager coordinates all wheels:
// Access global wheel manager
WheelControllerManager manager = WheelControllerManager.Instance;
// Get wheel group for a vehicle
WheelControllerGroup group = manager.GetGroup(rigidbody);
// Configure substep rate
group.targetEffectiveRateOverride = 200; // Hz
The manager is auto-created when any WheelController enables.
Powertrain Changes
ClutchComponent
New dynamic engagement system:
| New Property | Type | Description |
|---|---|---|
dynamicEngagementEnabled |
bool | Enable dynamic engagement behavior |
highSpeedLockupProtection |
bool | Prevent stall during hard braking |
engagementRate |
float | How fast clutch engages (per second) |
disengagementRate |
float | How fast clutch disengages (per second) |
The clutch now uses a 5-state machine for lockup protection:
- Normal
- Protecting (braking detected)
- Releasing (disengaging to prevent stall)
- Recovering (re-engaging after protection)
- Cooldown (waiting period)
DifferentialComponent
New differential types and parameters:
// New enum
public enum DifferentialType
{
Open, // Standard open differential
LSD, // Limited-slip differential
Locked, // Fully locked (go-kart style)
Torsen // Torsen-style torque-sensing
}
| New Property | Type | Range | Description |
|---|---|---|---|
differentialType |
enum | - | Type selection |
powerRampAngle |
float | 1-89 | LSD ramp on acceleration |
coastRampAngle |
float | 1-89 | LSD ramp on deceleration |
preloadTorque |
float | Nm | LSD preload |
slipTorqueCoefficient |
float | 0-1 | LSD slip response |
torqueBiasRatio |
float | 1-5 | Torsen TBR |
TransmissionComponent
New shift type enum:
public enum TransmissionShiftType
{
Manual, // Player-controlled shifting
Automatic, // Automatic gear selection
CVT, // Continuously variable
External // External controller
}
New properties for gear skipping:
| Property | Description |
|---|---|
allowUpshiftGearSkipping |
Allow skipping gears on upshift |
allowDownshiftGearSkipping |
Allow skipping gears on downshift |
maxGearSkip |
Maximum gears to skip |
Force Feedback Migration
Complete Replacement
The SteeringWheelInputProvider (LogitechGSDK-based) is replaced by FFBInputProvider (DirectInput-based).
Setup Steps
Install Unity-DirectInput package:
- Window > Package Manager > + > Add package from git URL
- Enter:
https://github.com/imDanoush/Unity-DirectInput.git
Import the FFB Sample:
- In Package Manager, select NWH Vehicle Physics 2
- Expand Samples section
- Import "Direct Input FFB Sample"
Add FFB components:
- Add
FFBInputProviderto your scene (replaces SceneInputProvider) - Add
FFBVehicleSettingsto each vehicle for per-vehicle tuning
- Add
API Mapping
| v13 (LogitechGSDK) | v14 (DirectInput) |
|---|---|
SteeringWheelInputProvider |
FFBInputProvider |
| Logitech wheels only | All DirectInput wheels |
| Per-SDK configuration | Per-vehicle configuration |
Supported Wheels
The new DirectInput system supports all DirectInput-compatible wheels:
- Logitech (G25, G27, G29, G923, etc.)
- Thrustmaster (T150, T300, T500, etc.)
- Fanatec (all models)
- Moza (all models)
- Simagic (all models)
- Simucube (all models)
- Any DirectInput-compatible wheel
Step-by-Step Migration
1. Backup Project
Create a full backup before upgrading.
2. Update Unity
Upgrade to Unity 6000 (Unity 6).
3. Remove Old Package
Delete the old v13 installation (typically Assets/NWH/Vehicle Physics 2).
4. Install New Package
Import v14 via Package Manager or .unitypackage.
5. Fix Compilation Errors
Address breaking changes:
// Find all VC_FixedUpdate overrides without parameter
// Replace:
public override void VC_FixedUpdate()
// With:
public override void VC_FixedUpdate(float DeltaTime)
// Find all VC_Update overrides without parameter
// Replace:
public override void VC_Update()
// With:
public override void VC_Update(float DeltaTime)
6. Update Wheel References
// Find and replace:
wheelUAPI → wheelController
.BrakeTorque → .brakeTorque
.MotorTorque → .motorTorque
.Radius → .wheel.radius
.RPM → .wheel.rpm
// etc.
7. Test Prefabs
Open each vehicle prefab and:
- Verify WheelController has StandardFriction component
- Check friction settings transferred correctly
- Test physics behavior
8. Update FFB (if used)
- Remove old SteeringWheelInputProvider
- Install Unity-DirectInput package
- Import FFB sample
- Configure FFBInputProvider and FFBVehicleSettings
Compatibility Notes
What Requires Attention
- Custom VehicleComponent subclasses (add DeltaTime parameter)
- Scripts accessing WheelController friction (now on StandardFriction)
- Force feedback setups (switch to DirectInput)
- Custom input providers (update to v14 API)
Compatible Without Changes
- StateSettings, steering curves, brake parameters
- Input handler configuration
- Module configurations (ABS, TCS, ESC, etc.)
- Surface presets, transmission gearing
- Namespaces
Serialized Data
Prefabs and ScriptableObjects maintain their serialized values. v14 preserves serialization compatibility where possible.
Common Migration Issues
"Method signature mismatch" Errors
Cause: VC_FixedUpdate/VC_Update signature changed
Fix: Add float DeltaTime parameter to all overrides
"wheelUAPI not found" Errors
Cause: Field renamed to wheelController
Fix: Replace all instances of wheelUAPI with wheelController
Missing Friction Properties
Cause: Friction moved to StandardFriction component
Fix: Access via GetComponent<StandardFriction>()
Vehicle Handles Differently
Cause: New friction/physics systems may behave differently Fix: Tune friction presets, check ARB settings, verify substep count
FFB Not Working
Cause: Old LogitechGSDK system removed Fix: Install DirectInput package, use new FFBInputProvider
Support
For migration issues:
- Check this guide and documentation
- Email: nwhcoding@gmail.com
- Discord: https://discord.gg/59CQGEJ
Related Documentation
- WheelController - Wheel physics
- WheelControllerManager (WheelController3D package) - Substepping system
- Powertrain - Powertrain system
- Architecture - System overview
- FrictionPreset - Tire friction