I’ve got a simple script like this one in an Asset Utility Action
[Image Removed]
The script checks if a BoxComponent has a static mesh as its parent and set its extent and position based on that information to match with the static mesh component.
Script works fine
However, the new values of the box are not reflected in the viewport tab of the asset
Details Panel though reflect these modifications
The new values are reflected if we reload manually the asset after a save.
Now I understand why we wouldn’t reload the viewport on every subobject change (would be hard to detect) but then what can I do to manually force the viewport of an object to update?
The issue doesn’t occur if the object is not opened in the editor when rolling the script
Thanks
Steps to Reproduce
Open a blueprint
Modify that blueprint using the SubObjectData feature
Notice that your changes are not reflected in the viewport
Save your asset if your script didn’t do so
Reload the asset
Notice that the viewport is updated
Hey there, the functions SetBoxExtent and SetRelativeLocation are functions that only modify the object you’re calling it on. There is no magic in running a function inside an editor utility. Rather, there are functions that explicitly do the extra work of propagating a property changes to existing instances (like viewport instances of an actor) and subclasses.
When you want to modify a property on a blueprint asset and have it affect (propagate to) viewport instances, call SetEditorProperty instead like this for “BoxExtent” and “RelativeLocation”. SetEditorProperty internally calls UObject::PreEditChange/PostEditChangeProperty/PostEditChangeChainProperty which also will propagate from the current archetype object (the component of the blueprint) to archetype instances (the component of the preview actor in viewport).
[Image Removed]
I haven’t tested this solution fully but this is the direction you should try in. Please let me know how far you get!
Hi Zhi thanks for the answer
It does work however the solution will not scale enough for my needs:
- For the Relative Transform : I’d need to have three calls for location, rotation etc. To set the relative transform … it’s not the worst as the value saved is the relative one. If I wanted to make a World … that would mean that I’d have to make hard math scripting that are already done in other nodes …
- I cannot modify easily nested structures this way. It’s doable … but I’d need to Set Editor Property on the proeprty structure on a UObject but it wouldn’t work if I want to modify that a structure inside the structure … it’s half doable .. but more complex
- It’s not safe as the property name is hard coded …
- On some rare cases (BodyInstance) : modifying it becomes very complex
In the end, what I ended up doing was the following:
My script gather all the objects that has been modified by that script, converts them to package and for reload these …
[Image Removed]
I see how the code is done and what you’ve described and I don’t see a way to make these work in a more smoother way than by reloading …
Note : I couldn’t find a way to know if a package is Dirty : would be quite beneficial for editor tooling (second time I miss that option …) and also UPackages are not BlueprintType which means I can’t make any variables in blueprint of that type and it would be really helpful for some cases like this. Any reason why it’s not like this?
1) Indeed, to set a transform you’d need three calls via the SetEditorPropetty route but it’s straight forward to make a helper function in CPP or BP that combines it into one function.
2) Good point. In the past I have thought about adding support for nested paths. “MyComp.MySubobject.MyStruct.MyProp”.
3) True, a property picker would help here to prevent typos and validation to possibly catch invalid data due to variable renamed faster. I’ll gather some thoughts of other people who worked on these features.
4) SetEditorProperty isn’t intended as the one solution for all. The ideas implemented in it can be used for your own natively implemented but blueprint exposed utility functions. When modifying anything on a blueprint, PreEditChange/PostEditChange(Chain)Property is what triggers propagation and refreshed open editors in a lot of cases. UObject::GetArchetypeInstances can be used to manually propagate values or call refresh functions on instances. That forms a basis for writing your own utility functions.
As for why UPackages and other classes aren’t exposed. Blueprint utilities and their capabilities are relatively new and the API is still growing. However, exposing everything to BP do that utilities may cover some use cases is risky for us managing the engine API since once exposed we can’t undo that. If you can summarize what benefit you would have from UPackage as a blueprint type I can start an internal discussion.
However, I can predict that SetEditorProperty and making custom util functions would be our recommendation for your initial need here so the manual reloading workaround won’t be enough reason to expose UPackage as a BP type.
Thanks for the additional context for the desire of UPackage as a blueprint type. Interesting that you already found the wildcard pin-based workaround.
I’ve started gathering thoughts from other team members about SetEditorProperty usability and exposing UPackage as a BP type. I’ll let you know when I know more!
Hey Raphael, to close the loop:
- Devs I spoke to internally were open to improvements to SetEditorProperty, including supporting nested paths as text value and property picking from a class that would get support redirectors. Although that doesn’t solve your general case since you mention that you’re setting properties of a subclass (B : A) on a pointer of type parent class (A), hopefully when those improvements are implemented it does prove useful somewhat. This is treated as a feature request and we don’t give estimates for when we get to them. I appreciate our discussion leading to these ideas though!
- We decided to still not expose UPackage as a blueprint type. Currently there are 3 (maybe a few more) BP functions that expect or return a UPackage. Of those, GetPackageForObject() was recently created so at least there is some way to get the package to reload from an object. We believe exposing UPackage as a BP type has more drawbacks, like causing confusion around lack of ways to interact with said packages. For the time being, I recommend either passing around UObjects and calling GetPackageFromObject at the last moment or to create C++ helper functions yourself to collect (unique) packages from objects to reload.
- To find out in BP whether a package is dirty, currently also create your own C++ function to expose this to blueprint.
I believe that answers the questions you had. Is
“whatever the end solution could be, Epic should provide the option to enter an arbitrary string, for this case and other I may not foresee”
I agree! We will keep the current SetEditorProperty for sure, which allows you to just enter the property name as a string.
The OnHover tooltip makes sense so I’ll add that as a note for the feature request. Thanks for these suggestions! I’ll close this case.
Hi,
first of all, thanks for the quick replies it’s highly appreciated!
Here are some thoughts:
1) True. Though a bit tedious to do for each case when we’re trying to do a tool in BP. Still true though
2) Note that this is an issue I also had for handling data for DataTables. For there we don’t have access to the UObject, we can only manipulate a row with AddRow (which is unclear if you don’t go in the code as if the row exists already it does override it. It’s good but opaque in its naming imo). Still, all I can have access to is the structure property. What I end up doing for this is the logic of : Store the value of the row in an instanced struct variable, modify that temp variable, push AddRow with that temp variable on the same row. Only issue is : I have to expose that value to blueprintreadwrite when we would prefer not to.
In my opinion : if we’re in the context of a Blueprint Editor : we could just provide full access to structure properties marked as EditAnywhere. Same could go for any property … but that would come with an overhead.
3) The property is a name list, it’s not easy as we cannot have an exhaustive list : the property type doesn’t bring enough information as we may have a variable of type Parent when we’re manipulating a Child which would have more … we could maybe have an advanced checkbox saying “Only use known properties?”. If it’s ticked : we could parse every properties from the object type and push in the list of all the properties (definitely would need to have a filter text box …)
4) Thanks ! I’ll check that GetArchetypeInstances.
For the UPackage : I have the node “ReloadPackages” that takes an array of UPackages but I cannot create an array of UPackage … or I kind of did using a macro that is capable of holding any sort of array including the UPackage one. This kind of solved my issue but the script then becomes a mess as I cannot have multiple nodes representing that array[Image Removed]
Yea … used that trick to cache easily a value on complex pure node logics … right before the Show Exec option appeared ^^
Yes thanks Zhi.
For the support of the SetEditorProperty, main reason why I’m mentioning this parent/child case is because maybe whatever the end solution could be, Epic should provide the option to enter an arbitrary string, for this case and other I may not foresee
it’s going to be a big improvement anyway as finding the properties can be hard for a non-programmer so thanks 
Last suggestion on that feature : do so the OnHover of the property in the list displays a tooltip with the friendly name and the tooltip of the property?
Thanks a lot!