Open
Description
The problem: Change ownership of physic gameobject makes it goes back and forth on its path.
Unity_8iJhOKEsLu.mp4
the client that lose the ownership see this bug
I think because when he lose the ownership the other client become authoritative and send him the old position value
Request:
I would like that changing ownership would work out of the box
Describe alternatives you've considered
I tried syncing position and velocity throught networkvariable, OnLostOwnership
and OnGainedOwnership
callbacks, rpcs
without good results
Current Implementation:
current logic NetPhysicBall:
private void Update()
{
if (IsOwner && !_isChangingOwnership)
{
float distanceToLocal = Vector3.Distance(transform.position, localTransform.position);
float distanceToEnemy = Vector3.Distance(transform.position, enemyTransform.position) + 2f;
// se la palla è dall'altra parte del campo di questo client
if (distanceToEnemy < distanceToLocal)
{
Debug.Log(
$"NetPhysicBall::Change Ownership: {gameObject.name} => {(IsServer ? 1 : 0)}, currentPos={transform.position}, currentVelocity={rb.velocity}");
_isChangingOwnership = true;
ChangeOwnershipServerRpc(rb.position, rb.velocity);
}
}
}
[ServerRpc]
private void ChangeOwnershipServerRpc(Vector3 pos, Vector3 vel)
{
ChangeOwnershipClientRpc(pos, vel);
}
[ClientRpc]
private void ChangeOwnershipClientRpc(Vector3 pos, Vector3 vel)
{
Debug.Log(
$"NetPhysicBall::ChangeOwnershipClientRpc: {gameObject.name} {!IsOwner}, pos={pos}, realPos={rb.position}, vel={vel}, realVel={rb.velocity}");
_velocity = vel;
_position = pos;
Debug.DrawLine(pos, pos + vel * 0.2f, Color.yellow, 2f, false);
Debug.DrawLine(pos, pos + vel * 0.1f, Color.red, 2f, false);
// se sono il server aggiungo logica di cambio ownership
if (IsServer)
{
// se sono il server, ma non l'owner imposto il prossimo owner con il mio Id
ulong clientId = IsOwner
? ((MultiGameManager)(ServerGameManager.Instance)).enemyClientId
: NetworkManager.LocalClientId;
Debug.Log($"Server NetPhysicBall::ChangeOwnershipClientRpc: {gameObject.name} => {clientId}");
NetworkObject.ChangeOwnership(clientId);
}
}
public override void OnLostOwnership()
{
Debug.Log($"NetPhysicBall::OnLostOwnership: {gameObject.name}");
_isChangingOwnership = false;
}
public override void OnGainedOwnership()
{
if (!IsOwner)
{
// devo uscire perchè l'host riceve questa callback anche quando non è lui il nuovo owner
return;
}
Debug.Log($"NetPhysicBall::OnGainedOwnership: {gameObject.name}");
rb.velocity = _velocity;
}