更好的掷骰子方式
A better way to roll dice
我有一款游戏要求玩家掷两个骰子。由于这是一个多人游戏,我目前这样做的方式是有 6 个动画(每个骰子的结果有 1 个)。当玩家点击一个按钮时,它会向我的服务器代码发送一个请求。我的服务器代码确定骰子的结果并将结果发送给客户端。然后客户端播放相应的动画。
这工作正常,但有一些问题。例如,如果服务器发回两个相同的值(例如两个 6),则动画无法正常工作。由于两个动画相同,它们相互重叠,看起来就像只掷了一个骰子。
有更好的方法吗?使用 "real" 骰子而不是动画?如果是这样的话,我总是需要确保在服务器上 "pre-determine" 掷骰子的结果。我还需要确保骰子不会从 table 上掉下来或撞到棋盘上的任何其他玩家棋子。
感谢任何想法。
您可以在服务器上模拟物理,在动画期间跟踪骰子的位置和方向,然后将数据发送到客户端。我知道如此简单的事情需要大量数据,但这是让滚动看起来逼真并在所有客户端之间同步的一种方法。
如果 Unity 的物理是确定性的,那会容易得多。
服务器只需要关心数值结果,不需要运行物理计算
设置12种不同的滚动动画:
- 第一个骰子六颗
- 第二颗骰子六颗
每个人都应该始终以相同的模型面朝上结束(开始位置不相关,只有结束位置)。对于后面的步骤,您可能需要调整模型的 UV 坐标以使用非常高或非常宽的纹理(或只是正方形的一部分)。所以 不是 like this 而是全部在 1-2-3-4-5-6 行中。
下一步是选择要播放的随机动画。您已经获得 运行 给定动画的代码,只需将其设置为随机选择,而不是基于服务器的掷骰值:
int animNum = Mathf.Floor(Random.Next()*6);
最后,有趣的一点。调整纹理,以便在动画完成时显示 所需的面孔 。我假设你沿着方形纹理的顶部边缘排列你的脸。 Material.SetTextureOffset().
int showFace = Mathf.Floor(Random.Next()*6); //this value should come from the server
die.renderer.material.SetTextureOffset(1f/6 * showFace,0);
这将设置纹理偏移,使所需的面显示在顶部。您甚至可以在检查器中看到它的变化。由于 UV 的排列使得每个面都使用下一个块,并且因为纹理在到达边缘时会环绕(除非纹理在其导入设置中设置为 Clamp:您不希望在此处设置)。
请注意,这将导致实例化一个新的 material 实例(性能不是很好)。如果您想避免这种情况,则必须改用 a material property block。
我有一款游戏要求玩家掷两个骰子。由于这是一个多人游戏,我目前这样做的方式是有 6 个动画(每个骰子的结果有 1 个)。当玩家点击一个按钮时,它会向我的服务器代码发送一个请求。我的服务器代码确定骰子的结果并将结果发送给客户端。然后客户端播放相应的动画。
这工作正常,但有一些问题。例如,如果服务器发回两个相同的值(例如两个 6),则动画无法正常工作。由于两个动画相同,它们相互重叠,看起来就像只掷了一个骰子。
有更好的方法吗?使用 "real" 骰子而不是动画?如果是这样的话,我总是需要确保在服务器上 "pre-determine" 掷骰子的结果。我还需要确保骰子不会从 table 上掉下来或撞到棋盘上的任何其他玩家棋子。
感谢任何想法。
您可以在服务器上模拟物理,在动画期间跟踪骰子的位置和方向,然后将数据发送到客户端。我知道如此简单的事情需要大量数据,但这是让滚动看起来逼真并在所有客户端之间同步的一种方法。
如果 Unity 的物理是确定性的,那会容易得多。
服务器只需要关心数值结果,不需要运行物理计算
设置12种不同的滚动动画:
- 第一个骰子六颗
- 第二颗骰子六颗
每个人都应该始终以相同的模型面朝上结束(开始位置不相关,只有结束位置)。对于后面的步骤,您可能需要调整模型的 UV 坐标以使用非常高或非常宽的纹理(或只是正方形的一部分)。所以 不是 like this 而是全部在 1-2-3-4-5-6 行中。
下一步是选择要播放的随机动画。您已经获得 运行 给定动画的代码,只需将其设置为随机选择,而不是基于服务器的掷骰值:
int animNum = Mathf.Floor(Random.Next()*6);
最后,有趣的一点。调整纹理,以便在动画完成时显示 所需的面孔 。我假设你沿着方形纹理的顶部边缘排列你的脸。 Material.SetTextureOffset().
int showFace = Mathf.Floor(Random.Next()*6); //this value should come from the server
die.renderer.material.SetTextureOffset(1f/6 * showFace,0);
这将设置纹理偏移,使所需的面显示在顶部。您甚至可以在检查器中看到它的变化。由于 UV 的排列使得每个面都使用下一个块,并且因为纹理在到达边缘时会环绕(除非纹理在其导入设置中设置为 Clamp:您不希望在此处设置)。
请注意,这将导致实例化一个新的 material 实例(性能不是很好)。如果您想避免这种情况,则必须改用 a material property block。