-
Notifications
You must be signed in to change notification settings - Fork 10
AI Support
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
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()
The subsystem provides several search methods depending on your use case.
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.
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);Use FindGraspablesInTargetingRequest when working with UE's Targeting System. Pass the FTargetingRequestHandle from a completed targeting request.
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.
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. |
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). |
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
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_GameTraceChannel4for 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.
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
}
}