Skeletal mesh overlap returns null bone

Steps to reproduce:

  1. Make a character with a skeletal mesh
  2. Make the skeletal mesh overlappable with pawn object type
  3. Tick Generate Overlap Events for the skeletal mesh
  4. Add logic to print bone name for on component overlap for the skeletal mesh
  5. Drag a copy of the character into the map
  6. Use the character in your game mode and play
  7. Overlap other character mesh
  8. bone name prints none

I understand that when mesh overlaps with the capsule the bone name is none. However , it also overlaps the skeletal mesh inside the capsule so there is no reason to not have a bone name.

Whats more disturbing is even the location and impact point return zero vector. As such how would you proceed on making a game where its important to know which bone of your character hit which bone of other character?

Hey Commander Shepard,

Can you show me your BP graph?

both overlapping characters are same class

Commander Shepard,

I will be taking a look into this issue early next week.

Thanks,
Jon N.

Command Shepard,

Component overlaps are determined using PhysX sweeps. PhysX doesn’t inherently know about Bone Names, but FBodyInstance (which is the user data we pass through) has the notion of Item Indices. On skeletal meshes, these map directly to bones.

So, what you should be doing is something like this:

Additionally, in order for ItemIndex / OtherBodyIndex to be properly set, you’ll need to have bMultiBodyOverlap enabled on the other component. So, in the example project you uploaded, you need it enabled for NewBlueprint’s SkeletalMesh component, but not for ThirdPersonCharacter.

Finally, this will cause each bone to generate overlap events as they are each considered their own physics body. This means that as you run through the skeletal mesh with the cube you’ll notice several events occurring (one for each bone) as opposed to the single event you currently see. If you need bone information, you’ll have to manually filter and ignore these events (something like checking to see if you’re already overlapping the given actor, and not performing the begin overlap if you are).

Thanks,
Jon N.

1 Like

alright , I’ll give it a trial

It worked, thanks for your time Machina and

I’m on 4.19 and this solution is not working for me. For some reason, the bones indexes seem to be scrambled. In particular, when I hit the head area with a projectile (static mesh), the overlap reports that “pinky_01_l” was overlapped.

I’m using the Third Person SK.

1 Like

Bumping this. Same thing is happening for me in 4.19. Any solutions yet?

Same here - suggested solution not working properly for 4.19.

I’ve done some counting and what I’ve found is that the OtherBodyIndex returned by the overlap event does not account for all bones, but rather only bones that have a PhysicsBody attached to them,
while the GetBoneName goes over the entire hierarchy and does not skip bones that do not have a PhysicsBody.

It just seems both functions count the index in a different way,
knowing this it is at least possible to guess up manually determine up front what OtherBodyIndex translates into which BoneName - this of course is a very (very!) temporary workaround and should be fixed.

but rather only bones that have a PhysicsBody attached to them

Yes, this was my conclusion as well when I had this problem.

I tried looking through the source to determine how this was being used and unfortunately did not have good results – I think the variable was an int32 called BodyIndex or ItemIndex and for me was very hard to understand its use.

Does this problem persist in 4.18 or 4.20? Perhaps a bug report should be submitted.

Yes it does persist in 4.18 and 4.19
Have not checked 4.20 yet

It seams that the bone name index has the same order of GetBoneNames() method, so I write a function to find all bone name with physic asserts, and use this array, you can get the currect bone name by OtherBodyIndex in ComponentOverlapBegin event.

  1. Create a TArray PhysicBoneNames in my character(Or any actor owns the SkeletalMeshComponent).
  2. Add a function GetBoneName(float BodyIndex) to return bone name in PhysicBoneNames array .
  3. Call this method on your OnComponentOverlapBegin Event.

In Header file:

TArray PhysicBoneNames;

In Begin Play:

    USkeletalMeshComponent* SkelMeshComp = Cast<USkeletalMeshComponent>(GetMesh());
    	if (SkelMeshComp) {
    		TArray<FName> BoneNames;
    		SkelMeshComp->GetBoneNames(BoneNames);
    		for (int i = 0; i < BoneNames.Num(); i++) {
    			FBodyInstance* BodyInst = SkelMeshComp->GetBodyInstance(BoneNames[i]);
    			if (BodyInst) {
    				UPhysicalMaterial* PM = BodyInst->GetSimplePhysicalMaterial();
    				EPhysicalSurface SurfaceType = UPhysicalMaterial::DetermineSurfaceType(PM);
    				if (SurfaceType_Default != SurfaceType) {
    					PhysicBoneNames.Add(BoneNames[i]);
    				}
    			}
    		}
    	}
}

Create function in your pawn:

  FName AArCharacter::GetBoneName(float BoneIndex)
    {
    	if (BoneIndex >= PhysicBoneNames.Num()) {
    		UE_LOG(LogTemp, Error, TEXT("Bone index out of bound."));
    		return "None";
    	}
    	else {
    		return PhysicBoneNames[BoneIndex];
    	}
    }

In your overlap event:

    AArCharacter* OtherCharacter = Cast<AArCharacter>(OtherActor);
	if (OtherCharacter) {
		if (OtherComp) {
			USkeletalMeshComponent* SkelMesh = Cast<USkeletalMeshComponent>(OtherComp);
			if (SkelMesh) {
				FName BoneName = OtherCharacter->GetBoneName(OtherBodyIndex);
			}
		}
	}

4.20 wrong body indexes confirmed)

Set Generate Overlap events to true in SkeletalMeshActor or component that owns physics asset

1 Like
  1. Set Generate Overlap events to true all components of physics asset

2 set “Multi Body Overlap” option to true in the Collision settings of core character
3… cast the other component to SkeletalmeshComponent

  1. get index value from Overlap event and insert to “Find constrain bone name” along with mesh from (3…) to bet the bone name of primitive Component.

Two things that took me a while to figure out:

  1. OtherBodyIndex will be -1 unless the collider that moves into the skeletal mesh is moving. A piece of the skeletal mesh can’t hit the collider and cause this to happen. For example, you have a cube and the skeletal mesh moves into it - doesn’t work. Move the cube into the skeletal mesh - works.
  2. OtherBodyIndex is the index into SkeletalMesh->Bodies and the body can be used to find the bone index, bone name, location, etc.
1 Like