我正在研究和学习Unity 5,UNET和网络的一些基础知识.我制作了一个简单的3D游戏,你可以四处走动并改变物体的颜色.但我现在想让它成为多人游戏,而且我在如何通过网络发送更改方面遇到了很多麻烦,因此所有玩家都可以看到单个玩家的颜色变化.
部分问题是使用较新的UNET网络引擎很难找到答案.有时我会遇到旧方式的答案.
所以主要的问题是,如何联网非玩家GameObject属性的变化?颜色,形状,大小等.
这是我现在的一些代码 – 我有很多不同的版本,所以我只发布当前版本:
using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Player_Paint : NetworkBehavIoUr { private int range = 200; [SerializeField] private Transform camTransform; private RaycastHit hit; [SyncVar] private Color objectColor; [SyncVar] private GameObject objIdentity; void Update () { CheckIfPainting(); } void CheckIfPainting(){ if(Input.GetMouseButtonDown(0)) { if (Physics.Raycast (camTransform.TransformPoint (0,0.5f),camTransform.forward,out hit,range)) { string objName = hit.transform.name; CmdPaint(objName); } } } [ClientRpc] void RpcPaint(){ objIdentity.GetComponent<Renderer>().material.color = objectColor; } [Command] void CmdPaint(string name) { objIdentity = GameObject.Find (name); //tell us what was hit objectColor = new Color(Random.value,Random.value,Random.value); RpcPaint (); } }
我已经尝试了更多的解决方案,包括在我想要更改颜色的对象上编写单独的脚本,包括[SyncVar]和钩子函数.我也尝试过每一个我希望更新客户端上的对象的函数的Debug.Log,并且它们正在使用预期的数据执行.
我真的不知道还能做什么.我觉得这是一件非常简单的事情,但是我没有遇到任何问题,教程或其他资源中的非玩家GameObject的同步.任何想法都会有所帮助,谢谢.
解决方法
我找到了答案.这是非常困难的,因为几乎每一个问题,帖子,例子等……我都能找到关于玩家对象,而不是非玩家对象.
所以,我需要使用AssignClientAuthority函数.我曾尝试了几次,但没有正确使用它.以下是适用于播放器的正常运行的C#脚本:
using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Player_Paint : NetworkBehavIoUr { private int range = 200; [SerializeField] private Transform camTransform; private RaycastHit hit; [SyncVar] private Color objectColor; [SyncVar] private GameObject objectID; private NetworkIdentity objNetId; void Update () { // only do something if it is the local player doing it // so if player 1 does something,it will only be done on player 1's computer // but the networking scripts will make sure everyone else sees it if (isLocalPlayer) { CheckIfPainting (); } } void CheckIfPainting(){ // yes,isLocalPlayer is redundant here,because that is already checked before this function is called // if it's the local player and their mouse is down,then they are "painting" if(isLocalPlayer && Input.GetMouseButtonDown(0)) { // here is the actual "painting" code // "paint" if the Raycast hits something in it's range if (Physics.Raycast (camTransform.TransformPoint (0,range)) { objectID = GameObject.Find (hit.transform.name); // this gets the object that is hit objectColor = new Color(Random.value,Random.value); // I select the color here before doing anything else CmdPaint(objectID,objectColor); // carry out the "painting" command } } } [ClientRpc] void RpcPaint(GameObject obj,Color col){ obj.GetComponent<Renderer>().material.color = col; // this is the line that actually makes the change in color happen } [Command] void CmdPaint(GameObject obj,Color col) { objNetId = obj.GetComponent<NetworkIdentity> (); // get the object's network ID objNetId.AssignClientAuthority (connectionToClient); // assign authority to the player who is changing the color RpcPaint (obj,col); // usse a Client RPC function to "paint" the object on all clients objNetId.RemoveClientAuthority (connectionToClient); // remove the authority from the player who changed the color } }
!!!重要!!!
您想要影响的每个对象都必须具有NetworkIdentity组件,并且必须将其设置为LocalPlayerAuthority
因此,此脚本只是为了更改随机颜色,但您应该能够更改实际内容以将其应用于材质中的任何更改或您要与非玩家对象联网的任何其他内容. “应该”是最佳词 – 我还没有尝试过任何其他功能.