Update ChaosVehicleWheel during runtime

Hello All,

Currently in 5.4 as a C++ project. Working through some chaos vehicle madness. Curious if anyone has had any luck or can give any recommendations on how to go about making updates to wheel properties during runtime? The current example I’m trying to get through is updating the CorneringStiffness. In this, I created a class off UChaosVehicleWheel to Get/Set CorneringStiffness on my wheels. Then calling these in my vehicle pawn class off AWheeledVehiclePawn.

While I can update the value and get a log of the update, the cornering stiffness affect on the wheels doesn’t update. It feels like the physics just aren’t getting updated, so I’ve been stuck trying different solutions with no luck. The logic I currently have is to update CorneringStiffness when Throttle Input is >= 0.8, to make testing easier. I have tried setting to 1 while defaults have been around 300, which gives me a quick result during testing as having a cornering stiffness that low would cause the wheels to essentially have no cornering ability. I’ve tried writing the logic in both C++ and with blueprints, reading that it could possibly be a C++ issue not updating the properties but still no luck.

Another attempt I had was to update the Chaos Vehicle plugin files under the Engine folder but I get compiling errors saying to rebuild the source files which I ultimately wasn’t able to solve so I backed those updates out. The idea was that since I can update the steer angle through ChaosWheeledVehicleMovement, pointer to UChaosWheeledVehicleMovementComponent GetVehicleMovement(), then I could add in the logic to update the cornering stiffness. So maybe this could be a possibility, just couldn’t figure out the issues I was having there.

Vehicle_Pawn_CS.h
UCLASS()
class AVehicle_Pawn_CS : public AVehicle_Pawn_Default
{
	GENERATED_BODY()

	TObjectPtr<UChaosWheeledVehicleMovementComponent> ChaosWheeledVehicleMovement;

public:
	float OriginalSteerAngle;
	EAxleType FrontAxleType;
	float FrontCorneringStiffness;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float ThrottleTorqueThreshold = 0.8f;

	UFUNCTION(BlueprintCallable)
	float GetMaxSteerAngle() const;

	UFUNCTION(BlueprintCallable)
	float GetCorneringStiffness(int32 WheelIndex) const;
	
	UFUNCTION(BlueprintCallable)
	void SetCorneringStiffness(int32 WheelIndex, float NewFrontCorneringStiffness);

protected:
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Torque")
	bool bTorqueFlag = false;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Torque")
	float fTorqueMultiplier = 1200.0f;
	
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Torque")
	float fTorqueGearMultiplier = 35.f;

public:
	AVehicle_Pawn_CS();
	
	virtual void Tick(float Delta);
};

Vehicle_Pawn_CS.cpp
AVehicle_Pawn_CS::AVehicle_Pawn_CS()
{
	ChaosWheeledVehicleMovement = CastChecked<UChaosWheeledVehicleMovementComponent>(GetVehicleMovement());
	
	if (ChaosWheeledVehicleMovement)
	{
		ChaosWheeledVehicleMovement->TransmissionSetup.FinalRatio = 1.45f;
		OriginalSteerAngle = GetMaxSteerAngle();

		FrontAxleType = FrontWheelLeft->GetAxleType();

		//ChaosWheeledVehicleMovement->SetWheelFrictionMultiplier(0, 0.6);

	}
}

void AVehicle_Pawn_CS::Tick(float Delta)
{
	Super::Tick(Delta);

	float ThrottleInput = ChaosWheeledVehicleMovement->GetThrottleInput();
	
	FrontCorneringStiffness = GetCorneringStiffness(0);

	float RearTorque = ChaosWheeledVehicleMovement->GetWheelState(2).DriveTorque;
	GEngine->AddOnScreenDebugMessage(-1, 0, FColor::Green, FString::Printf(TEXT("Rear Torque: %f"), RearTorque));
	GEngine->AddOnScreenDebugMessage(-1, 0, FColor::Green, FString::Printf(TEXT("Front CS: %f"), FrontCorneringStiffness));


	if (ThrottleInput >= ThrottleTorqueThreshold && bTorqueFlag)
	{
		ChaosWheeledVehicleMovement->SetWheelMaxSteerAngle(0, 65.f);
		ChaosWheeledVehicleMovement->SetWheelMaxSteerAngle(1, 65.f);

		SetCorneringStiffness(0, 1);
		SetCorneringStiffness(1, 1);
		SetCorneringStiffness(2, 1);
		SetCorneringStiffness(3, 1);
	}
	else 
	{
		ChaosWheeledVehicleMovement->SetWheelMaxSteerAngle(0, OriginalSteerAngle);
		ChaosWheeledVehicleMovement->SetWheelMaxSteerAngle(1, OriginalSteerAngle);

		SetCorneringStiffness(0, 280);
		SetCorneringStiffness(1, 280);
		SetCorneringStiffness(2, 340);
		SetCorneringStiffness(3, 340);
	}
}

float AVehicle_Pawn_CS::GetMaxSteerAngle() const
{
	if (ChaosWheeledVehicleMovement->WheelSetups.IsValidIndex(0))
	{
		UChaosVehicleWheel* Wheel = Cast<UChaosVehicleWheel>(ChaosWheeledVehicleMovement->WheelSetups[0].WheelClass.GetDefaultObject());
		if (Wheel)
		{
			if (UWheel_Front_Default* FrontWheelInstance = Cast<UWheel_Front_Default>(Wheel))
			{
				return FrontWheelInstance->GetMaxSteerAngle();
			}
		}
	}

	return 0.f;
}

float AVehicle_Pawn_CS::GetCorneringStiffness(int32 WheelIndex) const
{
	if (ChaosWheeledVehicleMovement->WheelSetups.IsValidIndex(WheelIndex))
	{
		UChaosVehicleWheel* Wheel = Cast<UChaosVehicleWheel>(ChaosWheeledVehicleMovement->WheelSetups[WheelIndex].WheelClass.GetDefaultObject());
		if (Wheel)
		{
			if (UWheel_Front_Default* FrontWheelInstance = Cast<UWheel_Front_Default>(Wheel))
			{
				return FrontWheelInstance->GetFrontCorneringStiffness();
			}
			else if (UWheel_Rear_Default* RearWheelInstance = Cast<UWheel_Rear_Default>(Wheel))
			{
				return RearWheelInstance->GetRearCorneringStiffness();
			}
		}
	}

	return 0.f;
}

// updating cornering stiffness doesn't seem to work during runtime
void AVehicle_Pawn_CS::SetCorneringStiffness(int32 WheelIndex, float NewCorneringStiffness)
{
	if (ChaosWheeledVehicleMovement->WheelSetups.IsValidIndex(WheelIndex))
	{
		UChaosVehicleWheel* Wheel = Cast<UChaosVehicleWheel>(ChaosWheeledVehicleMovement->WheelSetups[WheelIndex].WheelClass.GetDefaultObject());
		if (Wheel)
		{
			if (UWheel_Front_Default* FrontWheelInstance = Cast<UWheel_Front_Default>(Wheel))
			{
				FrontWheelInstance->SetFrontCorneringStiffness(NewCorneringStiffness);
			}
			else if (UWheel_Rear_Default* RearWheelInstance = Cast<UWheel_Rear_Default>(Wheel))
			{
				RearWheelInstance->SetRearCorneringStiffness(NewCorneringStiffness);
			}
		}
	}
}

Wheel_Front_Default.h
UCLASS()
class UWheel_Front_Default : public UChaosVehicleWheel
{
	GENERATED_BODY()

public:
	UFUNCTION()
	float GetMaxSteerAngle() const;

	UFUNCTION()
	float GetFrontCorneringStiffness() const;
	
	UFUNCTION()
	void SetFrontCorneringStiffness(float NewFrontCorneringStiffness);

	UWheel_Front_Default();
};

Wheel_Front_Default.cpp
UWheel_Front_Default::UWheel_Front_Default()
{
	AxleType = EAxleType::Front;
	bAffectedBySteering = true;
	
	WheelRadius = 36.5f;
	WheelWidth = 36.f;
	MaxSteerAngle = 55.f;
	CorneringStiffness = 280.f;
	FrictionForceMultiplier = 3.05f;
	SideSlipModifier = 1.f;
	SpringPreload = 20.f;
}

float UWheel_Front_Default::GetMaxSteerAngle() const
{
	return MaxSteerAngle;
}

float UWheel_Front_Default::GetFrontCorneringStiffness() const
{
	return CorneringStiffness;
}

// updating cornering stiffness doesn't seem to work during runtime
void UWheel_Front_Default::SetFrontCorneringStiffness(float NewFrontCorneringStiffness)
{
	CorneringStiffness = NewFrontCorneringStiffness;
}