Download

Custom events running concurrently! Work-around?

Hello all,

I’m trying to animate the death of an actor in my Level Blueprint, by calling the Animate_Row_Death EVENT (custom event set up in the blueprint of BLOCK_ROW_PARENT), then immediately calling Destroy Actor (assuming that the event will fully finish executing first, before moving onto the Destroy Actor node). This can be seen below:

However, what appears to be happening is that the Event is firing in its own thread (or maybe the timeline is what begins the separate thread), and simply continues along its original execution path (shown above) in the Level Blueprint, which just deletes the actor:

I would obviously want for the timeline animation to finish, then have the Level Blueprint continue its execution path. Are there any workarounds to this? I can’t reference the Level Blueprint from my Block_Row_Parent BP, so firing off an event from within my blockrow parent is out of the question (plus, its a little dirty, the row shouldn’t communicate with the level BP). Could someone either provide a quick example or point me in the direction of one please?

Thank you very much, any help is appreciated!

What is the timeline length? Are you only calling the event once? Also, which version of the engine are you using?

Timeline length is 2.00 seconds exactly. The event is indeed only being called once, as only one row is destroyed at a time. Lastly, version 4.7.6

Event dispatchers should do the trick. Here is an example

Level blueprint:
d6675fd0587902bf2645a2399904b6d8e999cb46.png

Row Actor blueprint:
efeeaead044a27751ba2532ed3bba5c99ae50430.png

AnimationFinished event dispatcher is called after the timeline finishes. Level blueprint picks up on this and tidies up by destroying and whatnot.

THanks for the response! I essentially have that workaround set up for another similar issue. But after running into this twice, I’ve decided I want to see if there’s a more obvious way to do this, or a way to make sure the event finishes completely before moving along the execution path.

Another alternative is just add a delay node inbetween the death row Event and the Detroy actor function so you’re basically saying do this first, then wait (delay) for x amount of time then execute destroy function. and then just play with the timer to adjust it how you want.

Also in you’re animate event you could just add a bool flag. Eg event is finished and add it to the end Of the chain. Eg event finished set bool to true.

Then before you destroy the actor you just check the bool. If it Is true then the animate event has finished so destroy actor if false do nothing etc

Also I noticed on you’re branch you have it set to true and false both leading to destroy actor. What is the condition for this branch ?? Have you done checks to see if this condition is evaluating to what you want ?? Just to rule out that this isn’t the problem ??

No it’s not an actual animation, I’m just using a timeline to produce a float-track and using that to set the location of a part of my actor. It’s just a timeline updating the objects location. I also can’t add a delay node there because where I actually call the Animate_Row_Death event (in the LevelBP) is a function, and we can’t place time-sensitive or altering nodes in functions.

EDIT:

Yes, the branch is confirmed working fine. It’s only supposed to animate death for a certain type of row, so if it’s not that row, it just deletes without animation.

I’ve tried the bool method, and while it works, it lets the animation finish, and it takes the “do nothing” path (ie, doesn’t delete the row). However actually deleting the row and doing the remaining data clean up (ie, deleting the reference from the array of rows, and a bit of extra data management) is integral to the game. So i have to delete the row before I spawn my next row. With the bool method, after it does nothing (doesn’t delete the row, lets the animation finish), I have nothing to precisely tell me how much longer I need to wait before doing the delete.

What so in the top screen shot you can’t add a delay node to the execution line coming out of the event then from there plug it in to the destroy actor function ?? I’m talking actually in you’re level blueprint not inside the function .

So in level blueprint the flow would go
BRANCH condition true > call animate row death > delay node > call destroy actor

Like that ??

The top screenshot is a function inside my level blueprint. And since I can’t place latent functions within functions, I can’t place a delay node between the ANIMATE_ROW_DEATH and Destroy Actor nodes.

I get what you mean now I thought that was just the level blueprint didn’t realise it was a function. Can you post up the level blueprint where you actually call these functions ??

How bout just ending the animate event where it is. Then take the destroy actor function put it into it’s own custom event then just call that in the actual level blueprint after the animate event has been called ??

I was thinking about it, but the thing is, I’d need to put that Destroy Actor node (as well as the data cleanup that involves variables native to the Level BP) at the END of the actual animation event (ie, the Event ANIMATE_ROW_DEATH in BLOCK_ROW_PARENT). The row can’t communicate with the level BP.

Not yet no but in engine 4.9 release you will be able to as there adding a cast to level blueprint node an functionality . Which will be nice

You could run them in Sequence? On the row before the death event, set the bool at the end and check for it at the beginning. If it’s set, move down the sequence. Then on the next sequence, check the bool and if it is set, execute the line of death, clearing the bool before-hand.

So basically, if the sequence was somehow called twice or three thousand times in a half-second, it would execute the correct lines in order.

I thought of sequencing too, but it essentially garners the same result. The first sequencing pin will call the timeline via the event, and that will execute in its own thread while the sequencer moves down and continues the sequential executiob. (Ie, deleting the row before animation is done).

I think the workaround is to not have my BLOCK_ROW_PARENT class contain the event for death animation (even though it makes sense, and I can have different block rows that extend the PARENT class override the event and implement their own). This way, I can call the death animation event from my level BP but not connect the event to the destroy actor node. Then in the actual event itself (now in the level BP), I can tell it to destroy and do the data management after its cleanup.

And that IMO is messy and defeating the reason of me using abstraction and overridable functions.

Also the bool method I discussed above, I can add bool checks to let the animation finish, but deleting the row is important before I spawn my next one, and if i don’t destroy it becuase of some bool (eg, bIsAnimatingDeath), the function which deletes stuff (top screenshot in OP) will never reach a condition where the animated row gets destroyed. I don’t know how long to wait before calling the function again to indeed delete it

You can do one of the following things.

1.call destroy actor on the end event of animate death rowI.e attach destroy actor to the finished node of the time line

  1. If you want to seperate things give destroy actor and subsequent required actions its own event and call that in the finished node of the timeline

Hi,

not sure if i am overseeing something very simple, but do you really need an event?

Events will run in an own thread (thats also why they cant have a return value), the execution flow that comes out of the call-event-node is just there for being able to continue execution while the event runs (otherwise you would run into a dead end when call an event).

You could actually call a public function instead of a event, this will do its stuff and then return to the caller, so its done synchronously.

Cheers,
Indy

You know what, that should actually work. With the function, you will likely need Delays.

Sorry Indygoof, mind expanding a little? Won’t I still have to use events to throw a timeline in there? If it’s a cleaner workaround, I’ll change what I did.

I sorted it without delays! I used Event Dispatchers, which allowed me to keep certain segments of the blueprints where they should have been (ie, ANIMATE ROW DEATH stays in BLOCK_ROW).

So here was a little summary of the clusterf***:

  • If I call the ANIMATE_ROW_DEATH event, it calls the destroy actor node right after - obviously not desired functionality. So I set up an event dispatcher which dispatches its event when the actual animation (in BLOCK_ROW) is finished. (This allowed the animation to finish before the delete).
  • Right after I called the PURGE ROW event (which is the one in question - the one that calls ANIMATE_ROW_DEATH and deletes), I eventually either spawn another row. But since PURGE ROW is an event, you guessed it, that event fires off in its own thread. So what happens is the BLOCK_ROW death is animated, but at the same time, a row is added above it (again, NOT DESIRED). Animation MUST finish and row must delete before we add another.** Again, i solved this by creating another event dispatcher, within the LevelBP, and I fire off the event when the delete is done.**

So, to add a new row (when the user fails a row and its death is animated), I needed to wait for the row delete to complete, and to wait for the row delete to complete, I needed to wait for the animation to complete.

Thus, if you could expand on that public function stuff, or link me to some documentation I could read for it I’d really appreciate it, cause my blueprints have been spaghettified.

EDIT:

Also, I’m a little vague on what you mean by public function? Just a regular function in a BP? Aren’t they public by default? Also, I can’t add latent functionality to functions, so I can’t use timelines to update their positions (ie, animate their deaths).