Forum Discussion

lghna's avatar
lghna
Honored Guest
28 days ago
Solved

(Unreal Engine) Pinch doesn't work properly in multiplayer.

It's version 5.5.4 and sdk version is being developed as 78.0. 

I'm developing a case where 3 people multi-play, and different Pawn can be set up each player. 

For example, one person is DefaultPawn, the other is IsdkSamplePawn, IsdkSamplePawn2, and so on.

The two Pawn's are using hand-tracking.

The code link that I referenced to make different Pawn is like

https://unreal.gg-labs.com/wiki-archives/networking/spawn-different-pawns-for-players-in-multiplayer

and this is Unreal 4, so I modify the code to version 5. 

By the way, if the Player Controller class calls GameMode's RestartPlayer within DeterminePawnClass,

Pinch grab action does not work in handtracking.

I think it's a bug of RigComponent in InteractionSDK,

but I wonder if anyone has solved this problem.

  • I’ve been struggling for days with Pinch Grab not working in multiplayer using the Meta Interaction SDK (UE5).
    Palm Grab worked fine, but Pinch never fired on clients — even though single-player worked perfectly.

    After digging through the SDK source code, I finally found the root cause and a clean workaround.

    I’m sharing it here in case anyone else is fighting the same issue.

     

    I found it's not related to  GameMode's RestartPlayer function, it's just Meta InteractionSDK bug need to patch when multiplay

    First, I added InteractionSDK project codes into my plugins folder, so I can make break point and debug..

    In UIsdkHandRigComponent::BeginPlay(), the Interaction SDK tries to bind input actions: (it call parent UIsdkRigComponent::BeginPlay() function call, super::BeginPlay()),

    Inside UIsdkRigComponent::BeginPlay(), there is below codes,

    if (bAutoBindInputActions)
    {
        AActor* OwnerActor = GetOwner();
        OwnerActor->EnableInput(LocalPlayer);
        auto EnhancedInputComponent = OwnerActor->FindComponentByClass<UEnhancedInputComponent>();

        if (EnhancedInputComponent)
        {
            BindInputActions(EnhancedInputComponent);
        }

    ......

    }

    Single Play or Multiplay as ListenServer Play, it's okay, because the Pawn’s InputComponent has already been created before BeginPlay.
    But, Multiplay as Client, FindComponentByClass<UEnhancedInputComponent>() returns nullptr, So Pinch input actions never get bound on the client

    Maybe there are two to fix the problem, one is delay bind or check bind until find UEnhancedInputComponent

    I tested two ways, all make work in multiplay client pinch action

    As second way, I made a function like below 

    void UIsdkHandRigComponent::BindPinchInputActions()
    {
        APawn* OwnerPawn = Cast<APawn>(GetOwner());
        if (!OwnerPawn || !OwnerPawn->IsLocallyControlled())
            return;

        const auto FirstLocalPlayer = UGameplayStatics::GetPlayerController(this, 0);

        AActor* OwnerActor = GetOwner();
        OwnerActor->EnableInput(FirstLocalPlayer);
        const auto EnhancedInputComponent = OwnerActor->FindComponentByClass<UEnhancedInputComponent>();
        if (EnhancedInputComponent)
        {
            BindInputActions(EnhancedInputComponent);
        }
    }

    and I checked in TickCompoent function 

    void UIsdkHandRigComponent::TickComponent(
        float DeltaTime,
        ELevelTick TickType,
        FActorComponentTickFunction* ThisTickFunction)
    {
      Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

      if (IsPinchGrabBinded == false)
      {
          BindPinchInputActions();
      }

    (I added IsPinchGrabBinded = true; into BindPinchInputActions() function if bind successed)

    Pinch Grab failed in MP because Interaction SDK attempts to bind input in BeginPlay before the client creates its EnhancedInputComponent.
    Delaying or retrying the binding fixes it fully.

    Hopefully, this saves someone hours of debugging the Interaction SDK internals

     

2 Replies

  • lghna's avatar
    lghna
    Honored Guest

    I’ve been struggling for days with Pinch Grab not working in multiplayer using the Meta Interaction SDK (UE5).
    Palm Grab worked fine, but Pinch never fired on clients — even though single-player worked perfectly.

    After digging through the SDK source code, I finally found the root cause and a clean workaround.

    I’m sharing it here in case anyone else is fighting the same issue.

     

    I found it's not related to  GameMode's RestartPlayer function, it's just Meta InteractionSDK bug need to patch when multiplay

    First, I added InteractionSDK project codes into my plugins folder, so I can make break point and debug..

    In UIsdkHandRigComponent::BeginPlay(), the Interaction SDK tries to bind input actions: (it call parent UIsdkRigComponent::BeginPlay() function call, super::BeginPlay()),

    Inside UIsdkRigComponent::BeginPlay(), there is below codes,

    if (bAutoBindInputActions)
    {
        AActor* OwnerActor = GetOwner();
        OwnerActor->EnableInput(LocalPlayer);
        auto EnhancedInputComponent = OwnerActor->FindComponentByClass<UEnhancedInputComponent>();

        if (EnhancedInputComponent)
        {
            BindInputActions(EnhancedInputComponent);
        }

    ......

    }

    Single Play or Multiplay as ListenServer Play, it's okay, because the Pawn’s InputComponent has already been created before BeginPlay.
    But, Multiplay as Client, FindComponentByClass<UEnhancedInputComponent>() returns nullptr, So Pinch input actions never get bound on the client

    Maybe there are two to fix the problem, one is delay bind or check bind until find UEnhancedInputComponent

    I tested two ways, all make work in multiplay client pinch action

    As second way, I made a function like below 

    void UIsdkHandRigComponent::BindPinchInputActions()
    {
        APawn* OwnerPawn = Cast<APawn>(GetOwner());
        if (!OwnerPawn || !OwnerPawn->IsLocallyControlled())
            return;

        const auto FirstLocalPlayer = UGameplayStatics::GetPlayerController(this, 0);

        AActor* OwnerActor = GetOwner();
        OwnerActor->EnableInput(FirstLocalPlayer);
        const auto EnhancedInputComponent = OwnerActor->FindComponentByClass<UEnhancedInputComponent>();
        if (EnhancedInputComponent)
        {
            BindInputActions(EnhancedInputComponent);
        }
    }

    and I checked in TickCompoent function 

    void UIsdkHandRigComponent::TickComponent(
        float DeltaTime,
        ELevelTick TickType,
        FActorComponentTickFunction* ThisTickFunction)
    {
      Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

      if (IsPinchGrabBinded == false)
      {
          BindPinchInputActions();
      }

    (I added IsPinchGrabBinded = true; into BindPinchInputActions() function if bind successed)

    Pinch Grab failed in MP because Interaction SDK attempts to bind input in BeginPlay before the client creates its EnhancedInputComponent.
    Delaying or retrying the binding fixes it fully.

    Hopefully, this saves someone hours of debugging the Interaction SDK internals

     

  • Hey there lghna!

    I understand you're having trouble with the interaction SDK in UE. I'm not sure if you've seen our documentation, but we do have some resources that cover this topic and I can link them below. Regarding the interaction SDK, I will mention that UE has certain limitations as to which interactions are supported in UE vs Unity. I would highly suggest you check out our "Hands" documentation linked below that go over the limitations using UE and see if any of the limitations listed are the interactions you're using. 

    If you're still running into issues after checking out our documentation, we can explore some options that should hopefully point you in the right direction. Regarding your pawn and camera rig, are they scaled? It's possible that if they're scaled, the pinch offset is calculated incorrectly and might be set at the wrist. You could also try to implement your own pinch detection using the finger joint positions, and this might be what you want to try if all else fails as this option gives you more control over your pinch detection. 

    Lastly, I would suggest that you spawn the pawns carefully and try to avoid calling RestartPlayer inside DeterminePawnClass. It's a known issue that certain spawn logic can sometimes reset hand tracking state in multiplayer.

    Hopefully you found some of this helpful, and if not please feel free to let me know and we can investigate further!

    Getting Started with Interaction SDK for Unreal Engine
    Hands
    Setup Hand Tracking in Unreal Engine

    -G

→ Find helpful resources to begin your development journey in Getting Started

→ Get the latest information about HorizonOS development in News & Announcements.

→ Access Start program mentor videos and share knowledge, tutorials, and videos in Community Resources.

→ Get support or provide help in Questions & Discussions.

→ Show off your work in What I’m Building to get feedback and find playtesters.

→ Looking for documentation?  Developer Docs

→ Looking for account support?  Support Center

→ Looking for the previous forum?  Forum Archive

→ Looking to join the Start program? Apply here.

 

Recent Discussions