Hi all
We are working on a rigging picker for Control Rig, and we want it to be able to execute Control Rig user events. Currently, our code collects a list of user events that start with the prefix PICKER_
and attempts to trigger them. Here’s what we have so far:
void UKhaosControlRigPickerWidget::OnActorSelectionChanged(const TArray<UObject*>& SelectedObjects, bool bIsActorSelectionChanged)
{
// Find first selected actor with a control rig.
TSet<UControlRig*> ControlRigs;
for (UObject* SelectedObject : SelectedObjects)
{
AActor* SelectedActor = Cast<AActor>(SelectedObject);
if (!SelectedActor || !IsValid(SelectedActor))
{
continue;
}
TArray<USkeletalMeshComponent*> SkeletalMeshComponents;
SelectedActor->GetComponents(USkeletalMeshComponent::StaticClass(), SkeletalMeshComponents);
for (USkeletalMeshComponent* SkeletalMeshComponent : SkeletalMeshComponents)
{
TArray<UControlRig*> OwnedControlRigs = UControlRig::FindControlRigs(SkeletalMeshComponent, nullptr /* optionally filter by class */);
for (UControlRig* ControlRig : OwnedControlRigs)
{
if (ControlRig->IsModularRig())
{
auto ModularRig = Cast<UModularRig>(ControlRig);
for (const auto& Module : ModularRig->Modules)
{
ControlRigs.Add(Module.GetRig());
}
}
else
{
ControlRigs.Add(ControlRig);
}
}
}
}
// Build action list.
TArray<UKhaosControlRigPickerAction*> PickerActions;
for (UControlRig* ControlRig : ControlRigs)
{
PickerActions.Append(GetPickerActionsForControlRig(ControlRig));
}
K2_OnControlRigSelectionChanged(PickerActions);
}
TArray<UKhaosControlRigPickerAction*> UKhaosControlRigPickerWidget::GetPickerActionsForControlRig(UControlRig* const ControlRig)
{
if (!ensure(ControlRig))
{
return {};
}
if (!ensure(!ControlRig->IsModularRig()))
{
return {};
}
TArray<UKhaosControlRigPickerAction*> Actions;
// All user events prefixed with PICKER_ will be automatically registered as picker actions.
const TArray<FName> EventNames = ControlRig->GetSupportedEvents();
for (const FName& EventName : EventNames)
{
if (EventName.ToString().StartsWith("PICKER_"))
{
auto Action = NewObject<UKhaosControlRigPickerAction>(this);
Action->Name = FText::FromString(FString::Printf(TEXT("%s (%s)"), *EventName.ToString(), *ControlRig->GetFName().ToString()));
Action->Tooltip = FText::FromString(FString::Printf(TEXT("Execute '%s' user event."), *ControlRig->GetFName().ToString()));
Action->ActionDelegate.BindLambda([ControlRig, EventName]() {
ControlRig->Execute_Internal(EventName);
});
Actions.Add(Action);
}
}
return Actions;
}
We are facing some issues when trying to invoke events on control rig inside modular rigs. Specifically, calling both Execute_Internal
and ExecuteEvent
seems to be very hit or miss.
For example, on our 4-armed character it only works on 2. It is always the same 2.. Which i find a little odd?