variant\_set \= variants\_asset.get\_variant\_set(i)
if not variant\_set:
continue
display\_name \= variant\_set.get\_display\_text()
number\_of\_variants \= variant\_set.get\_num\_variants()
for j in range(number\_of\_variants):
variant \= variant\_set.get\_variant(j)
if not variant:
continue
display\_name \= variant.get\_display\_text()
actors \= variant.get\_num\_actors()
for k in range(actors):
actor \= variant.get\_actor(k)
if not actor:
continue
captured\_properties \= variant.get\_captured\_properties(actor)
for captured\_property in captured\_properties:
property\_type \= captured\_property.get\_property\_type\_string()
full\_display\_string \= captured\_property.get\_full\_display\_string()
if property\_type \=\= 'bool':
value \= captured\_property.get\_value\_bool() \<\- Crash here sometimes
Steps to Reproduce
Through the Python API, is there a way to reach the actual binding between an actor and the property which is captured in a variant? Currently it seems I must use the property label, which in many cases is fine, but can be unreliable. A user might have duplicated and rebound some binding to another actor, in which case the label does not update. When I try to retrieve the binding in this case, I will likely get errors, and cant reach the actual binding, and in some case Unreal will just crash hard
Non-fatal error: Error: Invalid property type for UPropertyValue ‘ANIM_SEAT_1L_BACKREST_0 / Relative Rotation’!
Fatal error: LogVariantContent: Warning: Returning size zero for PropertyValue ‘shell_1 / Absolute Location’
Even using the function get_capturable_properties, and checking if the property for which I’m trying to capture the value is valid, isn’t always enough, and is still problematic because I still want the binding, even though the property label is wrong, or the property label might be in the list, but as soon as I try to access its value, Unreal could crash hard with the size zero error
First of all, my apologies for the very delayed answer.
I locally tried your script and I got no crash. However, I wonder whether you are experiencing those crashes after having made some modifications to your level, i.e. renaming an actor.
Thanks for your patience.
Regards,
Jean-Luc
P.S. I will be on vacations for the next two weeks. I will try to come back to you as soon as I am back.
I looked into the code and I can’t find a way to solve your issue. Unfortunately, there is no exposed API to ‘refresh’ a LevelVariantSet before accessing properties. I am sorry.
If you can write your own C++ BP function, I suggest to look at SVariantManager::OnPieEvent which is doing some cleanup. This may help.
Sorry again for not being able to help you better.
Found a work around. Call variant.switch_on() for each variant before you try to gather their properties. Seems to cause some clean up and validation, which eliminated the crashing in my case
Sorry for the late answer and kudos for finding this workaround.
The developer in charge of the variants is not part of the team anymore. So we lost from knowledge there.
A quick look at UVariant::SwitchOn confirms it is strengthening all the bindings from bottom to top which may fix some stale pointers which were causing the crash. Ill look deeper into this.
Yes, I believe the crashes only occur when a user has changed something after the variant was created and some properties were bound. Perhaps they are renaming actors, or manually rebinding within the Right clicking on variant manger UI by right clicking on the actor and choosing ‘Rebind to other actor’. Its difficult to anticipate all the things they might be doing. Many of the users I support are on the opposite side of the world from me, so I dont know exactly what they are doing to cause these occasional corruptions in the variant bindings. I’m hoping for some solution to avoid a hard crash incase there is some issue with the bound properties. There doesnt seem to be a great way to validate before calling .get_value_bool, for instance