I’ve an ability system that uses actor components. When using async load asset class then attaching the component I need to pass variables that were sent to the event that’s doing the async loading and attaching. How is everyone handling this? I had to switch to blocking loading to allow for this otherwise 2 calls to the event in a row cause all manner of problems. It’d be great if there was an async load asset class node that accepted a payload object or something.
There’s a finished pin on the node, you need to use that.
It’s a bit more tricky if you’re load many async assets…
I know there’s a finished pin. That’s not what I’m talking about. Example as follows for my problem.
Event(Location) → Async Load → Finish → Set Location
Call Event once and pass it the location. Call it a second time immediately. The first async load will get the location of the second call not the first call. Note this is just a simple example. What I’m doing is a bit more complicated than that.
There needs to be a way to pass a payload otherwise this will always happen with async behaviors. I can’t see a workaround for this other than juggling states myself I guess in a map variable, but there’s no guarantee the async loads will happen in order so that’s not ideal either.
So far have had to just use blocking loading as I don’t see a workaround.
I know exactly what you mean, I have it with callbacks on level loads.
There’s only two options I’m aware of
1 Write the call back in a ‘re-entrant’ way to handle this.
2 Spawn objects or actors to handle the call back.
N 1 is a bit more tricky in blueprint, but possible. Yes, you might need something like a map or array of handles ( or another way to recognize what just happened ).
I’m not really seeing a workaround in blueprints to be honest. I think I’d need to consider making a new C++ node that can handle passing along a payload with the callback. Ah well. At the moment blocking loading isn’t showing any performance issues for now and will look into improving it later should I need to.
correct, you can make a K2Node to do it for you but its pretty complicated.
I’ve a few custom K2 node plugins I made already I’ll look into it further should I need to. Thanks everyone. Seams like it might be a good idea for UE to improve that node to accept a UObject payload maybe.
im not sure of your use case but cant you just add a payload to the parent class of your abilities and cast on load completed?
I ended up spawning a lightweight actor to handle the task, it works well. No trying to figure out which callback is for what.
Also passes a payload to the calling actor.
I’m of course only casting on load complete. Feeding payload to parent event is what I’m already doing and that only works if the event is called once and not a second time during execution of the event when you’re dealing with latent actions. Async Load Asset Class is a latent action so the data fed to it on its finish event may not exist anymore or may have changed. That’s basically why you need a payload or caching system.
Will probably just make a new C++ K2 node to deal with this when the time comes as I’ll be able to just keep a UObject for each call and can contain whatever data I need in that, but for now performance is fine with blocking loading since the event is often just called during game pause.
In short this is just a BP problem. It’s completely solvable with C++. Was just seeing if I was missing something in BP here.
you can even just use a UObject for this, which ultimately is what a K2Node will do.
or for the simple BP option, instead of calling the Async load on a loop just recall itself on completed.
or load all objects in parallel and then have a second loop resolve the items and cast/spawn
Not in BP, was far as I’m aware
Calling in a loop or parallel is not an option, as we don’t know when a load is going to happen. The loads, and callbacks, all happen in a totally unpredictable sequence.
The simple actor handles it very elegantly in BP. I know some people are allergic to spawning an actor for this sort of thing, but when you’re already streaming a level, I don’t think one more actor will do any harm
loop->construct object->bind to load complete, call load function?
they do but you know when they have all completed.
so you have an ItemsToLoad Array, loop->Async load, wait until all loading is complete (int check) then ItemsToLoad loop->resolve->call functions.
i have no problem with this, although if i understand you its an Actor per loaditem yeah? UObject does the same job.
ive done this myself so im sure it works but i did encapsulate it in a K2Node so havent actually tested my above methods
I tried an array, waaaaay too hard
I don’t get how the object can pass a payload to an actor on completion
i was being general, so to use the original question for clarity.
create a UObject, pass in the payload as spawn param, call Activate function on the UObject.
on activate the UObject Async loads the component, and assigns the payload data then.
each loaded asset is encapsulated in its own UObject so each one has its own payload and knows when its finished loading.
Yeah that could work. BP Object should even be able to do that fine, but that’s a lot of back and forth communication between my classes I don’t want to deal with. I’m going to make my own latent action node in C++ that handles the uobject for me. It’s basically what I’ve done for my async projectiles and attack system I just need to do it for loading assets and I’ll be good to go.
yep exactly what ive done, i used a k2node as a macro for what i suggested above but with the advantage of dynamic spawn params and a resolved output type