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"

Office Holiday

Epic Games' offices will be on holiday from June 22nd to July 7th. During this period support will be limited. Our offices will reopen on Monday, July 8th. 

UProjectileMovementComponent::HandleHitWall is not virtual

I have used HandleImpact in my derived class to allow our projectile to penetrate objects. I noticed in the UProjectileMovementComponent::TickComponent() function that it calls HandleHitWall() (which in turn calls HandleImpact that is virtual and I overridden it). Right after calling HandleHitWall() the TickComponent() then tries to slide the projectile across the wall (hence messing up my velocity settings to allow for penetration). I am not able to override HandleHitWall to return true to avoid this function from modifying our velocity. Please make HandleHitWall virtual.

Here is the header file:

     /** @return true if the simulation should stop. */
     bool HandleHitWall(const FHitResult& Hit, float TimeTick, const FVector& MoveDelta);
     /** Applies bounce logic (if enabled) to affect velocity upon impact, or stops the projectile if bounces are not enabled (or velocity is below threshold). Fires applicable events. */
     virtual void HandleImpact(const FHitResult& Hit, float TimeSlice=0.f, const FVector& MoveDelta = FVector::ZeroVector) override;

In the TickComponent() function:

         if (HandleHitWall(Hit, TimeTick, MoveDelta))
         if (bIsSliding)
                 //adjust to move along new wall
                 Velocity = ComputeSlideVector(Velocity, 1.f, Normal, Hit);

If this is not the correct way to allow projectiles to penetrate objects then what is the correct way to allow penetration?

Product Version: Not Selected
more ▼

asked Feb 15 '15 at 07:51 AM in Bug Reports

avatar image

383 8 132 45

avatar image Kory Feb 15 '15 at 08:50 AM

Overriding these functions will circumvent not having virtual on the HandleHitWall() function. .h file:

     //UMovementComponent overrides - prevent messing with our penetration logic
     virtual FVector ComputeSlideVector(const FVector& Delta, const float Time, const FVector& Normal, const FHitResult& Hit) const override;
     //UProjectileMovementComponent overrides - prevent messing with our penetration logic
     virtual bool HandleSliding(FHitResult& Hit, float& SubTickTimeRemaining) override;

cpp file:

 FVector UDragProjectileMovementComponent::ComputeSlideVector(const FVector& Delta, const float Time, const FVector& Normal, const FHitResult& Hit) const
     //Override this function because it messes with our penetration logic
     return Velocity;
 bool UDragProjectileMovementComponent::HandleSliding(FHitResult& Hit, float& SubTickTimeRemaining)
     //Override this function because it messes with our penetration logic
     return false;
avatar image zeroexception STAFF Mar 17 '15 at 08:46 PM

Hi Kory, I'm looking at the request to make HandleHitWall() virtual.

The more I look at that function the more I just want to remove it, or leave it non-virtual. Really all it's doing is checking that the actor/component remains valid, and calls HandleImpact(). I think that the actor validity checks should occur outside a virtual because they always need to happen and users shouldn't be able to accidentally remove those. I could move them to the tick/update loop if the function were removed.

In any case, I would like more background about what your virtual HandleHitWall() would look like so I can make sure you can still do what you want. As far as I can tell you would just be overriding the return value which will make the tick update stop.

             if (HandleHitWall(Hit, TimeTick, MoveDelta))

Maybe we need a different check during the update loop, or allow HandleHitWall to return an enum indicating that updates should stop, continue with deflection, or continue to the next loop update.

Thanks, -Zak

avatar image Kory Mar 17 '15 at 09:00 PM

If I remember correctly, I think it was to to get out of the Tick loop because the function calls later were messing up my custom terminal ballistics code. So I think having a way of returning early out of the Tick function would work for us and others. Basically, if I remember correctly, it was changing my velocity after I had already set it. I just wanted to handle the rest of the movement myself and exit out of the parent's Tick function. So an enum would make sense. Thanks Zak, Kory

avatar image zeroexception STAFF Mar 24 '15 at 10:46 PM

So what I've come up with to address this is the following (apologies if the formatting gets a bit screwy, I'll add a screenshot of the code which is probably more readable):

Replaced HandleHitWall() with virtual HandleBlockingHit() that returns an enum:

     // Enum indicating how simulation should proceed after HandleBlockingHit() is called.
     enum class EHandleBlockingHitResult
         // Assume velocity has been deflected, and trigger HandleDeflection().
         // This is the default return value of HandleBlockingHit().
         // Advance to the next simulation update. Typically used when additional slide/multi-bounce logic can be ignored,
         // such as when an object that blocked the projectile is destroyed and movement should continue.
         // Abort all further simulation. Typically used when components have been invalidated or simulation stops.

Added new virtual HandleDeflection() which wraps up all the old code that adjusted velocity in multi-bounce situations and handled logic deciding whether to call HandleSliding() with new velocity.

I think this should allow easier overrides to have "blocking hits" that allow the projectile to simply pass through-- you would override HandleBlockingHit to return "AdvanceNextSubstep" and be good to go.

Let me know if that makes sense and fits your needs. I think this will be useful in a lot of scenarios.


alt text

avatar image Kory Mar 24 '15 at 11:21 PM

Yes, I think that would be very useful in a lot of scenarios as well. What I ended up doing for us was just creating my own projectile movement class, maybe now I can go back to the engine version with this addition. Thanks so much, Kory

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

1 answer: sort voted first

Hey Kory-

It sounds as though you were able to find a solution to the problem you were having. Since you point out the call to HandleImpact() from HandleHitWall(), another solution you could use would be to modify the source code to explictly call your overridden HandleImpact() function. Best of luck in your project with whichever solution you chose to go with.


Doug Wilson

more ▼

answered Feb 18 '15 at 06:50 PM

avatar image Kory Feb 19 '15 at 01:05 AM

Sorry Doug, this was not a solution but a work-around rather. I would prefer that function be made virtual so we can override it the right way. Please put in a ticket to make that function virtual and we will fix our code once that is done. Thanks, Kory

avatar image Doug E ♦♦ STAFF Feb 19 '15 at 01:51 PM

Hey Kory-

A feature request for HandleHitWall() to be made virtual has been entered (UE-10106) for consideration.

avatar image Kory Feb 19 '15 at 02:32 PM

Awesome, thanks Doug! (:

(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