【问题标题】:Physics.Simulate every framePhysics.模拟每一帧
【发布时间】:2019-07-17 12:20:50
【问题描述】:

我有一个游戏对象,当玩家选择力和方向时,会使用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;
}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    通常您应该在FixedUpdate 中执行与Physics 引擎(也包括RigidBody)相关的所有事情,或者因为您使用IEnumerator 使用yield return new WaitForFixedUpdate(); - 每帧基础。

    物理更新不是在每帧的基础上而是在固定的时间间隔(因此是“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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 2017-11-07
      • 2013-07-15
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      相关资源
      最近更新 更多