即使在使用FixedUpdate()或Time.DeltaTime()时,物理学也不一致。

问题描述 投票:0回答:2

我想在玩家按下按钮时,以固定的速度在固定的时间内移动一个刚体2D。我在FixedUpdate()中调用该方法,结果并不一致。有时刚体会移动得更多,有时会移动得更少(以下是我的代码的相关部分,我是如何做到这一点的)。

 void Update()
 {
     GetPlayerInput();
 }
 private void FixedUpdate()
 {
     GroundCheck();
     ApplayNormalPlayerMovement();
     ApplyMove(); // This is the method of interest - I tried calling this in Update() with Time.DeltaTime - still inconsistent results.
     MoveCooldownCounter(); // I tried calling this in Update() - inconsistent results also
 }
 IEnumerator MoveRB()
 {
     savedVelocityX = rb.velocity.x;
     rb.gravityScale = 0;
     savedXinput = xInput;
     while (moveTimer >= 0)
     {
         if (xInput != 0)
             xInput = 0;
         cc.sharedMaterial = noFriction;
         if (facingRight)
         {
             rb.velocity = new Vector2(moveSpeed, .0f); // I tried multiplying the moveSpeed by Time.DeltaTime and FixedDeltaTime - still inconsistent results.
         } else
         {
             rb.velocity = new Vector2(-moveSpeed, .0f);
         }
         moveTimer -= Time.fixedDeltaTime;
         yield return null;
     }
     moveTimer= moveDuration;
     rb.gravityScale = gravity;
     rb.velocity = new Vector2 (savedVelocityX, .0f);
     xInput = savedXinput;
     moveCooldownInternal -= Time.deltaTime; // I tried changing this to a specific float - still inconsistent results in physics..
 }
 private void MoveCooldownCounter()
 {
     if (moveCooldownInternal != moveCooldown)
     {
         moveCooldownInternal -= Time.deltaTime;
         if (moveCooldownInternal <= 0)
         {
             moveCooldownInternal = moveCooldown;
         }
         if (moveCooldownInternal == moveCooldown && isGrounded)
             canMove = true;
     }
 }
 private void ApplyMove()
 {
     if (b_Fire3 && canMove)
     {
         StartCoroutine("MoveRB");
         canMove= false;
     }
 }

附注:现在我有时会遇到玩家输入丢失的情况,因为我在FixedUpdate()中调用了这个ApplyMove()(将不得不找到一个变通的方法--自然如果我可以在Update()中调用ApplyMove并得到一致的结果,这个问题就会得到解决)。

请原谅我的新手,我正在努力学习:)

先谢谢你

添加评论

c# unity3d game-physics
2个回答
0
投票

Unity是一个游戏引擎。所有的游戏引擎都是基于 循环游戏 - 然而Unity在某种程度上向你隐藏了如果,在3个更新功能的背后。

并非所有的部分都同样重要。当GPU还没有准备好或者FPS达到上限时,绘图通常会被跳过。而Drawing和Physics一般是相互独立计算的(除非你真的把开发搞乱了)。

对于物理和动画,你一般希望东西与游戏Tick Counter一致。 实时。所有游戏棋子的移动和所有的动画都应该以游戏ticks来计算。实时是一个很好的数字,但是ticks的处理时间会有很大的不同。尤其是CPU端绘图工作也要在同一个线程中运行。

只要算出你的最大tickssecond就可以了。如果你想运行的东西要运行 "大概 "10 ingame秒,你就乘以这个值。这台机器上的游戏是需要2秒200个tick还是2分钟200个tick并不重要--有了tick的数量,结果就会一致(除非数学本身不精确,比如浮点数学)。


0
投票

如果是 在多人游戏中,它不一定要防黑客攻击,因此最简单的解决方法是捕捉按下按钮的第一帧,然后只在该帧上施加力,因此我们必须在更新函数中捕捉输入,并在那里静静地施加力,尽管建议在固定更新中做物理学的东西,但如果你在更新函数中使用delta时间来计算,应该是没有问题的!现在我想你知道如何做,但我写的是,无论如何,我们可以使用应用力或设置速度。

现在我想你知道怎么做了,但我还是要写出来,我们可以使用施力或设置速度。

void Update()
{
    if(Input.GetKeyDown("w"))
        rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y + 5f*Time.deltaTime);
}

注意:我没有测试过,但应该没问题,因为GetKeyDown只在按下按钮的第一帧时才返回true。 我没有测试,但应该没问题,因为GetKeyDown只在按钮被按下的第一帧返回true。

如果只是GetKey,在跳跃的情况下,我们会检查玩家的接地,我们可能在跳跃过程中,即使跳跃了,也会在第二格被接地,因为没有真正精确的地面检查。

PS.在游戏中使用fixedDeltaTime。在 fixedUpdate 方法中使用 fixedDeltaTime!

© www.soinside.com 2019 - 2024. All rights reserved.