Building Actor from multiple static meshes welded together with all having collisions

What I am trying to do is build a vessel out of parts like you do in Kerbal Space Program. This would require me to have multiple static meshes welded together and have physics simulated. All the meshes have to have collisions enabled.

Here’s my current code:


UStaticMeshComponent* AShip::AddPart(FString name, FVector location, FRotator rotation, USceneComponent* parent)
{
	UStaticMesh* mesh = LoadObject<UStaticMesh>(NULL, *name);
	UStaticMeshComponent* component = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass(), this);
	component->SetStaticMesh(mesh);
	if(parent)
	{
		component->AttachTo(parent);

		UPhysicsConstraintComponent* weld = ConstructObject<UPhysicsConstraintComponent>(UPhysicsConstraintComponent::StaticClass(), this);
		weld->ConstraintActor1 = this;
		weld->ConstraintActor2 = this;
		weld->ComponentName1.ComponentName = component->GetFName();
		weld->ComponentName2.ComponentName = parent->GetFName();

		weld->SetAngularSwing1Limit(EAngularConstraintMotion::ACM_Locked, 0.f);
		weld->SetAngularSwing2Limit(EAngularConstraintMotion::ACM_Locked, 0.f);
		weld->SetAngularTwistLimit (EAngularConstraintMotion::ACM_Locked, 0.f);
		weld->SetDisableCollision(true);

		weld->AttachTo(parent);
		weld->RegisterComponent();

		Joints.Add(weld);
	}
	component->SetRelativeLocationAndRotation(location, rotation);
	component->SetSimulatePhysics(true);
	component->RegisterComponent();

	Parts.Add(component);

	return component;
}

Current problem is that weld doesn’t seem to work at all. Meshes aren’t connected to each other at all. What I have tried:

  • Using auto weld (only parent had collisions enabled)
  • Attaching weld to component, attaching weld to parent, attaching weld to their common ancestor (weld didn’t do anything)
  • Using physics constrain actor (weld didn’t do anything)
  • With and without set disable collisions (weld didn’t do anything)

Am I completely on the wrong tracks about implementing this? How I could make this work?

Edit: If I try to move the ship using radial force actors, it doesn’t move at all. Using AddForce on one of the meshes results in weld having no effect.

Apparently the bodies were of type WorldStatic and that’s why radial force actor didn’t have any effect on them. By adding component->SetMobility(EComponentMobility::Movable), I was able to make them of type WorldDynamic. However, I think they should be of type PhysicsBody? How do I make them PhysicsBodies?

This is along the lines of what you want:


	GetCapsuleComponent()->SetCollisionObjectType(ECollisionChannel::ECC_PhysicsBody);

Yes, I added this and it made the object a physics body.


component->SetCollisionObjectType(ECollisionChannel::ECC_PhysicsBody);

However, the weld still doesn’t work. I was able to make the physics constrain show up correctly in the editor by using SetConstrainedComponents. However, when I start the simulation, the constrain disappears (it no longer has boxes around the two parts).

I found the problem. ComponentName for physics constraint component is not the name of the component but instead name of a field in the constrained actor. My components don’t have a field in the actor and they are instead stored in an array. SetConstrainedComponents can be used to set the components correctly. However, when I start the simulation, the objects get recreated and they are no longer set correctly. My current solution now is to set the constrained components again using SetConstrainedComponents on BeginPlay.

So you got welds to work properly? Do the pieces maintain their individual masses/physical material properties? I’d love to see a video of it if you’ve got one on youtube.

I’m trying to do something similar and haven’t been having much success. I’ve tried making one mesh with physics and the moving all of my meshes around that, but this causes a lot of jitter and the collision is basically nonexistant. Have you have any success with the welding?

Is there Any Progress? I am also struggling with that. I honestly expected welding together the physics-simulting parts of an actor to be the default behaviour. However, not only is it not, it does also not work at all. I had one exception though: Using


auto rule = FAttachmentTransformRules(EAttachmentRule::KeepRelative, EAttachmentRule::KeepRelative, EAttachmentRule::KeepWorld, true);
auto success = ShieldMesh->AttachToComponent(GetAttachParent(), rule)

this makes the component stick. I however have to do this everytime on BeginPlay, and since I alter the component structure, it doesn’t work if you play in editor more than once.