Announcement

Collapse
No announcement yet.

Destroy actor called twice due to endoverlap being called on destroyed actors

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

    Destroy actor called twice due to endoverlap being called on destroyed actors

    Hello,

    I have created a small 2d sidescroller. The play area is surrounded by a trigger used to clean up any actors leaving it. Problem is when an actor is destroyed inside of it the destroyed actor will trigger the endoverlap event of the surrounding trigger which will call destroy actor again on the already destroyed actor.

    I was wondering if anybody know a good approach to dealing with this problem?
    It would be nice if you could check if actor is pending kill or something before calling destroy actor. Some other things also happen when actors are destroyed which I do not want to be fired again for same actor.

    I am currently doing this as a blueprint only project just to try it out however if the best solution(s) is for c++ then that would be fine as well.

    NOTE: It seems you can check for pending kill in c++. Still wondering if there are any solutions to blueprint?
    Last edited by Insanez; 09-25-2015, 09:43 PM.

    #2
    I didn't expect a second trigger to get called if the actor has been destroyed.. does the blueprint stay in memory even if destroyed?

    If so, you could probably do the usual set a boolean to true if it's been killed and do a check before killing it.

    Comment


      #3
      I didn't check up on it properly. I was expecting some "PendingKill" boolean and searched for it. I however found the "IsActorBeingDestroyed" in blueprints (really should've searched properly). Problem now is that it gives the pending kill error when trying to access it. Log:

      PIE:Error: Error Cannot access 'BP_Beam_C_2'. It is pending kill. Property: 'Actor' from node Print String in graph 'DestroyActor' in blueprint BP_GameMode

      To RumbleMonk: There is only one trigger. I may have explained poorly so let me give an example. I shoot a beam which hits a target. In the process I call destroy actor for the beam since it should be destroyed on impact. If it does not hit a target it will continue moving and eventually get out of bounds of a surrounding trigger box. When this happens an EndOverlap event is triggered which will call destroy actor on the beam. Problem is when the actor is destroyed on the impact it will follow up with the EndOverlap event of the surrounding box trigger which will also call destroy actor.

      I do have an array set up with spawned actors in it. Getting late so will check it out tomorrow. I may just have made some silly mistake now that it is late. From what I know actors should be kept in memory until the GC kicks in once every minute or something.

      Comment


        #4
        Try with "Is Valid" and destroy it.

        Comment


          #5
          That works thanks. It is not part of the actor so I guess that is why it works. Is probably hooked up to the list of pending kill actors or something. Well it was the solution I had hoped for. Nice and clean:P

          NOTE: Actually it doesn't work which I thought it did. It does not produce the ispendingkill error. The problem is that "Is Valid" is not set to false before after it has already been removed from the scene so the "EndOverlap" event is being triggered before "Is Valid" is set to false.

          The flow is like this -> Call DestroyActor (beam impacts) -> OnActorEndOverlap (bounding trigger)-> Call DestroyActor (end overlap response) -> Return from DestroyActor(end overlap response) -> IsValid is set to false at this point which is too late -> Return from DestroyActor (beam impact)

          As you can see the second call to DestroyActor happens before the first DestroyActor has returned and also before the first DestroyActor call has set IsValid to false.

          My current solution is to store a reference to the most recent destroyed actor. Before destroy is call a valid check is made and then a check to see if the actor being destroyed is the same as the referenced one.
          Last edited by Insanez; 09-26-2015, 12:37 PM.

          Comment


            #6
            But why you check IsValid on the end ?

            I mean, why no do this:
            Call DestroyActor (beam impacts) -> OnActorEndOverlap (bounding trigger)-> IsValid ? -> Call DestroyActor (end overlap response) -> Return from DestroyActor(end overlap response)

            Comment


              #7
              Because IsValid has not been set to false yet. OnActorEndOverlap is called before IsValid has been set to false. Remember the first call to DestroyActor has not yet returned and I guess IsValid is only set near the end of the call.

              NOTE: Also I did check IsValid where you described it. Just that it is set to false where I posted it.
              Last edited by Insanez; 09-27-2015, 06:13 AM.

              Comment

              Working...
              X