Reputation: 35
I have problem with collisions. I want to make simple projectile. I have made an Actor which has Root, Sphere and mesh components. When this actor hits target object nothing happens. I have tried many ways, also with
void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
functions, but without any results..
Here is constructor of my custom projectile:
AProjectile_2::AProjectile_2()
{
// 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;
Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
RootComponent = Root;
mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("staticMesh"));
static ConstructorHelpers::FObjectFinder<UStaticMesh>SphereMeshAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
if (SphereMeshAsset.Succeeded())
{
mesh->SetStaticMesh(SphereMeshAsset.Object);
mesh->SetWorldScale3D(FVector(0.2f));
}
mesh->SetEnableGravity(true);
mesh->SetSimulatePhysics(true);
mesh->SetupAttachment(Root);
Sphere = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
Sphere->InitSphereRadius(5.f);
Sphere->SetupAttachment(Root);
Sphere->SetCollisionProfileName(TEXT("Target"));
Sphere->OnComponentHit.AddDynamic(this, &AProjectile_2::OnHit);
Sphere->SetupAttachment(RootComponent);
InitialLifeSpan = 5.f;
}
Here is a detect function
void AProjectile_2::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
if ((OtherActor != NULL) && (OtherActor != this) && (OtherComp != NULL))
{
if (OtherActor && (OtherActor != this) && OtherComp && OtherActor->GetClass()->IsChildOf(ADestroypack::StaticClass()))
{
destroypack = (ADestroypack*)OtherActor;
destroypack->decreasehp(50);
destroypack->check_hp();
destroypack->showhp();
}
}
}
Here my mesh is getting force to move
void AProjectile_2::Initvel(FVector Velocity)
{
mesh->AddForce(Velocity * 300);
}
And here is my character function to shoot with RMB button
void AHero::Attack_right()
{
FVector Location = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation();
FRotator Rotation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorRotation();
GetActorEyesViewPoint(Location, Rotation);
projectiles = (AProjectile_2*) GetWorld()->SpawnActor(AProjectile_2::StaticClass(), &Location, &Rotation);
FVector LaunchDir;
LaunchDir = GetActorForwardVector() * 5000.f;
projectiles->Initvel(LaunchDir);
}
If someone could say what am i doing wrong, or what is missing in my project i will be grateful.
OK! I have figure it out! :D I made a mistake adding Gravity and Physics to mesh and Sphere. I've deleted it from mesh, and it works now :)
AProjectile_2::AProjectile_2()
{
// 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;
//Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
//RootComponent = Root;
Sphere = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
Sphere->SetSimulatePhysics(true);
Sphere->SetEnableGravity(true);
Sphere->SetNotifyRigidBodyCollision(true);
Sphere->InitSphereRadius(40.f);
Sphere->BodyInstance.SetCollisionProfileName("BlockAllDynamic");
Sphere->SetCollisionProfileName(TEXT("Target"));
Sphere->OnComponentHit.AddDynamic(this, &AProjectile_2::OnHit);
RootComponent = Sphere;
mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("staticMesh"));
static ConstructorHelpers::FObjectFinder<UStaticMesh>SphereMeshAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
if (SphereMeshAsset.Succeeded())
{
mesh->SetStaticMesh(SphereMeshAsset.Object);
mesh->AddRelativeLocation(FVector(0.f, 0.f, 0.f));
mesh->SetWorldScale3D(FVector(0.2f));
}
/*mesh->SetEnableGravity(true);
mesh->SetSimulatePhysics(true);
mesh->SetGenerateOverlapEvents(true);*/
mesh->SetupAttachment(RootComponent);
InitialLifeSpan = 5.f;
}
Upvotes: 2
Views: 18704
Reputation: 8229
You should add the dynamic delegate in the BeginPlay
function. The rest of the code in relation to the setup of the Sphere Component can stay in the constructor. The reason for this is that in Unreal, if you made the blueprint first, parent it to your projectile cpp class but then later added the OnComponentHit
functionality declared in the constructor, it won't work. It will only work in the constructor if the blueprint was made with the cpp class, including the OnComponentHit
delegate, from the very beginning. This is a very common issue that goes unnoticed often times.
Make sure to add the BeginPlay
function to your header file if you haven't done so,
virtual void BeginPlay() override;
Then in your cpp file, declare the function and move your call to AddDynamic
from the constructor to BeginPlay
,
void AProjectile_2::BeginPlay()
{
Super::BeginPlay();
Sphere->OnComponentHit.AddDynamic(this, &AProjectile_2::OnHit);
}
Upvotes: 5
Reputation: 806
If you are using OnOverlapBegin, your components should be using Overlap for collision response against other components, rather than Block.
Upvotes: 0