计算/预测方式

时间:2014-02-24 08:53:33

标签: c# unity3d physics game-physics

我刚刚从物理学开始,所以我并不总是确定我在做什么。这是一个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);

2 个答案:

答案 0 :(得分:3)

因此,如果您使用的统一版本可能在2018年以上,则可以使用不错的方法

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

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

答案 1 :(得分:1)

免责声明:不幸的是,我在数学方面很糟糕,因此无法提供任何计算代码。

现在合法的东西已经不在了:)

在我看来,你看这一切都错了。您需要的是计算曲线(物体轨迹的路径),然后使用线渲染器在OnDrawGizmos中绘制曲线。

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

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

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