Handling properties unexposed to bp/python

Have a couple questions regarding what’s best practice for handling properties unexposed to blueprint and python and the only way to change them is from c++.

  1. How do I identify them? For example I want to change UAnimSequence.RetargetSourceAssetReferencePose (maybe not the best example but it will work).
    Couldn’t find it in blueprint search…

And in python API it’s missing too and trying to access it directly

    assets = unreal.EditorUtilityLibrary.get_selected_asset_data()
    a = assets[0].get_asset() # type: unreal.AnimSequence
    print(a.get_editor_property("RetargetSourceAssetReferencePose"))
    # Exception: AnimSequence: Property 'RetargetSourceAssetReferencePose' for attribute 'RetargetSourceAssetReferencePose' on 'AnimSequence' is protected and cannot be read

The question is how do I make sure it’s not exposed by some other nickname?

I’ve researched source code and it seems that unexposed properties have empty UProperty macro (I guess it also can have other value besides EditAnywhere that would make it unexposed). Is this it or there are other ways to make it usable for bp/python?

  1. Is there some way around it to access it from blueprint and python besides rewriting the entire thing in C++? Maybe there is some way to make it exposed from C++ without recompiling the engine and then access it from bp and python?

Check the UPROPERTY specifiers in C++ source :
EditDefaultsOnly —> editable in details panel when editing blueprint.
EditInstanceOnly —> editable in details panel of a placed actor.
EditAnywhere —> editable in both.
BlueprintReadOnly —> can be get (but not set) in graphs.
BlueprintReadWrite —> can be get and set in graphs.

Meta tag “DisplayName” can be used to give it a different BP nickname than the C++ variable name. This nickname might not apply to python (I don’t know).

Further than that, also use thorough search to try and see if, maybe, there are fully exposed functions to get and set your variable. Functions need to have UFUNCTION with BlueprintCallable or BlueprintPure specifier to be exposed.

It doesn’t seem to be the case here.


The most proper way to handle this is to create your own C++ library of blueprint-callable functions to expose whatever you need to blueprints.
Example

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Animation/AnimSequence.h"
#include "MyFunctionLibrary.generated.h"

UCLASS()
class UMyFunctionLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()
public:
    UFUNCTION(BlueprintPure)
    static TArray<FTransform> GetBlahBlah(UAnimSequence* Target)
    {
        return Target->RetargetSourceAssetReferencePose;
    }
};


There is also a much less known approach, which I sometimes use.
As long as the UPROPERTY macro is present, they are exposed to the reflection system, and can be theoretically accessed without recompiling.
It will require a bit of C++ to expose, then can be used in blueprints/python without modifying/recompiling its source.

It is also interesting in that it can access protected/private members, as long as they have the UPROPERTY macro.
It can also be automated in a way, for example to automatically expose all properties in a class or in a struct with a simple for loop.

As an example, running the following code should expose the property to blueprints (and python) :

UClass* Class = UAnimSequence::StaticClass();
FProperty* Prop = Class->FindPropertyByName("RetargetSourceAssetReferencePose");
Prop->SetPropertyFlags(CPF_BlueprintVisible);

Not sure if there’s an official stance on doing this sort of thing though, so use at your own risk :stuck_out_tongue:

1 Like

your answer is pure gold, thank you!

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