Download

Overlapping Physics Bodiesand OtherBodyIndex

Hey,
In short, my problem is that of the two characters I spawn (same blue print) one character gets correct OtherBodyIndex and other one only -1?
So I have a custom character class, for a local PvsP fighting game, which I made a blueprint from. Then wrote a custom ActorComponent for hit detection.
The GameMode spawns 2 of these Character Blueprints on start then some logic set one to Red player and the other to Blue player for collision and such. They get a collision profile that was added to the DefaultEngine.ini. Anyway since it’s one character they run the exact same logic (with the difference of being filter and set to red and blue).

so by being spawned this BeginPlay set red/blue:


void AMTCPlayerState::BeginPlay()
{  
    //Initialize State with Red or Blue based upon character
    AMTCGameModeBase* GM = Cast<AMTCGameModeBase>(GetWorld()->GetAuthGameMode());
    //Find the characters to Init them
    TArray<AActor*> outCharacters;
    //TODO: Stop this search being done twice without making it static
    UGameplayStatics::GetAllActorsOfClass(GetWorld(), AMTCCharacter::StaticClass(), outCharacters);
    for (int i = 0; i < outCharacters.Num(); i++) {
        AMTCCharacter* ch = Cast<AMTCCharacter>(outCharacters*);
        //Error Check
        if (!ch->PlayerState) {
            UE_LOG(LogTemp, Error, TEXT("Characters dont have an associated PlayerState!!"));
            return;
        }
        //If the correct player
        if (ch->PlayerState->PlayerId == PlayerId) {
#ifdef PlayerStateHasRefToCharacter
            character = ch; //Set Ref from State back to Player
            UE_LOG(LogTemp, Warning, TEXT("Player: %c"), (ACharacter*)ch == GM->redPlayer->GetCharacter() ? 'r' : 'b');
#endif 
            if ((ACharacter*)ch == GM->redPlayer->GetCharacter()) //Red
                Init(true, Cast<AMTCCharacter>(GM->bluePlayer->GetCharacter())); //Init Red
            else //Blue
                Init(false, Cast<AMTCCharacter>(GM->redPlayer->GetCharacter())); //Init Blue
            ch->Init(); //Init Character
            break;
        } 
    } 
}
void AMTCPlayerState::Init(bool isRedPlayer, AMTCCharacter* opponent)
{
    if (isInitalized)
        return;
    isInitalized = true;
    //Setup
    this->opponent = opponent;
    this->isRedPlayer = isRedPlayer;
    this->SetActorLabel(this->GetActorLabel() + (isRedPlayer ? AMTCGameModeVersus::RED_PLAYER_ACTOR_SUFFIX : AMTCGameModeVersus::BLUE_PLAYER_ACTOR_SUFFIX));
#ifdef PlayerStateHasRefToCharacter
    //Set collision preset
    UImpactPhysics* impactPhysics = Cast<UImpactPhysics>(character->GetComponentByClass(UImpactPhysics::StaticClass()));
    impactPhysics->Init(isRedPlayer);
#endif 

}


then this line:


UImpactPhysics* impactPhysics = Cast<UImpactPhysics>(character->GetComponentByClass(UImpactPhysics::StaticClass()));
    impactPhysics->Init(isRedPlayer);

runs ImpactPhysics’ init (which is the hit detection component):


void UImpactPhysics::Init(bool isRed)
{
    //Get SkeletalMesh and subscribe to OnBeginOverlap
    USkeletalMeshComponent* mesh = Cast<USkeletalMeshComponent>(GetOwner()->GetComponentByClass(USkeletalMeshComponent::StaticClass()));
    if (mesh)
    {
        mesh->OnComponentBeginOverlap.AddDynamic(this, &UImpactPhysics::OnOverlapBegin);

        if (isRed)
        {
            UE_LOG(LogTemp, Warning, TEXT("Character Red"));
            mesh->BodyInstance.SetCollisionProfileName(TEXT("Red"));
        }
        else
        {
            UE_LOG(LogTemp, Warning, TEXT("Character Blue"));
            mesh->BodyInstance.SetCollisionProfileName(TEXT("Blue"));
        }
        mesh->SetGenerateOverlapEvents(true);
        mesh->bMultiBodyOverlap = true;
    }
}

the collision profiles are set to red ignore red and overlap blue and visa versa. This all seems to work fine.
as you can see OnOverlapBegin subscribed to OnComponentBeginOverlap, and the OnOverlapBegin is:


void UImpactPhysics::OnOverlapBegin(UPrimitiveComponent * HitComp, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
    AMTCCharacter* opponent = Cast<AMTCCharacter>(OtherActor);
    UImpactPhysics* opponentImpact = Cast<UImpactPhysics>(opponent->GetComponentByClass(UImpactPhysics::StaticClass()));
    USkeletalMeshComponent* opponentMesh = Cast<USkeletalMeshComponent>(OtherComp);
    if (opponentMesh)
    {
        AMTCCharacter* character = Cast<AMTCCharacter>(GetOwner());

        if (OtherBodyIndex > -1)
        {
            FBodyInstance* bI = opponentMesh->Bodies[OtherBodyIndex];
            UE_LOG(LogTemp, Warning, TEXT("Attacker: %s | OtherBodyIndex: %d"), *character->GetName(), OtherBodyIndex);
        }
        else
            UE_LOG(LogTemp, Warning, TEXT("Character: %s | OtherBodyIndex: %d"), *character->GetName(), OtherBodyIndex);

    }
}

and the log result is:

ok so my custom profile red was ignoring red and overlapping blue and blue was ignoring blue and overlapping red. Looks like it should be Blue overlaps Blue and Red and same for Red profile…
Strange it thought I should set them to ignore themself?