Skip to content

AI Support

Jared Taylor edited this page Apr 12, 2026 · 2 revisions

Important

UGraspSubsystem provides spatial search for graspable components
Mirrors the USmartObjectSubsystem pattern for AI integration
Available to both BP and C++

Requires Grasp version >=1.4.0

Graspable Angle and Distance

To find a location for the NPC to move to so that they can interact based on the angle and distance assigned to the GraspData, you can use UGraspStatics::GetInteractionLocationForGraspable()

Finding Graspables

The subsystem provides several search methods depending on your use case.

Spatial Search (Box or Sphere)

Use FindGraspables when you need to find all graspable components within a region. This performs a physics overlap query against the Grasp collision channel and filters results by FGraspRequestFilter.

FGraspRequest Request;
Request.bUseSphere = true;
Request.QuerySphereCenter = MyLocation;
Request.QuerySphereRadius = 500.f;

TArray<FGraspRequestResult> Results;
UGraspSubsystem::FindGraspables(this, Request, Results);

Use FindGraspable (singular) if you only need the closest match. It returns a single FGraspRequestResult.

Actor List Search

Use FindGraspablesInList when you already have a set of actors (e.g., from an EQS query or perception results) and want to check which ones have graspable components.

TArray<AActor*> PerceivedActors = GetPerceivedActors();
TArray<FGraspRequestResult> Results;
UGraspSubsystem::FindGraspablesInList(this, Filter, PerceivedActors, Results);

Targeting Request Search

Use FindGraspablesInTargetingRequest when working with UE's Targeting System. Pass the FTargetingRequestHandle from a completed targeting request.

Single Actor Search

Use FindGraspablesOnActor to find all graspable components on a specific actor. Useful when you know which actor to interact with but need to enumerate its interaction points.

Filtering

FGraspRequestFilter controls which results pass through.

Property Type Purpose
TagRequirements FGameplayTagQuery Match against UGraspData::InputTag. Leave empty to match all.
GraspDataClass TSubclassOf<UGraspData> Only return graspables using this data class (or subclass).
bIncludeDead bool Include graspables reporting IsGraspableDead() == true. Default: false.
bIncludeWithoutAbility bool Include graspables with no GraspAbility set. Default: false.

Request Types

FGraspRequest

Combines a spatial query volume with a filter.

Property Type Purpose
QueryBox FBox Search volume when bUseSphere is false.
QuerySphereCenter FVector Center of sphere search when bUseSphere is true.
QuerySphereRadius float Radius of sphere search when bUseSphere is true.
bUseSphere bool Toggle between box and sphere query shapes.
Filter FGraspRequestFilter Filtering criteria (see above).

FGraspRequestResult

A single search result.

Property Type Purpose
GraspableComponent TWeakObjectPtr<UPrimitiveComponent> The found component implementing IGraspableComponent.
GraspDataIndex int32 Index into the component's GraspDataEntries that matched the filter.
Distance float Distance from the query origin to this component.

Note

Results are sorted by distance (closest first)
A single graspable component can appear multiple times if it has multiple GraspData entries that pass the filter

Collision Setup

The subsystem uses the project's Grasp collision channel for overlap queries. This is configured in UGraspDeveloper settings:

  • Profile mode (default): Uses the configured collision profile
  • ObjectType mode: Uses the configured object type (defaults to ECC_GameTraceChannel4 for the Grasp channel)

Your graspable components must have collision responses set up to overlap with the Grasp channel for the subsystem to find them. This is the same collision setup required for the existing Grasp scan system.

AI Integration Example

A behavior tree or state tree task can use the subsystem to find nearby interactables:

void UMyBTTask::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
    APawn* Pawn = OwnerComp.GetAIOwner()->GetPawn();
    
    FGraspRequest Request;
    Request.bUseSphere = true;
    Request.QuerySphereCenter = Pawn->GetActorLocation();
    Request.QuerySphereRadius = SearchRadius;
    
    // Only find interactables tagged for sitting
    Request.Filter.TagRequirements = FGameplayTagQuery::MakeQuery_MatchTag(SitTag);
    
    FGraspRequestResult Result = UGraspSubsystem::FindGraspable(Pawn, Request);
    if (Result.IsValid())
    {
        // Found a graspable - proceed with interaction
    }
}

Clone this wiki locally