Unity - 客户端和服务器控制相同的Player对象

时间:2018-03-25 23:48:37

标签: unity3d

我正在编写一个简单的游戏,两个玩家控制一个角色,并且需要避免物体从屏幕顶部掉落。两个玩家控制相同的角色,因此一个玩家点击"左"应该导致其他玩家的屏幕上的角色向左移动。

我目前的尝试是让我在NetworkManager中的默认播放器预制件为空白,并让我的实际播放器对象成为背景的一部分。我遇到的问题是,当我尝试将位置从客户端发送到服务器时,我没有权限。我的运动类附在播放器上,位于下方。

public class PlayerMovement : NetworkBehaviour {

   public Button movementL, movementR;    
   public float speed;    
   private Rigidbody2D rigidbody2D;

   [SyncVar(hook = "OnChangeForce")]
   public Vector2 currentForce = new Vector2(0, 0);

    void Start () {
      rigidbody2D = GetComponent<Rigidbody2D>();

      Button tempL = movementL.GetComponent<Button>();
      tempL.onClick.AddListener(OnClickL);

      Button tempR = movementR.GetComponent<Button>();
      tempR.onClick.AddListener(OnClickR);
   }

   void OnChangeForce(Vector2 current)
   {
      rigidbody2D.AddForce(current);
   }

   void OnClickL()
   {
      if (isServer)
      {
         currentForce = new Vector2(0, 0);
         Vector2 move = new Vector2(-1, 0);
         currentForce += move * speed;
      } 
      else
      {
         GetComponent<NetworkIdentity>().AssignClientAuthority(GetComponent<NetworkIdentity>().connectionToClient);
         Debug.Log(hasAuthority);
         CmdOnClickL();
      }
   }

   void OnClickR()
   {
      if (isServer)
      {
         currentForce = new Vector2(0, 0);
         Vector2 move = new Vector2(1, 0);
         currentForce += move * speed;
      }
      else
      {
         CmdOnClickR();
      }
   }

   [Command]
   void CmdOnClickL()
   {
      OnClickL();
   }

   [Command]
   void CmdOnClickR()
   {
      OnClickR();
   }
}

1 个答案:

答案 0 :(得分:0)

在Unity Networking中,您有一个主客户端(同时是客户端+服务器)和另一个客户端,或者您有一个专用服务器+两个或更多客户端。具有服务器角色的人是拥有场景的人,因此是该场景中所有GameObjects的所有者,除非他们被专门分配给另一个玩家。

对于您设置为播放器预制件的对象已经完成,但正如您所说,您正试图在此场景中移动另一个对象。因为在您的情况下,这不是由服务器完成的,而是由客户端完成的,在实际属于服务器的对象上,您将获得Authority Exception。请记住,每个客户端只能操作实际属于它的对象上的变量。

最好的方法是将PlayerPrefab用于Player对象(因此它包含通过网络操纵的实际玩家对象),但您也可以尝试使用{{3}设置权限}。这样你就可以将对象的权限赋予它应该属于的玩家。

另一种方法可能是让服务器拥有所有游戏对象并仅向其发送玩家输入,因此服务器会移动所有游戏对象,但是这样你会放弃很多为你同步游戏对象的统一性。尽管如此,根据你的项目,它可能是值得的,因为你可以更好地控制一切。