So I created my own custom “physics” based Bullet which is comprised of a collision component with a mesh attached to it basically. However, I can’t get Collision (events or actor blocking) to work.
I’m attempting to design a bullet that I have full control over how it is handled by creating all the custom movement and “physics” simulation inside the Bullet class its self, without using a Movement Component since I didn’t like it, nor the ProjectileMovementComponent really. However. Getting the bullet to actually move has been a big hassle for some reason. I couldn’t figure out how you are suppose to properly move an actor with collision detection. I’ve been using SetActorLocation() per tick, with bsweep = true which alone took a while to do, however the bullet just flies through everything regardless of its Collision profile, I’ve tried OverlapAll, BlockAll, Custom Ones, etc. The projectile will not stop at objects nor will the overlap/hit events call when it goes through an object. BUT if the object goes through IT, it will.
Example: Bullet is fired (very slow movement) and me, the player with my pawn, walk into its path and let it hit me (no detection). But, if I fire the bullet, and run into it (meaning I’m moving this time) it fires off the hit/overlap events.
So, anytime I fire my bullet things that don’t move into it (idling pawn, world, staticmeshes) don’t call any collision. I’m taking it that I’m basically just setting the location of the actor without any collision checks using SetActorLocation() but I can’t seem to find the old UDK/uScript versions of MoveTo/MoveToward() that attempted a move rather than just set the location. Am I just missing something major?
Code!
#include "ROT.h"
#include "ROTPlayerSoldier.h"
#include "ROTProjectileMovementComponent.h"
#include "ROTBullet.h"
DEFINE_LOG_CATEGORY_STATIC(BulletLog, All, All)
AROTBullet::AROTBullet(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
PrimaryActorTick.bCanEverTick = true; //Enables ticking
SceneComponent = PCIP.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneComp"));
RootComponent = SceneComponent;
OnActorBeginOverlap.AddDynamic(this, &AROTBullet::ReceiveActorOverlap);
Mesh = PCIP.CreateOptionalDefaultSubobject<UStaticMeshComponent>(this, TEXT("MeshComp"));
Mesh->AttachParent = SceneComponent;
Mesh->SetCollisionProfileName("NoCollision");
Mesh->SetRelativeRotation(FRotator(0, -90, 0));
//Components
CollisionComponent = PCIP.CreateOptionalDefaultSubobject<UCapsuleComponent>(this, TEXT("CollisionComp"));
CollisionComponent->AttachParent = SceneComponent;
CollisionComponent->SetCapsuleSize(1.0f, 2.0f, true);
CollisionComponent->SetRelativeRotation(FRotator(-90,0,0));
CollisionComponent->BodyInstance.SetCollisionProfileName("OverlapAll");
CollisionComponent->bTraceComplexOnMove = false;
CollisionComponent->bGenerateOverlapEvents = true;
CollisionComponent->OnComponentBeginOverlap.AddDynamic(this, &AROTBullet::ReceiveOverlap);
ArrowComp = PCIP.CreateOptionalDefaultSubobject<UArrowComponent>(this, TEXT("ArrowComp"));
ArrowComp->AttachParent = SceneComponent;
ArrowComp->RelativeLocation = FVector(0,0,0.75);
ArrowComp->ArrowSize = 0.075;
}
void AROTBullet::BeginPlay()
{
UE_LOG(BulletLog, All, TEXT("===AROTBullet::BeginPlay()==="));
}
void AROTBullet::InitSimulation(FVector DirectionInput,AROTPlayerSoldier* InstigatorInput)
{
if (InstigatorInput)
Instigator = InstigatorInput;
Direction = DirectionInput; //Sets the direction of our projectile
DrawDebugLine(GetWorld(), GetActorLocation(), GetActorLocation() + (Direction * 4096), FColor::Blue, true);
bSimulating = true;
}
void AROTBullet::Tick(float DeltaSeconds)
{
DrawDebugSphere(GetWorld(), GetActorLocation(), 4, 8, FColor::Red, false); //Draws a sphere so we can see our bullet travel
//Draws our forward rotation so we can see where we're heading
FVector ForwardDir;
ForwardDir = FRotationMatrix(GetActorRotation()).GetUnitAxis(EAxis::X);
DrawDebugLine(GetWorld(), GetActorLocation(), GetActorLocation() + (ForwardDir * 256), FColor::Red, true,3.5);
//Only simulate when ready
if (bSimulating)
ProcessMove();
}
void AROTBullet::ProcessMove()
{
if (Velocity <= 0)
{
UE_LOG(BulletLog, Warning, TEXT("===AROTBullet::ProcessMove()==="));
UE_LOG(BulletLog, Warning, TEXT("Velocity for bullet is 0!!!!!"));
}
FVector FinalDir = GetActorLocation() + (Direction * Velocity);
SetActorLocation(FinalDir, true);
}
void AROTBullet::ReceiveActorOverlap(AActor* OtherActor)
{
GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Blue, TEXT("ACTOR OVERLAP!!!!"));
}
void AROTBullet::ReceiveOverlap(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Blue, TEXT("Component OVERLAP!!!!"));
}
//A HIT is any object that STOPS the bullet (probably won't be many)
void AROTBullet::ReceiveHit(class UPrimitiveComponent* MyComp, class AActor* Other, class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit)
{
GEngine->AddOnScreenDebugMessage(-1, 9.5f, FColor::Green, TEXT("HIT!"));
bSimulating = false;
}
void AROTBullet::ReceiveActorBeginOverlap(class AActor* OtherActor)
{
GEngine->AddOnScreenDebugMessage(-1, 9.5, FColor::Green, TEXT("ReceiveActorBeginOverlap (UE Function)"));
}