代码之家  ›  专栏  ›  技术社区  ›  Programmer

在x秒内预测刚体对象的位置

  •  4
  • Programmer  · 技术社区  · 9 年前

    Rigidbody Rigidbody.AddForce 或 Rigidbody.velocity

    Extrapolation 但在这种情况下,几乎不可能使用一些公式来获得物体在 x

    Physics.autoSimulation Physics.Simulate 来解决这个问题。对于2D物理,这是 Physics2D.autoSimulation 和 Physics2D.Simulate 若为false,则调用 物理。模拟 作用


    刚体 将在 4 1 5 更重要的是 Simulate 精确的太离谱了。

    为什么会发生这种情况,我该如何解决?这个问题在Android设备上更严重。

    Unity 2017.2.0b5

    下面是我正在使用的示例代码。这个 guide GameObject只是用来显示/显示预测的位置。

    public GameObject bulletPrefab;
    public float forceSpeed = 50;
    
    public GameObject guide;
    
    // Use this for initialization
    IEnumerator Start()
    {
        //Disable Physics AutoSimulation
        Physics.autoSimulation = false;
    
        //Wait for game to start in the editor before moving on(NOT NECESSARY)
        yield return new WaitForSeconds(1);
    
        //Instantiate Bullet
        GameObject obj = Instantiate(bulletPrefab);
    
        Rigidbody bulletRigidbody = obj.GetComponent<Rigidbody>();
    
        //Calcuate force speed. (Shoot towards the x + axis)
        Vector3 tempForce = bulletRigidbody.transform.right;
        tempForce.y += 0.4f;
        Vector3 force = tempForce * forceSpeed;
    
        //Addforce to the Bullet
        bulletRigidbody.AddForce(force, ForceMode.Impulse);
    
        //yield break;
        //Predict where the Rigidbody will be in 4 seconds
        Vector3 futurePos = predictRigidBodyPosInTime(bulletRigidbody, 4f);//1.3f
        //Show us where that would be
        guide.transform.position = futurePos;
    }
    
    Vector3 predictRigidBodyPosInTime(Rigidbody sourceRigidbody, float timeInSec)
    {
        //Get current Position
        Vector3 defaultPos = sourceRigidbody.position;
    
        Debug.Log("Predicting Future Pos from::: x " + defaultPos.x + " y:"
            + defaultPos.y + " z:" + defaultPos.z);
    
        //Simulate where it will be in x seconds
        Physics.Simulate(timeInSec);
    
        //Get future position
        Vector3 futurePos = sourceRigidbody.position;
    
        Debug.Log("DONE Predicting Future Pos::: x " + futurePos.x + " y:"
            + futurePos.y + " z:" + futurePos.z);
    
        //Re-enable Physics AutoSimulation and Reset position
        Physics.autoSimulation = true;
        sourceRigidbody.velocity = Vector3.zero;
        sourceRigidbody.useGravity = false;
        sourceRigidbody.position = defaultPos;
    
        return futurePos;
    }
    
    2 回复  |  直到 9 年前
        1
  •  4
  •   PassetCronUs    9 年前

    你甚至幸运地发现 1 根本不起作用。你 不应该 0.03 到 Physics.Simulate Physics2D.Simulate

    当该值高于 0.03 ,你必须把它切成碎片,然后使用 Simulate x 检查时间是否仍然大于或等于 Time.fixedDeltaTime 应该这样做。

    代替

    Physics.Simulate(timeInSec);
    

    具有

    while (timeInSec >= Time.fixedDeltaTime)
    {
        timeInSec -= Time.fixedDeltaTime;
        Physics.Simulate(Time.fixedDeltaTime);
    }
    

    predictRigidBodyPosInTime 函数应该如下所示:

    Vector3 predictRigidBodyPosInTime(Rigidbody sourceRigidbody, float timeInSec)
    {
        //Get current Position
        Vector3 defaultPos = sourceRigidbody.position;
    
        Debug.Log("Predicting Future Pos from::: x " + defaultPos.x + " y:"
            + defaultPos.y + " z:" + defaultPos.z);
    
        //Simulate where it will be in x seconds
        while (timeInSec >= Time.fixedDeltaTime)
        {
            timeInSec -= Time.fixedDeltaTime;
            Physics.Simulate(Time.fixedDeltaTime);
        }
    
        //Get future position
        Vector3 futurePos = sourceRigidbody.position;
    
        Debug.Log("DONE Predicting Future Pos::: x " + futurePos.x + " y:"
            + futurePos.y + " z:" + futurePos.z);
    
        //Re-enable Physics AutoSimulation and Reset position
        Physics.autoSimulation = true;
        sourceRigidbody.velocity = Vector3.zero;
        sourceRigidbody.useGravity = false;
        sourceRigidbody.position = defaultPos;
    
        return futurePos;
    }
    
        2
  •  0
  •   thatGuyDown    4 年前

    {
    Vector3 PredictionPos(Rigidbody _TargetRb, float _predictiontime){
    
    //get the rigidbodies velocity
    Vector3 _targvelocity = _TargetRB.velocity;
    //multiply it by the amount of seconds you want to see into the future
    _targvelocity *= _predictiontime;
    //add it to the rigidbodies position
    _targvelocity += _TargetRB.position;
    //Return the position of where the target will be in the amount of seconds you want to see into the future
    Return _targvelocity;
    }
    }