我想在玩家按下按钮时,以固定的速度在固定的时间内移动一个刚体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并得到一致的结果,这个问题就会得到解决)。
请原谅我的新手,我正在努力学习:)
先谢谢你
添加评论
Unity是一个游戏引擎。所有的游戏引擎都是基于 循环游戏 - 然而Unity在某种程度上向你隐藏了如果,在3个更新功能的背后。
并非所有的部分都同样重要。当GPU还没有准备好或者FPS达到上限时,绘图通常会被跳过。而Drawing和Physics一般是相互独立计算的(除非你真的把开发搞乱了)。
对于物理和动画,你一般希望东西与游戏Tick Counter一致。不 实时。所有游戏棋子的移动和所有的动画都应该以游戏ticks来计算。实时是一个很好的数字,但是ticks的处理时间会有很大的不同。尤其是CPU端绘图工作也要在同一个线程中运行。
只要算出你的最大tickssecond就可以了。如果你想运行的东西要运行 "大概 "10 ingame秒,你就乘以这个值。这台机器上的游戏是需要2秒200个tick还是2分钟200个tick并不重要--有了tick的数量,结果就会一致(除非数学本身不精确,比如浮点数学)。
如果是 不 在多人游戏中,它不一定要防黑客攻击,因此最简单的解决方法是捕捉按下按钮的第一帧,然后只在该帧上施加力,因此我们必须在更新函数中捕捉输入,并在那里静静地施加力,尽管建议在固定更新中做物理学的东西,但如果你在更新函数中使用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!