【问题标题】:Calculating/Predicting a way计算/预测方式
【发布时间】:2014-03-25 19:55:10
【问题描述】:

我刚开始学习物理,所以我并不总是确定自己在做什么。这是一个 2D 项目,但我使用的是 SphereCollider 等 3D 物理对象。

我有什么:

物体漂浮在空间中并通过重力相互影响:

protected virtual IEnumerator OnTriggerStay(Collider other) {
    yield return new WaitForFixedUpdate();

    if(other.attachedRigidbody) {
        Vector3 offsetVector = this.transform.position - other.transform.position;
        float distance = offsetVector.magnitude;
        float gravityForce = (other.rigidbody.mass * mass) / Mathf.Pow(distance, 2);
        // Clamp gravity.
        if(gravityForce > 1.0F) {
            gravityForce = 1.0F;
        }
        other.attachedRigidbody.constantForce.force = offsetVector.normalized * gravityForce;
    }
}

有一些可控制的物体,玩家可以在这些物体上点击并拖动一条线离开物体,以便给它一个相反方向的力(射击)。

我想要达到的目标:

玩家在瞄准时应该能看到大致的预测路线。这意味着路径预测需要考虑当前速度、玩家释放鼠标按钮时施加的力以及周围物体的重力。

到目前为止我所做的尝试:

出于测试目的,我只是将计算/预测的位置保存在一个数组中,然后在 OnDrawGizmos() 中绘制这些位置。

我写了一个方法,它返回某个位置的重力影响,称为 computeGravityForPosition(Vector3 position)。

这就是我尝试计算位置的方式:

private void drawWayPrediction() {
    Vector3 pos = this.transform.position;
    // The offsetVector for the shooting action.
    Vector3 forceVector = pos - Camera.main.ScreenToWorldPoint(Input.mousePosition);
    forceVector.z = 0.0F;

    // The predicted momentum scaled up to increase the strength.
    Vector3 force = (forceVector.normalized * forceVector.magnitude);

    // 1. I guess that this is wrong, but don't know how to do it properly.
    momentum = this.rigidbody.velocity + force;

    for(int i = 0; i < predictionPoints.Length; i++) {
        float t = i * Time.fixedDeltaTime;
        momentum += computeGravityForPosition(pos);
        pos += momentum * t * t;
        predictionPoints[i] = pos;
    }
}

一开始,当物体慢慢靠近时,看起来还不错。在第一枪之后,预测完全错误。我想这是因为 1. 在代码中。仅仅在速度上增加力可能是可怕的错误。

非常感谢您的宝贵时间。

编辑:

我删除了看似不必要的部分。

我仍然认为主要问题在于 1. 在代码中。我只是不知道如何将物体的当前运动(据我所知统一的物理引擎,我只有当前的速度)与新创建的力混合起来:

Vector3 forceVector = pos - Camera.main.ScreenToWorldPoint(Input.mousePosition); Vector3 force = (forceVector.normalized * forceVector.magnitude);

【问题讨论】:

    标签: c# unity3d physics game-physics


    【解决方案1】:

    所以如果你使用的是可能在 2018 年以上的新版本的 unity,你可以使用 nice 方法

    Physics.Simulate(dt); // delta time, dt, is the amount of time to simulate.
    

    通过使用此功能,您可以手动推进模拟。 这种方法应该应用于不同的物理场景。 因此我建议,当您单击时,您将模拟一些物理步骤(您模拟的越多,玩家将获得的指示越准确), 每一步都存储对象的位置,并在完成模拟后在所有点之间画一条线。 在我看来,如果操作正确,它应该会运行得非常快。

    代码应如下所示:

    public PhysicsScene physicsScene;
    
    GameObject actualBall;
    GameObject simulatedBall;
    
    OnClick() {
        simulatedBall.SetPosition(actualBall.transform.position);
    
        if (!physicsScene.IsValid())
            return; // do nothing if the physics Scene is not valid.
    
    
        for (int i=0; i < 10; i++) {
            physicsScene.Simulate(Time.fixedDeltaTime);
            // store the position.
            myPoints.append(simulatedBall.rb.position);
        }
    
        // draw a line from the stored points.
    
    } 
    

    另外还有这个视频,希望对你有帮助,祝你好运 https://www.youtube.com/watch?v=GLu1T5Y2SSc

    我希望我回答了你的问题,如果没有,请告诉我:)

    【讨论】:

      【解决方案2】:

      免责声明:不幸的是,我的数学很烂,所以无法提供任何计算代码。

      现在法律的东西已经不碍事了:)

      在我看来,您对这一切的看法都是错误的。您需要计算曲线(对象轨迹的路径),然后使用线渲染器在 OnDrawGizmos 中简单地绘制曲线。

      您不需要模拟对象的行为。这不仅速度更快,而且在 TimeScale 恶作剧方面也更简单。通过更改 TimeScale,您还会影响轨迹模拟的 TimeScale,这很可能看起来和感觉很奇怪。

      通过进行基本的轨迹计算,您将不会遇到此问题。

      PS:这个link 可能会有所帮助。

      【讨论】:

      • 太空中有几个物体会根据质量和距离或多或少地影响可射击的身体。所以我不确定是否有一种简单的方法可以通过简单的弹道学计算路径。通过更改 TimeScale,我不会影响轨迹计算的速度。我通过使用 Debug.Log(Time.DeltaTime); 检查了这一点。将位置保存在数组中仅用于测试目的。稍后我可以将其更改为每次更新调用仅计算一个时间步长,这样就足够快了。
      • 我认为同样的逻辑也适用。您可以考虑对对象的其他影响。当然,就像你说的,根据你的具体要求,它可能会变得很丑。
      猜你喜欢
      • 2017-06-07
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      • 2022-01-04
      • 2018-09-29
      • 2012-03-13
      • 2012-07-10
      • 2020-03-18
      相关资源
      最近更新 更多