Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grab Sync on Multiplayer with Fusion 2 Host mode #92

Open
ramkeshcse084 opened this issue Nov 20, 2024 · 5 comments
Open

Grab Sync on Multiplayer with Fusion 2 Host mode #92

ramkeshcse084 opened this issue Nov 20, 2024 · 5 comments
Labels
stale Stale issue.

Comments

@ramkeshcse084
Copy link

Hello,

I have successfully implemented full-body Meta movement with locomotion in multiplayer using Photon Fusion 2 Host Mode, following your guidance. Currently, I am working on implementing grab functionality for multiplayer. While grabbing works fine locally, I am encountering an issue when trying to sync it in multiplayer: the grabbed object and hand get stuck at a specific point.

Could you please guide me on how to properly sync grabbing in multiplayer?

Thank You
Ramkesh Singh

@ramkeshcse084
Copy link
Author

I had added Network object and Network Transform with following script :
1.
using UnityEngine;
using Oculus.Interaction;

public class GrabInteraction : MonoBehaviour
{
private GrabSync grabSync;

public PointableUnityEventWrapper pointableEventWrapper;

private void Start()
{
    grabSync = GetComponent<GrabSync>();

    if (pointableEventWrapper != null)
    {
        // Subscribe to the select (grab) event
        pointableEventWrapper.WhenSelect.AddListener(OnObjectGrabbed);
        // Subscribe to the unselect (release) event
        pointableEventWrapper.WhenUnselect.AddListener(OnObjectReleased);
    }
    else
    {
        Debug.LogError("PointableUnityEventWrapper is not assigned!");
    }
}

private void OnObjectGrabbed(PointerEvent pointerEvent)
{
    Debug.Log("Object has been grabbed.");

    if (grabSync != null)
    {
        // Pass the Pose directly to GrabSync
        grabSync.OnGrab(pointerEvent.Pose);
    }
}




private void OnObjectReleased(PointerEvent pointerEvent)
{
    Debug.Log("Object has been released.");

    if (grabSync != null)
    {
        grabSync.OnRelease();
    }
}

}

2. using Fusion;
using Meta.XR.MultiplayerBlocks.Fusion;
using UnityEngine;

public class GrabSync : NetworkBehaviour
{
[Networked] public Vector3 Position { get; set; } = Vector3.zero; // Initialize position
[Networked] public Quaternion Rotation { get; set; } = Quaternion.identity; // Initialize rotation

private bool isGrabbed = false;
private TransferOwnershipFusion transferOwnership;
private Transform grabberHandTransform; // Reference to the grabbing hand or controller
private Vector3 localOffsetPosition;   // Offset between object and hand
private Quaternion localOffsetRotation; // Offset for rotation

private void Awake()
{
    transferOwnership = GetComponent<TransferOwnershipFusion>();
    if (transferOwnership == null)
    {
        Debug.LogError("TransferOwnershipFusion component not found on this object!");
    }
}

public override void Spawned()
{
    // Initialize position and rotation on spawn
    if (Object.HasStateAuthority)
    {
        Position = transform.position;
        Rotation = transform.rotation;
    }
}

public override void FixedUpdateNetwork()
{
    if (Object.HasStateAuthority && isGrabbed && grabberHandTransform != null)
    {
        // Maintain the object's position and rotation relative to the grabbing hand
        transform.position = grabberHandTransform.position + grabberHandTransform.rotation * localOffsetPosition;
        transform.rotation = grabberHandTransform.rotation * localOffsetRotation;

        // Update the networked state
        Position = transform.position;
        Rotation = transform.rotation;
    }
    else if (!Object.HasStateAuthority)
    {
        // Smoothly interpolate for non-authoritative clients
        transform.position = Vector3.Lerp(transform.position, Position, Runner.DeltaTime * 10f);
        transform.rotation = Quaternion.Slerp(transform.rotation, Rotation, Runner.DeltaTime * 10f);
    }
}

public void OnGrab(Pose grabPose)
{
    if (transferOwnership != null && !isGrabbed)
    {
        transferOwnership.TransferOwnershipToLocalPlayer();
        isGrabbed = true;

        // Use the Pose to set initial offsets
        localOffsetPosition = Quaternion.Inverse(grabPose.rotation) * (transform.position - grabPose.position);
        localOffsetRotation = Quaternion.Inverse(grabPose.rotation) * transform.rotation;

        Debug.Log($"Object grabbed by {Runner.LocalPlayer}");
    }
}

public void OnRelease()
{
    if (transferOwnership != null && isGrabbed)
    {
        isGrabbed = false;

        // Transfer state authority back to the host (server)
        if (Runner.IsServer)
        {
            Debug.Log("State authority remains with the server.");
        }
        else
        {
            Object.RequestStateAuthority(); // Server/host reclaims authority.
            Debug.Log("State authority returned to the host.");
        }

        // Clear the grabbing hand reference
        grabberHandTransform = null;

        Debug.Log("Object released");
    }
}

}
3.
/*

  • Copyright (c) Meta Platforms, Inc. and affiliates.
  • All rights reserved.
  • Licensed under the Oculus SDK License Agreement (the "License");
  • you may not use the Oculus SDK except in compliance with the License,
  • which is provided at the time of installation or download, or which
  • otherwise accompanies this software in either electronic or hard copy form.
  • You may obtain a copy of the License at
  • https://developer.oculus.com/licenses/oculussdk/
  • Unless required by applicable law or agreed to in writing, the Oculus SDK
  • distributed under the License is distributed on an "AS IS" BASIS,
  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • See the License for the specific language governing permissions and
  • limitations under the License.
    */

using Fusion;
using Meta.XR.MultiplayerBlocks.Shared;

namespace Meta.XR.MultiplayerBlocks.Fusion
{
///


/// The class responsible for the networking part of transferring ownership of a networked game object when using
/// the Photon Fusion networking framework. It implements the interface
/// and is used by which handles the non-networking logic.
///

public class TransferOwnershipFusion : NetworkBehaviour, ITransferOwnership
{
///
/// Transfers the ownership of the networked game object to the local player.
/// An implementation of the interface.
///

public void TransferOwnershipToLocalPlayer()
{
if (!HasStateAuthority)
{
Object.RequestStateAuthority();
}
}

    /// <summary>
    /// Indicates whether the local player has ownership of the networked game object.
    /// An implementation of the <see cref="ITransferOwnership"/> interface.
    /// </summary>
    /// <returns>'true' if the local player has ownership of the networked game object.</returns>
    public bool HasOwnership()
    {
        return HasStateAuthority;
    }
}

}

@sohailshafiiWk
Copy link
Contributor

Hello. It seems like you are having issues with the grab interactions and not the Movement SDK code or functions. This forum is specifically for the Movement SDK issues. Can you clarify the problem if you are having questions or issues with the Movement SDK?

@ramkeshcse084
Copy link
Author

Having trouble on network player grabbing . Can you please give general idea and concept what should i take care when synching grab on network ?
I implemented Multiplayer on meta movement by your advice .
Thank You

@sohailshafiiWk
Copy link
Contributor

We don’t have resources to debug issues not associated with the Movement SDK code like the grab interactions. If you think there are issues with the Movement SDK implementation, could you clarify how you think our example is contributing to the problem?

@sohailshafiiWk sohailshafiiWk added the stale Stale issue. label Jan 3, 2025
Copy link

github-actions bot commented Jan 3, 2025

This issue is stale because it has been open for 14 days with no activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale Stale issue.
Projects
None yet
Development

No branches or pull requests

2 participants