物理.模拟每一帧



我有一个游戏对象,当玩家选择力和方向时,会使用physics.simulate绘制运动轨迹和结束位置的线。如果我每 0.5f 秒使用它一次,效果很好,但我必须预测每一帧的轨迹和结束位置,但这样游戏就会滞后。如何预测每帧的轨迹和结束位置?

private IEnumerator destcor()
{
    while (true)
    {
        yield return new WaitForSeconds(0.3f);
        touchhandler.listofcoll.Clear();
        touchhandler.force = (float)Math.Pow(distanceToRoller, 3);
        touchhandler.RollerMove();
        endpos = touchhandler.CheckPosition(rollerobj.GetComponent<Rigidbody>());
        destination.transform.position = endpos;
    }
}
public Vector3 CheckPosition(Rigidbody defaultRb)
{
    Physics.autoSimulation = false;
    defaultRb = GetComponent<Rigidbody>();
    Vector3 defaultPos = defaultRb.position;
    Quaternion defaultRot = defaultRb.rotation;
    float timeInSec = timeCheck;
    while (timeInSec >= Time.fixedDeltaTime)
    {
       timeInSec -= Time.fixedDeltaTime;
       Physics.Simulate(Time.fixedDeltaTime);
    }//end while
    Vector3 futurePos = defaultRb.position;
    Physics.autoSimulation = true;
    defaultRb.velocity = Vector3.zero;
    defaultRb.angularVelocity = Vector3.zero;
    defaultRb.transform.position = defaultPos;
    defaultRb.transform.rotation = defaultRot;
    return futurePos;
}

通常你应该在FixedUpdate中执行与Physics引擎相关的所有操作(所以也RigidBody(,或者因为你正在使用使用yield return new WaitForFixedUpdate();IEnumerator - 而不是在每个帧的基础上。

物理更新不是按帧完成,而是以固定的时间间隔(因此称为"FixedUpdate"(完成,这是有充分理由的:它通常有点耗时和资源密集。因此,为了避免巨大的滞后,您应该避免每帧都使用物理。

减慢速度的另一件事是重复拨打GetComponent电话。您应该只制作一次,稍后再重用引用:

private RigidBody rigidBody;
private void Awake()
{
    rigidBody = rollerobj.GetComponent<Rigidbody>();
}
private IEnumerator destcor()
{
    while (true)
    {
        yield return new WaitForFixedUpate();
        touchhandler.listofcoll.Clear();
        touchhandler.force = (float)Math.Pow(distanceToRoller, 3);
        touchhandler.RollerMove();
        endpos = touchhandler.CheckPosition(rigidBody);
        destination.transform.position = endpos;
    }
}

CheckPosition这条线

defaultRb = GetComponent<Rigidbody>();

没道理!您已经传入了有效的RigidBody引用,或者没有。所以在这里覆盖它似乎有点相反。

如果您想再次在这里进行一种回退,请在Awake中存储一次引用,然后重用它,例如

private RigidBody rigidBody;
private void Awake()
{
     rigidBody = rollerobj.GetComponent<Rigidbody>();
     // now add the fallback here already
     if(!rigidBody) rigidBody = GetComponent<RigidBody>();
     // or maybe you could even use
     //if(!rigidBody) rigidBody = GetComponentInChildren<RigidBody>(true);
     // in order to buble down the entire hierachy until a RigidBody is found
}

最新更新