Use Chooser Plugin in C++

Hi!
Has anyone tried using the Chooser plugin in code?
I want to rewrite a BP Evaluate Chooser node (screen 1) to C++ code, but I don’t understand how to do it correctly.

.h file

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Player|Anim", meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UChooserTable> AnimChooserTable = nullptr;

.cpp file

FTraversalChooserInputs* chooserInputs = new FTraversalChooserInputs(
  TraversalResult->ActionType,
  TraversalResult->HasFrontLedge,
  TraversalResult->HasBackLedge,
  TraversalResult->HasBackFloor,
  TraversalResult->ObstacleHeight,
  TraversalResult->ObstacleDepth,
  TraversalResult->BackLedgeHeight,
  GetCharacterMovement()->MovementMode,
  Gait,
  UKismetMathLibrary::VSizeXY(GetCharacterMovement()->Velocity)
);
FTraversalChooserOutputs* chooserOutputs;
TArray<UAnimMontage*> validMontages = UChooserFunctionLibrary::EvaluateChooserMulti(chooserInputs, AnimChooserTable, UAnimMontage::StaticClass());
// OR
TArray<UAnimMontage*> validMontages = UChooserFunctionLibrary::EvaluateObjectChooserBaseMulti(AnimChooserTable, chooserInputs, UAnimMontage::StaticClass());

I have 3 problems (questions):

  1. Which fun is appropriate (or neither)? (screen 2 and screen 3)


  2. How to correctly pass a struct rather than a class?

  3. In addition to the result (TArray<UAnimMontage*>), how can I fill out the struct FTraversalChooserOutputs?

I will be glad for any help

Hi,

I don’t know what is the behavior you are looking for, so from what I’ve understood from your code I can say you have done most of the work, so:

  1. To create your FInstancedStruct use UChooserFunctionLibrary:
FInstancedStruct InstancedStruct = UChooserFunctionLibrary::MakeEvaluateChooser(ChooserTable);
  1. To add input (entry) to your FChooserEvaluationContext use UChooserFunctionLibrary or its functions:
FChooserEvaluationContext EvaluationContext;

// Object
UChooserFunctionLibrary::AddChooserObjectInput(EvaluationContext, Object);
EvaluationContext.AddObjectParam(Object);
// Struct
UChooserFunctionLibrary::AddChooserStructInput(EvaluationContext, Struct);
EvaluationContext.AddStructParam(Struct)	
  1. To get your out struct you can use the function below, since its params are references:
UChooserFunctionLibrary::GetChooserStructOutput(params)
  1. After that you can proceed with UChooserFunctionLibrary::EvaluateChooserMult(params);

If I can give you a suggest, simple create a function that do all the work, and also return what you expect.

May that help you.

Bye

Do I understand correctly that point 2 is needed not to add a new row to the table, but specifically to prepare input data for searching?
Because the table is already filled in. I just need to search in it.

I tried to do it as I understood. But it turned out badly).

The AddChooserStructInput() is not expecting a structure to input, but int32…

The GetChooserStructOutput() expects 2 more additional parameters to input, one of which is also int32.

And EvaluateChooserMulti() doesn’t want to accept my context because it expects a class, not a struct.

Sorry for writing this is separate messages. I can only attach one screenshot in one message.

I apologize for asking strange questions. I don’t have much experience with the UE. And I’m trying to improve it.

P.S. For additional info. I’m using UE 5.5.3 version.

Hey,

No problem, that’s ok.

That’s correct and make sense, if you take a look in your print, your ChooserTable set a enum that is inside your struct.

Your Enum ActionType comes from your struct FTraversalChooserOutputs, to better ilustrate, look this example:

.h file

UENUM(BlueprintType)
enum class ESVMovementState : uint8
{
	Idle,
	Walk,
	Run,
	Sprint
};

USTRUCT(BlueprintType)
struct FTraversalChooser
{
	GENERATED_BODY()
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	ESVMovementState MovementState;
};

In Chooser Table editor:

Look, I’m not sure what you are trying to do, all I know is you’d like to get the return data in C++, so there is a quick solution to achieve this, create a BlueprintImplementableEvent, that’s going to save you much time, since you can call this function in C++ and implement it in Blueprint, simple example:

.h file

UENUM(BlueprintType)
enum class ESVMovementState : uint8
{
	Idle,
	Walk,
	Run,
	Sprint
};

USTRUCT(BlueprintType)
struct FTraversalChooserIn
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool bIsMoving;
};

USTRUCT(BlueprintType)
struct FTraversalChooserOut
{
	GENERATED_BODY()
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	ESVMovementState MovementState;
};


UCLASS()
class DEV55_API ADevCharacter : public ACharacter
{
	GENERATED_BODY()

	UPROPERTY()
	FTraversalChooserOut OutData;
	
	UPROPERTY()
	FTraversalChooserIn InData;

public:
	
UFUNCTION(BlueprintImplementableEvent, Category = "Player|Anim")
	TArray<UAnimMontage*> CustomEvaluatedAnimMontage(FTraversalChooserIn InTraversal, FTraversalChooserOut& OutTraversal);
};

In Chooser Table:

In Your Blueprint override your custom function:

.cpp file - call your function:

InData.bIsMoving = true;

TArray<UAnimMontage> MontagesToPlay = CustomEvaluatedAnimMontage(InData, OutData);

May this solve your issue

Bye.

1 Like

At first I thought it would be better to do everything in code. But your solution seems more logical and convenient for me.
Thanks for your help!