x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How do I make my collision loop?

I currently have this setup (.cpp):

 AFire::AFire(const class FObjectInitializer& ObjectInitializer)
 {
     ProxSphere = ObjectInitializer.CreateDefaultSubobject<USphereComponent>(this, TEXT("Sphere Component"));
     ProxSphere->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepWorldTransform);
     ProxSphere->SetSphereRadius(32.f);
     ProxSphere->OnComponentBeginOverlap.AddDynamic(this, &AFire::Prox);
 
 
      // 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;
     PrimaryActorTick.bStartWithTickEnabled = true;
 
 }
 
 void AFire::Prox_Implementation(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
 {
     if (Cast<AMyCharacter>(OtherActor) == nullptr)
     {
         return;
     }
     if (Cast<AMyCharacter>(OtherActor))
     {
         AMyCharacter* Character = Cast<AMyCharacter>(OtherActor);
         Character->Damage(Character->GetHp(), 6.f);
     }
 }


.h:

        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Collision")
             USphereComponent* ProxSphere;
         UFUNCTION(BlueprintNativeEvent, Category = "Collision")
             void Prox(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult);
     

This is successful in damaging my character every time I walk onto it, but it doesn't loop so if I stand on top of it I don't continue to take damage. I can't move this to the Tick class.

I tried adding a while loop, but it made my program crash:

 void AFire::Prox_Implementation(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
 {
     if (Cast<AMyCharacter>(OtherActor) == nullptr)
     {
         return;
     }
     if (Cast<AMyCharacter>(OtherActor))
     {
         while (Cast <AMyCharacter>(OtherActor))
         {
         AMyCharacter* Character = Cast<AMyCharacter>(OtherActor);
         Character->Damage(Character->GetHp(), 6.f);
 
         }
     }
     
 
 }

Is there any way to make my collision tick so it can check every second if my character is colliding with it?

Product Version: UE 4.12
Tags:
more ▼

asked Jul 19 '16 at 12:20 AM in C++ Programming

avatar image

Snowl0l
49 11 13 19

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

What you can do is to use a timer to try to inflict damage to a set of characters in the fire area every time it ticks. Every time a character enters the area (via OnComponentBeginOveralp) you add the character to this set, and every time a character exits the area you remove it from the set.

The additional codes would look something like this (please note that this code below is written from the top of my head and have not been tested, it's just to give you a rough idea of how it is done) :

in Fire.h

 ...
 
 /** Handle to the damage timer. */
 UPROPERTY(Transient)
 FTimerHandle DamageTimerHandle;
 
 UPROPERTY(Transient)
 TArray<TWeakObjectPtr<AMyCharacter>> CharactersInTheArea;
 
 /** How often the damage is applied to characters in the area. */
 UPROPERTY(EditAnywhere, Category="Damage")
 float DamageRate = 0.5;
 
 UFUNCTION()
 void ApplyDamageToCharacters();
 ...

in AFire.cpp

 AFire::AFire( const FObjectInitializer& ObjectInitializer)
 {
     ...
     ProxSphere->OnComponentBeginOverlap.AddDynamic(this, &AFire::HandleBeginOverlap);    
     ProxSphere->OnComponentEndOverlap.AddDynamic(this, &AFire::HandleEndOverlap);
 }
 
 void AFire::BeginPlay()
 {
     ...
     GetWorld()->GetTimerManager().SetTimer(DamageTimerHandle, this, &AFire::ApplyDamageToCharacters, DamageRate, false);    
     ...
 }
 
 void AFire::HandleBeginOverlap( AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult )
 {
     if ( AMyCharacter* Character = Cast<AMyCharacter>(OtherActor) )
     {
         CharactersInArea.AddUnique( Character );
     }
 }
 
 void AFire::HandleEndOverlap( AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex )
 {
     if ( AMyCharacter* Character = Cast<AMyCharacter>(OtherActor) )
     {
         CharactersInArea.Remove( Character );
     }    
 }
 
 
 void AFire::ApplyDamageToCharactersInTheArea()
 {
     for ( TWeakObjectPtr<AMyCharacter>& CharPtr : CharactersInTheArea )
     {
         if ( CharPtr.IsValid() )
         {
             CharPtr->Damage( Character->GetHp(), 6.f );
         }
     }
 }
 

There are of course a lot of additional things you can do with this kind of implementation, if you want to optimize the code you can play around with the timer handle on only run it when there's actually character in the area, you can tweak the damage rate to match the fire particle to give a bit of immersion to the game, etc.

more ▼

answered Jul 19 '16 at 03:16 AM

avatar image

Heapcleaner
526 15 5 19

avatar image Snowl0l Jul 19 '16 at 03:23 PM

This seems like an unorthodox way of doing it, and I may end up having to do it this way, but I also feel like there should be a way to create a collision event in my tick function. I just don't know how.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question