2
\$\begingroup\$

I'm doing a cooperation FPS game in which players can push big rigidbody cubes with their rigidbody characters (the one from the standard assets).

The problem is that the player hosting the game has authority on these cubes positions and so when the client tries to push them, he really struggles and the result is 100% disappointing.

So i'm searching a way to pass authority from the server to client and vice versa when the cube is touched by a player.

I'm using Unity 2018.2

Have a nice day.

\$\endgroup\$
0

2 Answers 2

2
\$\begingroup\$

And so here's the script I used to solve this problem. However, if both client and host are sending commands through the object, you'll have a problem when the client has authority. I'll try to solve this later.

public class CubeAuthority : NetworkBehaviour {

private void OnCollisionEnter(Collision collision)
{

    if (collision.transform.tag == "Player" && isServer)
    {
        CmdAssignNetworkAuthority(GetComponent<NetworkIdentity>(), collision.transform.GetComponent<NetworkIdentity>());
    }
}

[Command]
public void CmdAssignNetworkAuthority(NetworkIdentity cubeId, NetworkIdentity clientId)
{
    //If -> cube has a owner && owner isn't the actual owner
    if (cubeId.clientAuthorityOwner != null && cubeId.clientAuthorityOwner != clientId.connectionToClient)
    {
        // Remove authority
        cubeId.RemoveClientAuthority(cubeId.clientAuthorityOwner);
    }

    //If -> cube has no owner
    if (cubeId.clientAuthorityOwner == null)
    {
        // Add client as owner
        cubeId.AssignClientAuthority(clientId.connectionToClient);
    }
}
}
\$\endgroup\$
0
\$\begingroup\$

Probably this helps. Here's code I made, though I made it for a different purpose (changing owner of vehicle key in game) the key is clientauthority.

The player selects which vehicle's key to give away with selectkey() and transfers it with transferkey() which then invoke a method on raycastselect to get the key receiver player and transfers it to the givekey script.

    public class keyselector : NetworkBehaviour
    {
        public raycastselect rayselect;
        public Text keyname;
        int ind;
        NetworkIdentity currentkey;
        
        public void selectkey()
        {
            NetworkIdentity x = ClientScene.localPlayer;
            Cmdselectkey(x);
        }
        [Command]
        public void Cmdselectkey(NetworkIdentity x)
        {
            var y = new NetworkIdentity[x.connectionToClient.clientOwnedObjects.Count];
            (x.connectionToClient.clientOwnedObjects).CopyTo(y);
            Targetselectvehicle(y);
        }
        [TargetRpc]
        public void Targetselectvehicle(NetworkIdentity[] y) 
        { 
            ind += 1;
            if(ind >= y.Length)
            {
                ind = 0;
            }
            currentkey = y[ind];
            if(y.Length > 1)
            {
                if (y[ind] != ClientScene.localPlayer)
                {
                    keyname.text = y[ind].gameObject.name;
                }
                else
                {
                    keyname.text = "SELECT\nKEY";
                }
            }
            else
            {
                keyname.text = "U HAVE\nNO KEY";
            }
        }
        public void transferkey()
        {
            if(currentkey != null && currentkey != ClientScene.localPlayer)
            {
                rayselect.givekey(currentkey);
            }
        }
    }
    public class raycastselect : MonoBehaviour
    {
        public GameObject rider;
        public GameObject ramper;
        public GameObject key;
        public Text toride;
        public void go() 
        {
            RaycastHit trump;
            if (Physics.Raycast(transform.position, transform.forward, out trump))
            {
                enterexit stalin = trump.transform.GetComponent<enterexit>();
                if(stalin.player == null)
                {
                    stalin.player = transform.parent.gameObject;
                }
                if (trump.transform.GetComponent<crash>() && trump.transform.GetComponent<crash>().putin == null)
                {
                    trump.transform.GetComponent<crash>().putin = transform.parent.gameObject;
                }
                stalin.enter();
            }
        }
        public void givekey(NetworkIdentity vehicle)
        {
            RaycastHit trump;
            if (Physics.Raycast(transform.position, transform.forward, out trump))
            {
                GetComponentInParent<givekey>().Cmdchangeowner(vehicle, trump.transform.GetComponent<NetworkIdentity>());
            }
        }
        public void ramp()
        {
            RaycastHit trump;
            if (Physics.Raycast(transform.position, transform.forward, out trump))
            {
                ramp stalin = trump.transform.GetComponentInChildren<ramp>();
                stalin.door();
            }
        }
        private void Update()
        {
            RaycastHit trump;
            if (Physics.Raycast(transform.position, transform.forward, out trump))
            {
                if (trump.transform.GetComponentInChildren<enterexit>())
                {
                    rider.SetActive(true);
                    toride.text = trump.transform.gameObject.name;
                }
                else
                {
                    rider.SetActive(false);
                }
                if (trump.transform.GetComponentInChildren<ramp>())
                {
                    ramper.SetActive(true);
                }
                else
                {
                    ramper.SetActive(false);
                }
                if (trump.transform.GetComponentInChildren<raycastselect>())
                {
                    key.SetActive(true);
                }
                else
                {
                    key.SetActive(false);
                }
            }
            else
            {
                rider.SetActive(false);
                ramper.SetActive(false);
                key.SetActive(false);
            }
        }
    }
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Mirror;
    public class givekey : NetworkBehaviour
    {
        [Command]
        public void Cmdchangeowner(NetworkIdentity vehicle, NetworkIdentity player)
        {
            vehicle.RemoveClientAuthority();
            vehicle.AssignClientAuthority(player.connectionToClient);
        }
    }
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .