[Chaos vehicle] Trying to subclass simulation object

It seems like the vehicles are now designed to have all of their physics take place in the physics thread by a simulation object created by the movement component. So, to add functionality I want to subclass this sim object but I’m having problems…

The simulation object in UChaosVehicleMovementComponent:

TUniquePtr<UChaosVehicleSimulation> VehicleSimulationPT;	/* simulation code running on the physics thread async callback */

which is created in UChaosWheeledVehicleMovementComponent.h :

virtual TUniquePtr<Chaos::FSimpleWheeledVehicle> CreatePhysicsVehicle() override
{
	// Make the Vehicle Simulation class that will be updated from the physics thread async callback
	VehicleSimulationPT = MakeUnique<UChaosWheeledVehicleSimulation>(Wheels);

	return UChaosVehicleMovementComponent::CreatePhysicsVehicle();
}

and of course UChaosWheeledVehicleSimulation is a subclass of UChaosVehicleSimulation:

class UChaosWheeledVehicleSimulation : public UChaosVehicleSimulation
{
public:

UChaosWheeledVehicleSimulation(TArray<class UChaosVehicleWheel*>& WheelsIn)
	: Wheels(WheelsIn), bOverlapHit(false)
{
	QueryBox.Init();
}

so… my attempt at subclassing it looks like this:

class UPL_WheeledVehicleSimulation : public UChaosWheeledVehicleSimulation
{
public:

UPL_WheeledVehicleSimulation(TArray<class UChaosVehicleWheel*>& WheelsIn)
	: UChaosWheeledVehicleSimulation(WheelsIn)
{}

this much compiles fine since it satisfies the default constructor for the super, so we spawn it here:

TUniquePtr<Chaos::FSimpleWheeledVehicle> UPL_WheeledVehicleMovementComp::CreatePhysicsVehicle()
{
	// Make the Vehicle Simulation class that will be updated from the physics thread async callback
	VehicleSimulationPT =  MakeUnique<UPL_WheeledVehicleSimulation>(Wheels);
	return UChaosVehicleMovementComponent::CreatePhysicsVehicle();
}

but this creates link errors: (just showing a few of many of the member functions unresolved)

1>PL_WheeledVehicleMovementComp.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl UChaosVehicleSimulation::TickVehicle(class UWorld *,float,struct FChaosVehicleDefaultAsyncInput const &,struct FChaosVehicleAsyncOutput &,class Chaos::FRigidBodyHandle_Internal *)" (?TickVehicle@UChaosVehicleSimulation@@UEAAXPEAVUWorld@@MAEBUFChaosVehicleDefaultAsyncInput@@AEAUFChaosVehicleAsyncOutput@@PEAVFRigidBodyHandle_Internal@Chaos@@@Z)
1>PL_WheeledVehicleMovementComp.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl UChaosVehicleSimulation::UpdateSimulation(float,struct FChaosVehicleDefaultAsyncInput const &,class Chaos::FRigidBodyHandle_Internal *)" (?UpdateSimulation@UChaosVehicleSimulation@@UEAAXMAEBUFChaosVehicleDefaultAsyncInput@@PEAVFRigidBodyHandle_Internal@Chaos@@@Z)
1>PL_WheeledVehicleMovementComp.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl UChaosVehicleSimulation::FillOutputState(struct FChaosVehicleAsyncOutput &)" (?FillOutputState@UChaosVehicleSimulation@@UEAAXAEAUFChaosVehicleAsyncOutput@@@Z)

if I comment out

VehicleSimulationPT = MakeUnique<UPL_WheeledVehicleSimulation>(Wheels);

then it compiles but obviously won’t work…

What am I missing?

2 Likes

I believe that although you can subclass the WheeledVehicleSimulation class, the class itself is not exposed for use by other modules (e.g in this case your project). To expose it you need to make a small change to the engine code and add the required macro in front of the simulation class " CHAOSVEHICLES_API". See how UChaosWheeledVehicleMovementComponent uses it for example

1 Like

Makes sense. I’m hoping they fix things like that before release… I hate having to change engine code, especially for something like this

I have the same Errors!

Is there another way to solve it?

Another way to approach this is … (The Chaos Vehicle runtime portion of the API is not that large) You can copy the contents of the plugin, then build your own plugin for the engine.
This way you are only customizing that plugin. You may need to rename the API namespace or classes like the MovementComponent so they don’t conflict.

This is what I’ve done previously, and it works.

1 Like

Does it have to be a plugin specifically? I’m trying to do the same but I’m writing the code inside my project’s source folder and just try to ‘housekeep’ where needed with .Build dependency modules etc . and so far it’s going fine.
The reason I’m asking is because I was unsure of this to begin with and I haven’t fully tested it yet since I’m now starting to write my own vehicle physics to use with it.