Non-host client doesn't seem to have authority when running Command
I'm working on a multiplayer shooter and when spawning a bullet from a client that isn't a host, I get the "Trying to send a command from an object with no authority" warning. Here's all the related code:
PlayerController.cs:
using UnityEngine;
using System.Collections;
using System;
using UnityEngine.Networking;
public class PlayerController : NetworkBehaviour
{
[SerializeField]
private float Speed;
public bool OnGamepad = false;
public bool OnPrimary = true;
private Vector3 MoveData = Vector3.zero;
private Rigidbody PlayerRB;
public Camera PlayerCam;
public Transform gunOrigin;
public CombatItem Primary;
public CombatItem Secondary;
void Start()
{
PlayerRB = GetComponent<Rigidbody>();
PlayerCam = Instantiate(PlayerCam, transform.position, transform.rotation) as Camera;
PlayerCam.GetComponent<CameraControl>().target = transform;
PlayerCam.transform.parent = transform.parent;
}
void FixedUpdate ()
{
gameObject.SetActive(true);
checkConrolMethod();
Move();
if (OnPrimary && Primary != null) Action1(Primary);
else if(!OnPrimary && Secondary != null) Action1(Secondary);
if (OnGamepad)
{
GamepadRotate();
}
else
{
Rotate();
}
}
void Move()
{
float x = Input.GetAxisRaw("Horizontal");
float z = Input.GetAxisRaw("Vertical");
MoveData.Set(x, 0f, z);
MoveData = MoveData.normalized * Speed;
PlayerRB.MovePosition(PlayerRB.position + MoveData * Time.deltaTime);
}
void Rotate()
{
Ray camRay = PlayerCam.ScreenPointToRay(Input.mousePosition);
Plane floor = new Plane(Vector3.up, Vector3.zero);
float rayL;
if (floor.Raycast(camRay, out rayL))
{
Vector3 lookPoint = camRay.GetPoint(rayL);
transform.LookAt(new Vector3(lookPoint.x, transform.position.y, lookPoint.z));
}
}
void GamepadRotate()
{
Vector3 direction = Vector3.right * Input.GetAxisRaw("GPLookHorizontal")
+ Vector3.forward * -Input.GetAxisRaw("GPLookVertical");
if(direction.sqrMagnitude > 0.0f)
{
transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
}
}
void checkConrolMethod()
{
if (Input.GetJoystickNames().Length != 0)
OnGamepad = true;
if (Input.GetAxisRaw("Fire") != 0
|| Input.GetAxisRaw("Mouse X") != 0
|| Input.GetAxisRaw("Mouse X") != 0)
OnGamepad = false;
}
void OnCollisionEnter(Collision c)
{
if(c.gameObject.tag == "Bullet")
{
transform.position = new Vector3(0, transform.position.y, 0);
}
else if(c.gameObject.tag == "CombatItem")
{
PickUp(c.gameObject);
}
}
void PickUp(GameObject g)
{
g.transform.parent = transform;
g.transform.position = gunOrigin.transform.position;
g.transform.rotation = gunOrigin.transform.rotation;
CombatItem c = g.GetComponent<CombatItem>();
c.equiped = true;
if (OnPrimary)
{
if (Primary != null)
{
Drop(Primary.gameObject);
}
Primary = c;
}
else
{
Drop(Secondary.gameObject);
Secondary = c;
}
}
void Drop(GameObject g)
{
g.transform.parent = null;
if (OnPrimary) Primary = null;
else Secondary = null;
}
void Action1(CombatItem c)
{
if (Input.GetAxisRaw("Fire") != 0 || Input.GetAxisRaw("GPFire") == -1) c.Action1(true);
else c.Action1(false);
c.CmdNetProjectile();
}
void OnDestroy()
{
PlayerCam.GetComponent<CameraControl>().enabled = false;
Drop(Primary.gameObject);
Drop(Secondary.gameObject);
}
}
GunController.cs:
using UnityEngine;
using System.Collections;
using System;
using UnityEngine.Networking;
public class GunController : CombatItem
{
[SerializeField]
public Transform Origin;
[SerializeField]
GameObject Bullet;
public GameObject ToSpawn;
float ROFCountDown;
float TimeBetweenShots;
public float RateOfFire;
bool SingleShot;
bool IsFiring;
void Start()
{
TimeBetweenShots = 60 / RateOfFire;
}
void Update()
{
ToSpawn = Fire();
}
public GameObject Fire()
{
ROFCountDown -= Time.deltaTime;
if (IsFiring)
{
if (ROFCountDown <= 0)
{
ROFCountDown = TimeBetweenShots;
return Bullet;
}
return null;
}
return null;
}
public override void CmdNetProjectile()
{
if (ToSpawn != null)
{
GameObject projectile = Instantiate(ToSpawn, Origin.position, Origin.rotation) as GameObject;
NetworkServer.SpawnWithClientAuthority(projectile, connectionToClient);
}
}
public override void Action1(bool on)
{
IsFiring = on;
}
public override void Action2(bool on)
{
}
}
CombatItem.cs:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class CombatItem : NetworkBehaviour
{
public bool equiped = false;
public virtual void Action1(bool on){}
public virtual void Action2(bool on){}
[Command]
public virtual void CmdNetProjectile(){}
}
The code above spawns the bullets of the gun properly only on host. If you connect as a client, it tells me that the object doesn't have authority. The thing is that the command it self is sent from the player prefab, which should have authority, and yet it doesn't for some reason. The setup is proper, the bullet is registered in the network prefabs, the player prefab is setup, the PlayerController script is on the player prefab and the command is being sent from there.
Your answer
Follow this Question
Related Questions
Spawning a gun for a client doesn't work 0 Answers
Projectile not rendering for client when moving too fast 0 Answers
Unet NetworkServer.spawn, correcting my workflow: Found no behaviour for incoming Command 1 Answer
Spawning GameObject on network, locally change it only on the client that spawned it. 0 Answers
Client Spawning Player Objects 0 Answers