Change Vehicle Wheel Tire Type at runtime

How do I correctly change the UVehicleWheel TireType at runtime? I can set it with something like:

GetVehicleMovement()->Wheels[i]->TireType = MediumFrictionTiretype;

but the assignment doesn’t seem to have any effect. I tried reinitializing what I safely could without any luck.

The issue with setting something like the FrictionScale for the current TireType is that it affects all instances of a given vehicle class, so if one vehicle’s wheel friction is modified, they all feel it. Since they appear to be shared at the PhysXVehicleManager level, I thought a good workaround would be different TireTypes, and I’m here asking in case separating these at the engine level is a fool’s errand.

@oricohen If you’ve got a moment please let me know if you have any ideas. Thanks!

An update for anyone finds themselves here:

I took a look at the PhysXVehicleManager and I can see that it would be reasonable to include some kind of interface on a WheeledVehicle that provides something like a FrictionMultiplier, such that when the surface and tire pairs are being assembled for PhysX each particular pair would also be made aware of any vehicle instance-specific friction modifier. However, I didn’t spend a lot of time poking around in there, so I’m not especially confident that that’s a good approach, but I will soon dig further since it will eventually be an issue for my game.

Since my current project is primarily multiplayer, the shared tire type is only an issue for local testing with multiple clients, and that can probably be overcome with a crappy PlayerOneTireType and PlayerTwoTireType approach. Bots don’t really need to drift so they can just have a BotTireType. Not the kind of code I’d like to write but seems like the simplest solution at this stage.

VehicleGame.Build.cs

		PrivateDependencyModuleNames.AddRange(
			new string[] {
				"Slate",
				"SlateCore",
				"PhysX",
			}
		);




class UVehicleMovementComponentBoosted4w

VehicleMovementComponentBoosted4w.h

	/** Wheel Lat Stiff */
	UFUNCTION(BlueprintCallable, Category = "Wheel")
	void SetWheelLatStiff(int32 WheelIndex, float LatStiffValue, float LatStiffMaxLoad, float LongStiffValue, class UTireType* TireType);

	/** Wheel Friction*/
	UFUNCTION(BlueprintCallable, Category = "Wheel")
	void SetWheelFrictionScale(int32 WheelIndex, class UTireType* TireType);

	
VehicleMovementComponentBoosted4w.cpp
	
#if WITH_PHYSX
#include "PxVehicleWheels.h"
#endif //WITH_PHYSX


void UVehicleMovementComponentBoosted4w::SetWheelLatStiff(int32 WheelIndex, float LatStiffValue, float LatStiffMaxLoad, float LongStiffValue, class UTireType* TireType)
{

	if (WheelIndex >= 0 && LatStiffValue > 0.01 && LatStiffMaxLoad > 0.01 && LongStiffValue > 0.01 && Wheels.Num() > WheelIndex)
	{
		Wheels[WheelIndex]->LatStiffValue = LatStiffValue;
		Wheels[WheelIndex]->LatStiffMaxLoad = LatStiffMaxLoad;
		Wheels[WheelIndex]->LongStiffValue = LongStiffValue;
		Wheels[WheelIndex]->TireType = TireType;

		// init tire data
		// physx::PxVehicleTireData PTireData;
		physx::PxVehicleTireData PTireData;
		PTireData.mType = Wheels[WheelIndex]->TireType ? Wheels[WheelIndex]->TireType->GetTireTypeID() : GEngine->DefaultTireType->GetTireTypeID();
		PTireData.mLatStiffX = Wheels[WheelIndex]->LatStiffMaxLoad;
		PTireData.mLatStiffY = Wheels[WheelIndex]->LatStiffValue;
		PTireData.mLongitudinalStiffnessPerUnitGravity = Wheels[WheelIndex]->LongStiffValue;
		
		PVehicle->mWheelsSimData.setTireData(WheelIndex, PTireData);
	}

	
}

void UVehicleMovementComponentBoosted4w::SetWheelFrictionScale(int32 WheelIndex, class UTireType* TireType)
{
	if (WheelIndex >= 0 && Wheels.Num() > WheelIndex)
	{
		Wheels[WheelIndex]->TireType = TireType;
		// init tire data
		// physx::PxVehicleTireData PTireData;
		physx::PxVehicleTireData PTireData;
		PTireData.mType = Wheels[WheelIndex]->TireType ? Wheels[WheelIndex]->TireType->GetTireTypeID() : GEngine->DefaultTireType->GetTireTypeID();
		PTireData.mLatStiffX = Wheels[WheelIndex]->LatStiffMaxLoad;
		PTireData.mLatStiffY = Wheels[WheelIndex]->LatStiffValue;
		PTireData.mLongitudinalStiffnessPerUnitGravity = Wheels[WheelIndex]->LongStiffValue;

		PVehicle->mWheelsSimData.setTireData(WheelIndex, PTireData);
	}
}

This appears to work quite well. Thank you!

https://puu.sh/tk7zX/0fb3827155.png

https://puu.sh/tk7Fm/0c7560b158.png

It drops many errors about pointers, feels like I’m missing something, any tips?

Found fix:
#include “Vehicles/VehicleWheel.h” should be added into .cpp to fix pointers errors

I have the same issue as Pirog. The Include also does not work because it :
Cannot open include file: ‘VehicleWheel.h’: No such file or directory

I really do not understand why this include does not work.
Help would be really appreciated

VehicleGame.Build.cs

public VehicleGame(ReadOnlyTargetRules Target) : base (Target)
{


    PublicDependencyModuleNames.AddRange(
        new string[] {
            "Core",
            "CoreUObject",
            "Engine",
            "InputCore",
            "PhysX",
            "APEX",
            "PhysXVehicles",
            "PhysXVehicleLib",
            "MessagingRpc",
            "PortalRpc",
            "Networking",
            "Sockets",
            "PortalServices",
            "OnlineSubsystem",
            "OnlineSubsystemUtils",
            "Steamworks",
            "SteamParty",
            "OnlineSubsystemSteam",
		

        }
    );

    PrivateDependencyModuleNames.AddRange(
        new string[] {
            "Slate",
            "SlateCore",
            "OnlineSubsystem",
            "Sockets",
            "Networking",
            "OnlineSubsystemUtils",
            "PhysXVehicles",
            "PhysXVehicleLib",
        }
    );

VehicleMovementComponentBoosted4w.h

#pragma once
#include "WheeledVehicle.h"
#include "WheeledVehicleMovementComponent.h"
#include "WheeledVehicleMovementComponent4W.h"
#include "VehicleMovementComponentBoosted4w.generated.h"

VehicleMovementComponentBoosted4w.cpp

#include "VehicleGame.h"
#include "Pawns/VehicleMovementComponentBoosted4w.h"

#if WITH_PHYSX
//For Scene Locking using Epic's awesome helper macros like SCOPED_SCENE_READ_LOCK
#include "Runtime/Engine/Private/PhysicsEngine/PhysXSupport.h"
#include "PhysicsPublic.h"
#include "PhysXPublic.h"
#include "Runtime/Engine/Private/PhysicsEngine/PhysXSupport.h"
    
#endif //WITH_PHYSX

Thank you very much, i forgot to add the Public and Private Dependencies.
Now it is working properly!