Unity Unet 从玩家动作中调整同步变量? - 我究竟做错了什么?
Unity Unet Adjusting a syncvar from a player action? - What am i doing wrong?
我正在尝试一些应该非常简单的事情,因为它应该在游戏中经常发生。我允许玩家在世界中生成立方体,然后当玩家点击立方体时,立方体的文本值(和关联的 syncvar 计数器)会发生变化。
但是,这仅在从 server/client 组合尝试时有效。我究竟做错了什么?找不到这方面的教程让我大吃一惊,因为它在游戏中似乎无处不在。
SpawnCube.cs(附在每个玩家身上)
if (Input.GetKeyDown (KeyCode.Mouse1)) {
RaycastHit hit;
if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 1000f, layers)) {
SpawnedCubeController scc = hit.collider.gameObject.GetComponent<SpawnedCubeController>();
if (scc != null) {
print ("HIT A CUBE");
scc.CmdAdjustCounter (1);
} else {
Vector3 hitPos = new Vector3(hit.point.x, hit.point.y + .5f, hit.point.z);
Quaternion look = Quaternion.LookRotation(hitPos - this.transform.position);
CmdSpawnCube(hitPos, look);
}
}
}
然后肉在 SpawnedCubeController.cs 中,它附在生成的立方体上。
public class SpawnedCubeController : NetworkBehaviour {
[SyncVar(hook = "OnChangeCounter")]
public int counter = 10;
private TextMeshProUGUI text;
public void OnChangeCounter(int newCount) {
if (text == null)
text = gameObject.GetComponentInChildren<TextMeshProUGUI> ();
text.text = "" + newCount;
}
[Command]
public void CmdAdjustCounter(int amount) {
this.counter -= amount;
if (this.counter <= 0) {
Destroy (this.gameObject);
}
if (isServer)
RpcUpdateCounter (counter);
}
[ClientRpc]
public void RpcUpdateCounter (int amount) {
text.SetText ("" + amount);
}
在我的示例中,每个人都可以很好地生成和旋转立方体 - 但是我无法让每个人都能够执行命令。
我什至不认为 RpcUpdateCounter 是必要的,因为钩子应该管理这个?无论如何,在服务器以外的任何机器上单击多维数据集永远不会 运行 命令
谢谢!
这里的问题是您试图从未经授权的对象执行命令(我很确定如果您检查客户端上的控制台日志,则在您启动命令时会出现警告)。
默认情况下,您的场景中唯一具有权限的对象是您的玩家游戏对象,因此命令功能应该在它们上面。
另一种方法是在执行命令之前将权限授予多维数据集,并在他们完成操作后接管它。
给非玩家对象权限: https://unity3d.com/es/learn/tutorials/topics/multiplayer-networking/handling-non-player-objects
我正在尝试一些应该非常简单的事情,因为它应该在游戏中经常发生。我允许玩家在世界中生成立方体,然后当玩家点击立方体时,立方体的文本值(和关联的 syncvar 计数器)会发生变化。
但是,这仅在从 server/client 组合尝试时有效。我究竟做错了什么?找不到这方面的教程让我大吃一惊,因为它在游戏中似乎无处不在。
SpawnCube.cs(附在每个玩家身上)
if (Input.GetKeyDown (KeyCode.Mouse1)) {
RaycastHit hit;
if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 1000f, layers)) {
SpawnedCubeController scc = hit.collider.gameObject.GetComponent<SpawnedCubeController>();
if (scc != null) {
print ("HIT A CUBE");
scc.CmdAdjustCounter (1);
} else {
Vector3 hitPos = new Vector3(hit.point.x, hit.point.y + .5f, hit.point.z);
Quaternion look = Quaternion.LookRotation(hitPos - this.transform.position);
CmdSpawnCube(hitPos, look);
}
}
}
然后肉在 SpawnedCubeController.cs 中,它附在生成的立方体上。
public class SpawnedCubeController : NetworkBehaviour {
[SyncVar(hook = "OnChangeCounter")]
public int counter = 10;
private TextMeshProUGUI text;
public void OnChangeCounter(int newCount) {
if (text == null)
text = gameObject.GetComponentInChildren<TextMeshProUGUI> ();
text.text = "" + newCount;
}
[Command]
public void CmdAdjustCounter(int amount) {
this.counter -= amount;
if (this.counter <= 0) {
Destroy (this.gameObject);
}
if (isServer)
RpcUpdateCounter (counter);
}
[ClientRpc]
public void RpcUpdateCounter (int amount) {
text.SetText ("" + amount);
}
在我的示例中,每个人都可以很好地生成和旋转立方体 - 但是我无法让每个人都能够执行命令。
我什至不认为 RpcUpdateCounter 是必要的,因为钩子应该管理这个?无论如何,在服务器以外的任何机器上单击多维数据集永远不会 运行 命令
谢谢!
这里的问题是您试图从未经授权的对象执行命令(我很确定如果您检查客户端上的控制台日志,则在您启动命令时会出现警告)。
默认情况下,您的场景中唯一具有权限的对象是您的玩家游戏对象,因此命令功能应该在它们上面。
另一种方法是在执行命令之前将权限授予多维数据集,并在他们完成操作后接管它。
给非玩家对象权限: https://unity3d.com/es/learn/tutorials/topics/multiplayer-networking/handling-non-player-objects