好的,所以我通过在胶囊中添加一个刚体元件来部分解决了这个问题。 我读了一个地方,显然你必须有一个为了移动服务器。
问题2
接下来的问题是,我现在可以移动一个由客户产生的胶囊,主机可以随意移动胶囊多次。 现在我得到的问题是,当主机产生一个胶囊客户端不能移动它,我得到了一种客户端故障的影响,胶囊仍然不会在主机端移动。 为什么只有一种方式,而不是相反呢? 我首先想到的可能是Spawn vs SpawnWithClientAuthority,但这似乎没有什么区别。
项目总结
我有一个非常简单的多人游戏项目,我想要做的只有一个玩家主机,另一个作为客户端join。 一旦它们结合在一起,两个玩家可以产生一个胶囊,然后当用户点击胶囊时。 他们应该能够把它拿起来,在场景中移动,另一个玩家应该能够看到这个动作。 我可以让两个玩家连接到服务器并产生他们自己的胶囊,双方玩家都可以看到。 移动脚本也完成了。 但是,它只在主机端传输。 当客户端拿起对象时,它不会在服务器上更新。
问题
我已经做了一些debugging,发现当我在客户端调用这个命令时,它根本不是通过换行符和简单的debugging语句来执行的。
码
public void OnInputClicked(InputClickedEventData eventData) { Debug.Log("clicked"); if (isLocalPlayer) { if (Physics.Raycast(transform.position, direction: transform.forward, hitInfo: out hit, maxDistance: range)) { Debug.Log("Hit capsule"); objectID = GameObject.Find(hit.transform.name); objNetId = objectID.GetComponent<NetworkIdentity>(); playerIDThatClicked = player.GetComponent<NetworkIdentity>(); CmdAssignAuthority(objNetId, playerIDThatClicked); Debug.Log("grabbed"); } else { //if we are releasing the object we want to unassign our authority if (objNetId != null) { CmdAssignAuthority(objNetId, playerIDThatClicked); objNetId = null; Debug.Log("released"); } } } } [Command] void CmdAssignAuthority(NetworkIdentity target, NetworkIdentity player) { Debug.Log("inside cmd"); current = target.clientAuthorityOwner; playerconn = player.connectionToClient; if (current != null && current != playerconn) { Debug.Log("Had authority now removing and replacing"); target.RemoveClientAuthority(current); target.AssignClientAuthority(playerconn); } else if (current != null) { Debug.Log("removing authority"); target.RemoveClientAuthority(current); } else if (current == null) { Debug.Log("No authority, adding one now"); target.AssignClientAuthority(playerconn); } else { Debug.Log("CmdAuthority error"); target.RemoveClientAuthority(playerconn); } }
题
我是否正确地调用这个命令? 该脚本附加到玩家预制件上,并且胶囊预制件包含networkingID和networking变换。 我对Unet来说很新,这感觉就像一个noob错误。
编辑:
如果你的对象有相同的名字,我可以看到GameObject.find(hit.transform.name)
给你的问题(改用hit.transform.gameObject
)
原始答案:
如果我正在读你的逻辑权限, CmdAssignAuthority
另一种写法如下:
if (current != null && current != connectionToClient)
将权限设置为connectionToClient
else if ( current == connectionToClient )
设置为null
(b / c current!= null意味着由于第一个if语句,它必须连接到客户端) else if ( current == null )
设置为connectionToClient
我不能完全确定你的OnInputClicked
多lessOnInputClicked
因为AR设备之间的差异,但我将假设像这样的video 。 OnInputClicked
的逻辑可以被编码为:
if ( click and raycast hit )
它会做这个对象的上述例程 if ( click and miss and cached hit object )
它将执行相同的例程 这个逻辑有一些潜在的错误:
connectionToClient
分配权限,所以主机客户端在点击的时候也会把权限分配给connectionToClient
,这也许就是为什么你永远不能在主机上移动它。 CmdAssignAuthority
,你的第一个if
捕获不应该发生,使更难阅读正在发生的事情。 它看起来像你的逻辑纠结在CmdSetAuthority
并且如果OnInputClicked
不是connectionToClient
,可能会在OnInputClicked
分解。 我建议重写你的逻辑,以便发送点击播放器的某种ID到CmdSetAuthority
而不是在null
和connectionToClient
之间切换