Hi.
I try to simulate chains with instanced mesh components.
For some reasons, the hit event only trigger when the other actor is from the character class. I tried with static mesh, skeletal mesh, and tried to put it in an actor and add collision sphere to it, but still no event for hits.
I enabled “simulate physics”, “enable gravity” "simulation generates hit events and set the collision presets to block all and even switched the physics type to simulate for skeletal meshes, but still no event occur. All have simple and complex collision. It collide with each other and my chain have effects on the actors/objects.
This is in unreal engine 4.27
Here how I initialized my instanced mesh components in my c++ files:
chain.h:
UPROPERTY(VisibleAnywhere)
UInstancedStaticMeshComponent * Instancedchainlink_side;
UPROPERTY(VisibleAnywhere)
UInstancedStaticMeshComponent * Instancedchainlink_front;
...
UFUNCTION()
void OnComponentHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
chain.cpp
AChain::Achain()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
Instancedchainlink_side = CreateDefaultSubobject<UInstancedStaticMeshComponent>(TEXT("Instancedchainlink_side2893_A"));
Instancedchainlink_side->SetMobility(EComponentMobility::Movable);
Instancedchainlink_side->SetupAttachment(RootComponent);
Instancedchainlink_side->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
Instancedchainlink_side->SetGenerateOverlapEvents(true);
Instancedchainlink_side->bMultiBodyOverlap = true;
Instancedchainlink_side->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
Instancedchainlink_side->SetEnableGravity(true);
Instancedchainlink_side->SetSimulatePhysics(true);
Instancedchainlink_side->OnComponentHit.AddDynamic(this, &AVerletChain2D::OnComponentHit);
Instancedchainlink_front = CreateDefaultSubobject<UInstancedStaticMeshComponent>(TEXT("Instancedchainlink_front2893_A"));
Instancedchainlink_front->SetMobility(EComponentMobility::Movable);
Instancedchainlink_front->SetupAttachment(RootComponent);
Instancedchainlink_front->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
Instancedchainlink_front->SetGenerateOverlapEvents(true);
Instancedchainlink_front->bMultiBodyOverlap = true;
Instancedchainlink_front->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
Instancedchainlink_front->SetEnableGravity(true);
Instancedchainlink_front->SetSimulatePhysics(true);
Instancedchainlink_front->OnComponentHit.AddDynamic(this, &AVerletChain2D::OnComponentHit);
}
void AChain::BeginPlay()
{
//this s in a for loop
if (rawtransform[i].chainlinkstate)
{
Instancedchainlink_front->UpdateInstanceTransform(cainfrontcounter, reftransform, false, false, false);
cainfrontcounter++;
}
else
{
Instancedchainlink_side->UpdateInstanceTransform(cainsidecounter, reftransform, false, false, false);
cainsidecounter++;
}
...
Instancedchainlink_side->AddInstances(sidechaintransforms, false);
Instancedchainlink_front->AddInstances(frontchaintransforms, false);
}
void AChain::Tick(float DeltaTime)
{
//updating the position in a for loop
if (rawtransform[i].chainlinkstate)
{
Instancedchainlink_front->UpdateInstanceTransform(cainfrontcounter, reftransform, false, false, false);
cainfrontcounter++;
}
else
{
Instancedchainlink_side->UpdateInstanceTransform(cainsidecounter, reftransform, false, false, false);
cainsidecounter++;
}
}
void AChain::OnComponentHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
UE_LOG(LogTemp, Warning, TEXT("Hit event name: > %s, index > %d, ithercomponent: %s"), *HitComp->GetName(), Hit.ElementIndex, *OtherComp->GetName());
FString hitname = *HitComp->GetName();
int hitindex = Hit.Item;
float dist = Hit.Distance;
float pdepth = Hit.PenetrationDepth;
float time = Hit.Time;
if (hitindex != -1)
{
FVector hitnormal = Hit.Normal;
if (hitname == Instancedchainlink_sideName)
{
Verletchain->backslash(sidechainlinkparticlelist[hitindex], hitnormal, dist);
}
else if (hitname == Instancedchainlink_frontName)
{
Verletchain->backslash(frontchainlinkparticlelist[hitindex], hitnormal, dist);
}
}
FVector impactnormal= Hit.ImpactNormal;
//UE_LOG(LogTemp, Warning, TEXT("name: > %s, index > %d"), *HitComp->GetName(), Hit.Item);
FString otherhitcomp = OtherComp->GetName();
//UE_LOG(LogTemp, Warning, TEXT("dist: %f ,pdepth: %f, time: %f, %s"), dist, pdepth, time, otherhitcomp);
}
I hope I didn’t forget anything important.