内置游戏中的缓慢移动 - FixedUpdate 与 Update

Slow movement in built game - FixedUpdate vs Update

我注意到与在编辑器中的工作方式相比,测试构建的游戏速度明显变慢。

玩家移动:

public class PlayerScript : MonoBehaviour
{
    Vector3 objectSpeed;
    Rigidbody rigidBody;
    [SerializeField] float speed;
    [SerializeField] float maxSpeed;
    // Start is called before the first frame update
    void Start()
    {
        objectSpeed = gameObject.GetComponent<Rigidbody>().velocity;
        rigidBody = gameObject.GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
                objectSpeed = rigidBody.velocity;
        if (Input.GetKey("w"))
        {
            objectSpeed.z += speed;
        }
        if (Input.GetKey("s"))
        {
            objectSpeed.z -= speed;
        }
        if (Input.GetKey("a"))
        {
            objectSpeed.x -= speed;
        }
        if (Input.GetKey("d"))
        {
            objectSpeed.x += speed;
        }
        objectSpeed.x = Mathf.Clamp(objectSpeed.x, -maxSpeed, maxSpeed);
        objectSpeed.z = Mathf.Clamp(objectSpeed.z, -maxSpeed, maxSpeed);
        rigidBody.velocity = objectSpeed;
    }
}

构建过程中玩家的移动速度明显变慢。经过一番搜索,我发现了 FixedUpdate() 应该用于物理。将此代码移到那里后,构建中的玩家移动将按预期进行。

奇怪的是,敌人的移动在 Update()

中运行良好
public class EnemyScript : MonoBehaviour
{
    public GameObject player;
    Rigidbody enemyRigidbody;
    float zombieSpeed;

    // Start is called before the first frame update
    void Start()
    {
        player = GameObject.Find("Player(Clone)");
        enemyRigidbody = gameObject.GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 directionToPlayer = player.transform.position - transform.position;
        float distanceToPlayer = Mathf.Sqrt(
            Mathf.Pow(directionToPlayer.x, 2f) +
            Mathf.Pow(directionToPlayer.y, 2f) +
            Mathf.Pow(directionToPlayer.z, 2f));
        Vector3 movementVector = (1f / distanceToPlayer) * directionToPlayer * zombieSpeed;
        enemyRigidbody.velocity = movementVector;
    }
}

那么这是怎么回事?这与必须处理玩家移动的键盘输入有关吗?

TLDR;

FixedUpdate()运行s基于当前Time.timeScale,
Update()always 运行s 每帧一次。


FixedUpdate()总是运行s in-sync与physics-engine,它并不总是运行一次per-frame.
它可以 运行 多次 per-frame 或完全 none,具体取决于物理引擎。

出于优化目的,物理引擎 运行 相对于游戏的 time-scale 而不是 frame-rate。

如果游戏变慢时需要更精确的物理计算,请在编辑>项目设置>时间下减小Fixed TimeStep
不过可能会导致性能问题,因为您只是让物理引擎在一秒钟内进行更多计算。

If you do need help with optimizing, Unity has a documentation about it.


Update() 总是 运行 一次 per-frame.

有关更多详细信息,Unity 有一个 TimeFrameManagement documentation