Announcement

Collapse
No announcement yet.

Proper way to move an Actor / Collision Not Working

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Proper way to move an Actor / Collision Not Working

    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!

    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)"));
    }
    Pocket Sized Animations

    #2
    AM assuming you want to catch the event when the projectile hits the player?
    To detect a blocking hit you need to override AActor::OnActorHit also i asked a qustion about collision a while back you can check that out here
    Hope it helps.

    Comment


      #3
      The issue here is that the CollisionComponent is not the RootComponent. When you use SetActorLocation(...), that sweeps the RootComponent, and teleports attached components, so they don't get hit events (only overlaps). You need to set the collision component as the root instead.
      Last edited by zeroexception; 09-08-2015, 01:20 PM.
      Zak Middleton
      Sr. Engine Programmer, Epic Games

      Comment


        #4
        Zak,

        I ran across your post in this thread when I was having problems with the same issue. I tried to fix my basic debugging project but it didn't work. At some point I decided to start completely over after I suspected my project was corrupted (most likely from a series of forced blueprint deletes or renaming).

        I created a new project armed with the information from your post and the collision worked. I'm responding here because I thought you might be interested in looking at the bad project to see if there was a different issue. Here is my question and answer to myself. I attached the original debugging project and the solution project.

        UE4 Cube Mesh Not Colliding using SetRelativeLoc

        Comment

        Working...
        X