Unity 球在移动时摇晃

Unity Ball Shaking as it moves

我有一个球类游戏对象,我正在使用明确的物理方程使其反弹。我尝试使用 unity 的物理引擎,但不够精确。我像这样设置球的位置:

float dTime = Time.time - timeSinceBounce;
 ballPosition.x -= meterOffset / sensitivity;
 ballPosition.y = ballInitialPosition.y + GameConstants.Instance.GetBallYVel ()
 * dTime - (float)0.5 * GameConstants.Instance.GetGravity () * dTime * dTime; //Yi+Vy*t-0.5(G)(time^2)
 ballPosition.z = (-dTime * GameConstants.Instance.GetBallZVel ()
 + ballInitialPosition.z) * startConstant; //Zi + t*Vz
 ball.transform.position = ballPosition;

此代码在 Update() 方法中运行。当检测到碰撞时,重置时间和初始位置,这有效。目前,球可以正常弹跳,但在快速移动时会摇晃。 FPS 为 80。我认为我的方程式没有错,因为它正确地弹跳,只是摇晃了一下。去除抖动的最佳方法是什么?谢谢!

编辑 1:我决定编写自己的物理引擎,因为 Unity 的物理引擎有很多其他组件,例如摩擦和滚动,它们使球的弹跳发生变化。相机的 x 和 y 也是固定的,唯一改变的是相机的 z 位置。 固定更新效果更好

根据提问者的要求,我特此添加所有可能的细节,即使没有看到实际的、完整的和完整的代码以及看到这个 "shake" 效果,也很难给出准确和正确的答案。不过,我会尽力而为。

所以让我们开始吧。
1. "Shaking" 原因:很可能你设置了某种动画,以及强制 positioning/rotation/etc 并且这两个代码相互抵触。当您从 Unity UI 进行测试时,请仔细检查您的 AnimatorController and Animator as well as your Mecanim if you have set/configure these (also a good read: "Locomotion").
You can also keep the Animator Window 打开情况,看看是谁在为您执行 "shaking" 效果,并进一步了解它发生的原因。
如果这些没有帮助,请从头开始:最小化您为移动球而编写的代码,删除所有效果等,然后将它们一一添加回来。 "shakieness" 迟早会回来(如果它坚持使用尽可能干净的代码,请参见上文,Animator/Locomotion 问题)

2.再想想不重写Unity Physics ...你提到的例子
"...物理引擎有很多其他因素,如使球的弹跳发生变化的摩擦和滚动..."。
现在,您可以将其关闭。如果你愿意,完全可以。最简单的方法是在 Physics Material (i.e. friction and bouncieness) but if you want Unity to ignore all and every "actual physics" and let you do what you want with your GameObject, tick in the isKinematic property of the Rigidbody. The fun part of it, you'll still collide if and where you want, can AddForce, etc yet neither gravity nor friction or "anything physical" affect you.
If you are not comfy with Unity (and you are not it seems), I highly recommend learning about it a bit first as it is a very good and very powerful engine - so don't throw it's features away as they don't work as you initially expected they'll do. For example, Sebastian Lague 几周前刚刚开始一个很棒的初学者系列时将所有内容都设置为零。这个人是老师,他的视频很短,很有趣,而且信息量很大,所以我可以推荐他的频道。

3. 根据您的代码,我将进行以下更改:

public static class GameConstants { //no monobehaviour == can be a "proper, global" singleton!
   public static float GetGravity {
      get { return [whatever you want]; }
      //why not Physics.gravity, using locally when and where it's needed?
   }
   //etc, add your methods, properties and such
   //use this approach if and only IF you access these values application wide!
   //otherwise, instead of a """singleton""" logic you just implemented,
   //consider adding an empty GameObject to the Scene, name it "GM" and
   //attach a "GameManager" script to it, having all the methods and
   //properties you'll need Scene-wide! You can also consider
   //using PlayerPrefs (see help link below) instead of a global static
   //class, so you save memory (but will need to "reach out" for the data)
}<br>
private void FixedUpdate() { //FIXED update as you'll work with physics!
//float dTime = Time.time - timeSinceBounce; //not needed
//positioning like this is not recommended, use AddForce or set direction and velocity instead
 ballPosition.x -= meterOffset / sensitivity; 
 ballPosition.y = ballInitialPosition.y + GameConstants.Instance.GetBallYVel ()
 * Time.fixedDeltaTime - 0.5f * GameConstants.Instance.GetGravity () * Time.fixedDeltaTime * Time.fixedDeltaTime; //Yi+Vy*t-0.5(G)(time^2)
 ballPosition.z = (-dTime * GameConstants.Instance.GetBallZVel ()
 + ballInitialPosition.z) * startConstant; //Zi + t*Vz
 ball.transform.position = ballPosition;
}
但是老实说,

我会扔掉那些代码,实施 Unity 教程提供的 Bouncing Ball 示例,更改它(参见第 2 点)并从那里开始工作。

项目未链接但我在代码中提到: PlayerPrefs, Physics.gravity and Rigidbody.velocity.
注意 'velocity' 忽略了物理的一部分(加速,成为 "dragged" 等),即物体突然开始以您设置的速度移动(这就是为什么 Unity5建议改用 AddForce - 上面链接 -)

它也可能派上用场,您可以通过 Time Management 更改 FixedUpdate() 频率,但我不确定是否需要这样做(即仅用于弹跳球)

我希望这对您有所帮助,并且那个球会弹跳、跳跃和跳舞以及您希望它做的一切;)
干杯!