"Is Valid" not executing in For Each Loop handling Children casting to Parent Classes

Hello there! First time I post here.
I’m currently working on something and have a very weird issue. First time I see it after using UE5 since release. I’m currently using 5.1.1.

Summarized: I’ve made a PrimaryDataAsset and a couple of children of it. This is for some different item types.
Now, I’ve got a UI that displays all items on-screen that are in a container (any inventory you open).
I’ve got a an array of structs that’s the inventory variable itself in the “OpenContianer” function.
Now, inside this struct there’s only a PrimaryDataAsset of the item parent class and some other completely unrelated things.
I cast to the child classes to get specific variables from them inside the For Each Loop.

Sounds all good, right? Except that for whatever reason, the “Is Valid” in-built macro literally doesn’t execute. It doesn’t even print out anything. I’ve verified this in a new project even with just this functionality, entirely dumbed down.
I have to use the “Cast To” “Cast Failed” output, otherwise, stuff won’t execute and it doesn’t even reach a breakpoint. It’s very, very odd.

In my screenshot you can see that I’m using the “Is Valid” output because for this usage it still works. If it’s actually valid, it executes it. If it’s not valid, it doesn’t execute it. Again, no print to screen working. And again, if it’s not valid, I have to use the “Cast Failed” node instead of using the in-built macro or the bool node with a branch. The branch also doesn’t reach a breakpoint.

The whole goal here was to just simply set the UI Text to be blank if it’s some other item to get a spreadsheet kind of look in the UI.
That’s besides the point but yeah.

Either way, is there some sort of limitation as far as “Cast To” and “Is Valid” (including the bool version → doesn’t work. lol) goes that I’m unaware of in “For Each Loops?” Or maybe it’s an issue with PrimaryData Assets specifically.

Thank you very much and I think it’d be interesting to see what’s causing this. It’s working now but I could definitely sleep better now, knowing why this is actually happening.

You don’t need to use IsValid after casting. CastTo executes CastFailed if an object is invalid.

Thanks for this but I still need to check if it’s actually valid. Need both. Would be easier to use both pins from “Is Valid.”
For easier checking, consistency and setting the UI things.

Use IsValid before CastTo

Heyo, tried that. That executes but it doesn’t give the sort of functionality I wanted.
The whole goal was to check the parent class DataAsset in the struct and cast to different children classes to see what it actually is to get access to their own specific class variables.
Thanks for the help.

(Just for further clarification, this is what’s in blank project trying to replicate the issue.
Base class being PrimaryDataAsset.)

Just trying to cast a parent class item to a child class item and check if it’s valid or not to get access to specific child variables. “Cast To” failed node executes. The “Is Valid” failed exec pin literally does not execute. Doesn’t even print. It puts the whole script on hold, somehow.
Thanks!

Well, guess it’s time for a little update.
I’ve ended up using the Cast To “Cast Failed” execution pin but additionally reported this as a bug.
I could be wrong but I don’t think this is intended behaviour. Haha

It’s not a bug.

All variables that are universal to class should be set in the parent class and only configured in the child.

References for the Child should be of Parent Type.

e.g. BP_ParentClass, BP_ChildClass

ChildRef (BP_ParentClass Obj Ref)

No need to cast and you will have full access to globals. Only time you ever cast to the child is if appended new/custom variables in the child class. Shouldn’t be the case…ever.

An extended child class should be a sub Parent class.

e.g.
BP_Weapons

  • BP_Guns
    — BP_AssaultRifles (ref/cast BP_Guns)
    ----- BP_AK47 (ref/cast BP_AssaultRifles)
    — BP_Pistols (ref/cast BP_Guns)
    ----- BP_Baretta92fs (ref/cast BP_Pistols )

Heyo, thanks for the reply!

Thing is the children might have variables the parent does not have. The whole purpose was to have one parent class with its own shared variables, have children have some additional ones. Then easily pick whatever thing of the parent class and go from there. Which would be casting.

Let’s not forget the actual thing: The “Cast Failed” from the “Cast To” works. That’s not the issue. The problem is specifically the “Is Valid” node. The “Is not Valid” which should return null if it failed (meaning it should be doing pretty much the same thing) literally does not even execute. You could tell it to do whatever 500 more things but it would just stop the whole script and the pin does not execute.

Whole thing is more of a QoL thing. Make a parent class for Item. Make children that are MiscItem, HealItem, etc. Now you make a variable of the parent item and you get all the children in the drop-down. Now if you need to access specific child variables, you’re out of luck if you wanna use the IsValid node. Maybe there’s actually no functionality for parent/child shenanigans and that’s why it does not execute.

Your cast is failing!

If Cast is successful the Is Valid will execute. You cannot cast a Parent against Child. It will always fail.

Casts should be specific or UP the hierarchy.

Using my previous breakdown…

BP_Weapons (Parent)

  • BP_Guns (Sub Parent)
    — BP_AssaultRifles (Sub Sub Parent)
    ----- BP_AK47 (Child)
    — BP_Pistols (Sub Sub Parent)
    ----- BP_Baretta92fs (Child)

From BP_Guns down you can cast to BP_Weapons and it will succeed. You’ll get access to vars defined with in BP_Guns & BP_Weapons.

BP_AK47 should cast to BP_AssaultRifles… It’ll gain access to everything defined in BP_weapon, BP_Guns, and BP_AssaultRifles.

BP_AssaultRifles cannot be cast to BP_AK47 !!!


Your example clearly shows the Parent Class being Cast to a Child Class.

THIS WILL ALWAYS FAIL. Therefore your Is Valid node will not be executed. Flow logic is executing off the FAIL pin.

Thanks. I was hoping that it would fail. That was intended.
The thing I was assuming is that if it fails, it would return null. In which case the IsNotValid should have worked right?
Turns out that’s not the case then. Interesting how it doesn’t catch that.
The more you know. If you can confirm that I understood that right, I can mark your reply as the answer so others don’t get stuck on this in the future.

You cannot treat it like a Sequence node. It’s logic flow works like a branch. Was the cast successful (TRUE / FALSE).

If TRUE the top pins execution logic is processed.
If FALSE the Cast Failed execution logic is processed.

The As blah blah class pin (value, return) is only VALID if the cast was successful. If it fails it’ll always be empty/null.

If you need further clarification I’ll do a short vid.

Heyo, nah. All good.
Thank you very much. This was much needed info.
Didn’t find any sort of specific documentation about this usage case.

So, turns out I tried to choke it in the wrong spot. lol
My understanding of it was wrong.
In the end, in my actual project I was using the “Cast Failed” exec pin directly to check if it failed. Used the IsValid for when it was fine.
Turns out that’s the adequate way then afterall.

Thanks a ton!
It’s hilarious to me how in a video I recorded myself, I did that as well and I said “Huh? Why does it not work but this works?” Assuming it’s essentially the same thing. Hahaha

You shouldn’t be using Cast To with intent to fail as a flow control mechanism. It’s overall bad design.

Use Direct Comparisons instead.

Thanks. I was considering grabbing the item’s actual class and simply comparing those directly.
Another alternative would have been to make an enum in the parent for the base type and do a switch.
Good to know. I’ll switch things out. Thanks again!

I use Gameplay Tags to identify items without casting. IF I eventually need to cast I can do a direct cast.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.