C# 澄清Update()和FixedUpdate()的用法?单位2d

C# 澄清Update()和FixedUpdate()的用法?单位2d,c#,unity3d,design-patterns,syntax,physics-engine,C#,Unity3d,Design Patterns,Syntax,Physics Engine,所以我知道FixedUpdate应该用于物理运算之类的,但我很难理解什么是物理。例如,我移动我的角色,通过观察按下的键,然后施加一个力。目前我正在Update()中执行此操作。由于addForce是应用于物理对象(播放器,因为它有刚体组件)的代码,是否应该将此功能移动到FixeUpdate() 但是,如果我将此代码移动到fixedUpdate(),在该方法中运行input.GetKey是否可以?我在某个地方读到,如果在FixedUpdate()中侦听输入,则输入可能会丢失?所以,是的,令人困惑…

所以我知道FixedUpdate应该用于物理运算之类的,但我很难理解什么是物理。例如,我移动我的角色,通过观察按下的键,然后施加一个力。目前我正在Update()中执行此操作。由于addForce是应用于物理对象(播放器,因为它有刚体组件)的代码,是否应该将此功能移动到FixeUpdate()

但是,如果我将此代码移动到fixedUpdate(),在该方法中运行input.GetKey是否可以?我在某个地方读到,如果在FixedUpdate()中侦听输入,则输入可能会丢失?所以,是的,令人困惑……听起来好像Input.GetKey应该在Update()中,当按下一个键时,一个标志被激活。同时,FixedUpdate()中的功能正在监视是否激活相应的标志。这样…这种方式在Update()中处理输入,在FixedUpdate()中处理移动…我理解的对吗


另外,我正在使用碰撞器和触发器,它们的代码是否也位于FixeUpdate()中?

如果没有好的资源,这是最难理解的事情之一。这通常是新Unity开发者代码中大多数“初学者bug”的原因

在我们开始之前: 正如您在文档中所读到的,您可以理解以下内容

初始化顺序:

  • 开始
  • 帧顺序:

  • 更新
  • 最新更新
  • 通过进入“编辑>项目设置>脚本执行顺序”,可以进一步自定义特定脚本的顺序(例如:始终在播放移动之前运行ScoreManager)

    然而,这并不是Unity中发生的事情的完整列表。物理循环、渲染和输入都是按此顺序在不同时间发生的。需要注意的关键是有两个脚本执行周期。“Frame”(最常见的-Update)和“Fixed”(最常见的-FixedUpdate)

    考虑一下粗略地看一眼

    有两个脚本执行周期意味着什么?简单地说,所有单行为方法都与这两个周期中的一个相关联。这些方法只执行一次逻辑,直到循环完成。换句话说,“PlayerMovement.cs”脚本的更新方法对于每一帧只运行一次。您的OnCollisionStay在每个固定循环中只运行一次

    为什么统一有两个不同的周期。 统一的固定周期(FixedUpdate)为:

    • 确定性
    • 基于数学的
    • 不依赖于渲染
    物理不需要渲染精灵或UI元素可见,就可以计算碰撞器是否被击中或是否应应用重力。Unity分离出特定于物理的数据,以便高效地执行计算。此外,这其中很多是确定性的。如果你在一帧上从(0,0)开始,在下一帧你的刚体移动到(10,10)(并且你没有传送),我可以合理地假设你通过点(5,5)。这使得Unity的物理引擎可以“插入”碰撞和相互作用。这意味着物理学不需要看到每一个“动作”的框架来确定是否发生了碰撞。固定循环允许Unity独立于框架计算物理,并安全地传达这些变化

    统一中的帧周期(更新)是所有统一交互的基础。没有更新游戏的框架,任何事情都不会发生。如果帧没有被更新,那么在计算游戏逻辑时浪费CPU周期是没有意义的。这意味着:

    • 输入绑定到框架
    • 帧周期取决于渲染
    需要注意的一点是:固定周期可能会出现,也可能不会出现在每一帧中。在较低的帧速率下,每帧可能发生多个固定周期。在较高的帧速率下,许多帧将在没有任何固定周期的情况下出现

    这对我的游戏逻辑意味着什么? 在大多数情况下,这两个周期的工作相当协调。引起关注的最常见原因如下:

    • 尝试使用变换物理(即刚体)更新游戏对象的位置。你应该尝试只在两个周期中的一个周期中更新游戏对象的位置。如果游戏对象预计会与物体碰撞或与重力等物理现象交互,请使用Rigidbody.move或Rigidbody.velocity

    • 尝试以固定周期读取输入。由于固定周期每帧可能发生0到多次,因此可能会丢失输入。如果在一个帧上使用GetButtonDown(),但FixedCycle未运行,则会在FixedUpdate中“丢失”该输入。通常最好使用布尔或队列来管理输入和物理系统之间的差异。(如在更新中设置bool jump=true,以及在实际执行物理组件时在FixedUpdate中读取/更新bool jump)


    碰撞器和触发器使用事件