摄像头下面的刚体抖动与背景物体每隔几秒钟

问题描述 投票:0回答:1

相机以下Rigidbody2D抖动背景(非刚体)每隔几秒钟的对象(障碍)。在探查的FPS是好的这是附近的100也插值也未尝不可。使用Unity 2017年4月12日(LTS)

GIF GIF Video here

相机跟踪脚本

 public class CameraFollow : MonoBehaviour {
        public float followRange = 0.5f;
        public float cameraZ;
        public Transform Player;
        public Vector3 newPos;
        void Start () {
            cameraZ = transform.position.z;
        }
        void FixedUpdate() {
            newPos = new Vector3(Player.position.x + followRange, 0, cameraZ);
            transform.position = Vector3.Lerp(transform.position, newPos, 0.5f);
        }   
    }

播放器脚本:

public class PlayerBall : MonoBehaviour {

    public float xSpeed = 10;

    // Update is called once per frame
    void FixedUpdate () {
        this.transform.position = new Vector3(this.transform.position.x + Time.fixedDeltaTime * xSpeed, 
            this.transform.position.y , transform.position.z);
    }

}

球员刚体

enter image description here

Project File Download

c# unity3d game-physics unity3d-2dtools
1个回答
1
投票

在该FixedUpdate被称为速率比其规定在该UpdateLateUpdate被称为速率帧速率不同。

FixedUpdate应该用于刚体上设置的速度。设置在FixedUpdate位置始终运行抖动的危险,因为它被称为不同步与你的帧速率。设置在模拟刚体位置也违背模拟它,你要重写任何影响物理学可能对刚体的点。

Manual page for Ridgidbody 2D还指出:

该刚体2D部件覆盖变换和它更新由刚体2D所限定的位置/旋转。请注意,虽然你仍然可以通过修改自己的变换组件(因为团结暴露在所有组件的所有属性)覆盖刚体2D,这样做将导致问题,如通过或进入对方GameObjects,和不可预测的运动。

[...]甲撞机2D绝不应直接使用变换或任何对撞机偏移移动;该刚体2D应改用移动。这提供了最佳的性能,确保正确的碰撞检测。

对于应需而动一个刚体,你必须使用Dynamic BodyTypeKinematic一个,这取决于你的用例之间的选择。如果你想在飞机上被其他非静态撞机推来推去,应该是动态的。如果它不应该被搬来搬去,它应该是动态(这也是更好的性能)。

用例1:动态刚体2D

这是你目前的设置。然而,Manual page for Ridgidbody 2D还指出:

不要使用变换组件设置一个动态刚体2D的位置或旋转。模拟重新定位一个动态刚体2D根据其速度;您可以通过通过脚本应用到它的力量,或者间接地通过碰撞和重力直接改变这一点。

所以,你应该改变播放器脚本使用Rigidbody2D方法AddForce

public class PlayerBall : MonoBehaviour {

  public float thrust = 10;
  Rigidbody2D body;
  Vector2 forwardDirection = Vector2.right;

  void Awake() {
    body = GetComponent<Ridigbody2d>();
  }

  // FixedUpdate is called once per physics update
  void FixedUpdate () {
    body.AddForce(forwardDirection * thrust)
  }

}

现在,这将只是不断力添加到面,向前推进并加速它。所以,你可能会希望当你接近目标速度想出一个办法通过降低添加力以稳定的速度(你可以检查与body.velocity.x当前速度),并通过平面减慢使用drag

我不会再进一步​​细谈,因为我怀疑运动实际上是你想要的内容:

用例2:运动刚体2D

设置为动态时Body Type甲Ridgedbody2D可以安全地与Ridgedbody2D部件MovePosition方法移动。因此,与设置,你是玩家脚本应该是这样的:公共类PlayerBall:MonoBehaviour {

  public float xSpeed = 10;
  Rigidbody2D body;
  Vector2 forwardDirection = Vector2.right;

  void Awake() {
    body = GetComponent<Ridigbody2d>();
  }

  // FixedUpdate is called once per physics update
  void FixedUpdate () {
    body.MovePosition(forwardDirection + xSpeed * Time.deltaTime)
  }

}

注:我使用Time.deltaTime这里是因为此属性的返回值将始终是正确的时间增量因为它是在使用更新方法的类型。

下列相机

更新相机的位置应始终与帧率同步。在FixedUpate这样做会导致口吃。相反,它应该在Update做或者(如果你想如等到由于动画位置的变化,你设定的位置之前应用)在LateUpdate

最后

如果在游戏中的炸弹也被移动,而且在位置在他们FixedUpate同样地更新Ridgidbodies,你应该改变他们作为在任的2用例描述使用的解决方案。

需要注意的是运动学刚体不会引起任何冲突事件(触发事件仍然引起的)如果你想同时移动炸弹和平面运动Ridigbodies但撞船事件仍然是原因,您可以设置Use Full Kinematic Contacts上应该接受这些的刚体更新。我不知道这是否会有任何性能影响(除了一个用于生成这些事件),你可能还需要阅读1 [中Ridigbody2D组件的完整文档。

总体TL; DR:你看到的很可能不是一个性能问题(或者它会在Profiler出现了,你必须飘飘和较差的FPS),但运动抖动由于使用了错误的更新方法和方案应用于运动到肉体。这是一个团结很常见的陷阱。

如果有性能问题,请附上分析器的屏幕截图。随着FPS的显示方法,你都在用,很可能你是触发GC.Collect的每隔一段时间在FPS脚本字符串操作(和其他地方GC.Allocs)。

© www.soinside.com 2019 - 2024. All rights reserved.