在我的棋盘游戏中,得分是投掷7个贝壳cowry shell来给出的。这些壳被放到Unity中的一个球体上,因此它们会随机滚动到不同的位置。 rigidbody.isSleeping()
返回true后,我将进行一次Raycast(从腹部向下),以弄清外壳的方向。如果不是命中对象,我们就会知道贝壳的腹部朝上,这意味着一点。
在单人游戏模式下,一切都很好,而且非常现实。原因是我只是激活了贝壳的重力,然后它们掉到了球体上,随机滚动,停下来时,我得到了如上所述的痕迹。
现在的问题是我正在制作多人游戏。在这种情况下,我从服务器发送了随机生成的标记,客户端将必须对外壳进行动画处理以表示标记。例如,如果服务器在7个炮弹中发送了3个,则3个炮弹的腹部应该朝上。
尝试这样做一直是我的主要问题。当速度降低时,我尝试transform.Rotate()
,但是速度不是很可靠,有时表现得很疯狂。在rigidbody.isSleeping()
之后旋转是可行的,但是非常不现实。
我知道我想在这里违抗物理学,但是也许有一些方法可以以最小的人工效果实现我想要的。
我实际上需要一些想法。
更新-1
在收到以下信息后,我确实找到了一些信息here,some advanced stuff here。由于后一个链接包含一些高级内容,因此我想从小处入手。因此,我遵循了第一个链接并进行了以下测试。
我在启用自动仿真的情况下记录了贝壳的位置,旋转和速度,并将它们记录到文件中。然后,我将Physics.Simulate()用于相同的情况并记录了相同的情况。
将两者进行比较可知,两种情况下的数据都是相似的。因此,对于我的需求而言,我似乎需要模拟贝壳掉落,然后将该序列应用于实际对象。
现在我的问题是如何将physics.simulate()结果(位置,旋转,速度等)的结果应用于实际的贝壳,以便可以看到动画。如果在仿真循环中将位置设置为游戏对象,则不会发生任何事情。
public void Simulate()
{
rbdy = GetComponent<Rigidbody>();
rbdy.AddForce(new Vector3(0f, 0f, 10f));
rbdy.useGravity = true;
rbdy.mass = 1f;
//Simulate where it will be in 5 seconds
int i = 0;
while (simulateTime >= Time.fixedDeltaTime)
{
simulateTime -= Time.fixedDeltaTime;
Debug.Log($"position: {rbdy.position.ToString()} rotation: {rbdy.rotation.ToString()} Velocity {rbdy.velocity.magnitude}");
gameObject.transform.position = rbdy.position;
Physics.Simulate(Time.fixedDeltaTime);
}
}
那么,如何将模拟数据应用于场景中的实际游戏对象?
答案 0 :(得分:1)
假设物理是确定性的,只需设置速度和位置并让其在每个客户端上模拟。输出应该相同。如果输出的差异很小,则可以对其进行调整,并且可能几乎不会引起注意。
Physics.simulate可能很有趣,即使与您想要的相反。
您可以实时或使用physics.simulate(请参阅第2点)将客户端record the steps投掷到客户端,然后以二进制格式传输动画数据-然后在其他客户端中使用它来播放动画。