-
Notifications
You must be signed in to change notification settings - Fork 5
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
Socketable breaks when rapidly socketed on client #9
Comments
Fixed it, would be great if you could implement this: using FishNet.Connection;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
public class NetworkGrabbable : NetworkBehaviour
{
[SerializeField]
private bool initializeUnparented = true;
private HVRGrabbable hvrGrabbable;
private Rigidbody rb;
private bool isSocketed;
[SyncVar(WritePermissions = WritePermission.ServerOnly)]
private int socketId = -1;
private object socketLock = new object();
private void Awake()
{
if (initializeUnparented)
{
transform.SetParent(null);
}
rb = GetComponent<Rigidbody>();
hvrGrabbable = GetComponent<HVRGrabbable>();
hvrGrabbable.Grabbed.AddListener(OnGrabbed);
hvrGrabbable.Socketed.AddListener(OnSocketed);
hvrGrabbable.UnSocketed.AddListener(OnUnSocketed);
}
private void OnDestroy()
{
hvrGrabbable.Grabbed.RemoveListener(OnGrabbed);
hvrGrabbable.Socketed.RemoveListener(OnSocketed);
hvrGrabbable.UnSocketed.RemoveListener(OnUnSocketed);
}
//------------------------------------- HVR Event Listeners -----------------------------------------
private void OnGrabbed(HVRGrabberBase grabber, HVRGrabbable grabbable)
{
if (grabber.IsSocket) return;
lock (socketLock)
{
if (socketId > 0)
{
RPCUnSocket();
isSocketed = false;
}
else
{
RPCSendTakeover();
}
if (rb)
{
rb.isKinematic = false;
}
}
}
private void OnSocketed(HVRSocket socket, HVRGrabbable grabbable)
{
lock (socketLock)
{
if (Owner.IsLocalClient && !isSocketed)
{
var id = 0;
if (socket.TryGetComponent<NetworkObject>(out var networkObject))
{
id = networkObject.ObjectId;
}
else
{
Debug.LogWarning("Socket does not have a network object");
}
RPCSocket(id);
isSocketed = true;
Debug.Log("Client tells server to socket", gameObject);
}
}
}
private void OnUnSocketed(HVRSocket socket, HVRGrabbable grabbable)
{
lock (socketLock)
{
if (socketId > 0)
{
RPCUnSocket();
Debug.Log("Client tells server to unsocket", gameObject);
isSocketed = false;
}
}
}
//------------------------------------- Server Functions -----------------------------------------
public override void OnStartServer()
{
ServerManager.Objects.OnPreDestroyClientObjects += OnPreDestroyClientObjects;
if (hvrGrabbable.StartingSocket != null)
{
if (hvrGrabbable.StartingSocket.TryGetComponent<NetworkObject>(out var networkObject))
{
socketId = networkObject.ObjectId;
TrySocket(socketId);
if (!hvrGrabbable.LinkStartingSocket)
{
if (!Owner.IsHost)
{
hvrGrabbable.StartingSocket = null;
}
}
}
else
{
Debug.LogWarning("Socket does not have a network object");
}
}
}
public override void OnStopServer()
{
ServerManager.Objects.OnPreDestroyClientObjects -= OnPreDestroyClientObjects;
}
private void OnPreDestroyClientObjects(NetworkConnection conn)
{
if (conn == Owner)
RemoveOwnership();
}
[ServerRpc(RequireOwnership = false)]
public void RPCSendTakeover(NetworkConnection conn = null)
{
if (Owner.ClientId == conn.ClientId) return;
NetworkObject.GiveOwnership(conn);
Debug.Log("Server Grants Ownership to " + conn.ClientId, gameObject);
}
[ServerRpc(RequireOwnership = true)]
public void RPCSocket(int _socketId)
{
lock (socketLock)
{
if (!isSocketed)
{
socketId = _socketId;
ObserversSocketedGrabbable(socketId);
isSocketed = true;
Debug.Log("RPC Socketing called with socket ID: " + socketId);
}
}
}
[ServerRpc(RequireOwnership = false)]
public void RPCUnSocket(NetworkConnection conn = null)
{
lock (socketLock)
{
if (socketId > 0)
{
socketId = -1;
if (Owner.ClientId != conn.ClientId) NetworkObject.GiveOwnership(conn);
ObserversUnSocketedGrabbable();
Debug.Log("RPC Unsocketing");
isSocketed = false;
}
if (rb == null)
{
rb = GetComponent<Rigidbody>();
}
if (!Owner.IsValid && rb != null)
{
rb.isKinematic = false;
Debug.Log("Server is owner");
}
}
}
public override void OnOwnershipServer(NetworkConnection prevOwner)
{
base.OnOwnershipServer(prevOwner);
if (rb == null) return;
if (!Owner.IsValid || Owner.IsLocalClient)
{
if (socketId > 0)
{
rb.isKinematic = true;
}
else
{
// This line is commented to avoid conflicts when client hosted
// rb.isKinematic = false;
}
}
else
{
rb.isKinematic = true;
}
}
//------------------------------------- Client Functions -----------------------------------------
public override void OnStartClient()
{
base.OnStartClient();
if (Owner.IsLocalClient)
{
if (hvrGrabbable.StartingSocket)
{
isSocketed = true;
hvrGrabbable.StartingSocket.TryGrab(hvrGrabbable, true, true);
}
return;
}
if (socketId > 0)
{
TrySocket(socketId, true);
}
else if (hvrGrabbable.IsSocketed)
{
TryUnSocket();
if (hvrGrabbable.StartingSocket != null && !hvrGrabbable.LinkStartingSocket)
{
hvrGrabbable.StartingSocket = null;
}
}
}
[ObserversRpc(ExcludeOwner = true, ExcludeServer = false)]
public void ObserversSocketedGrabbable(int _socketId)
{
TrySocket(_socketId);
}
private void TrySocket(int _socketId, bool ignoreGrabSound = false)
{
lock (socketLock)
{
if (_socketId <= 0)
{
Debug.Log("Tried to socket invalid id", gameObject);
return;
}
if (isSocketed) return;
var netObjects = FindObjectsOfType<NetworkObject>(true);
foreach (var netObj in netObjects)
{
if (netObj.ObjectId == _socketId)
{
if (netObj.TryGetComponent<HVRSocket>(out var socket))
{
if (rb != null)
{
if ((NetworkManager.IsHost && !Owner.IsValid) || Owner.IsLocalClient)
{
rb.isKinematic = false;
}
else
{
rb.isKinematic = true;
}
}
socket.TryGrab(hvrGrabbable, true, ignoreGrabSound);
if (rb != null) rb.isKinematic = true;
Debug.Log("Socketed on client", gameObject);
break;
}
}
}
isSocketed = true;
}
}
[ObserversRpc(ExcludeOwner = true, ExcludeServer = false)]
public void ObserversUnSocketedGrabbable()
{
TryUnSocket();
}
private void TryUnSocket()
{
lock (socketLock)
{
if (rb == null)
{
rb = GetComponent<Rigidbody>();
}
if (!hvrGrabbable.IsHandGrabbed)
{
hvrGrabbable.ForceRelease();
Debug.Log("Unsocketed on client", gameObject);
}
hvrGrabbable.transform.SetParent(null);
Debug.Log("Unsocketing...");
isSocketed = false;
}
}
public override void OnOwnershipClient(NetworkConnection prevOwner)
{
base.OnOwnershipClient(prevOwner);
if (prevOwner == Owner) return;
if (rb)
{
if (((NetworkManager.IsHost && !Owner.IsValid) || Owner.IsLocalClient) && !isSocketed)
{
rb.isKinematic = false;
}
else
{
rb.isKinematic = true;
}
}
}
} |
Thats great you found a solution! I will review and add your fixes in this weekend. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When I socket a network grabbable in quick succession, it breaks and the next time I socket it I have ownership a very short amount of time, and then immediatly loose ownership. When the host grabs the socketable and drops it again, the issue is fixed, until I spam socket the grabbable again.
The text was updated successfully, but these errors were encountered: