【问题标题】:How to decrease value of float over time in C#?如何在 C# 中随时间减少浮点值?
【发布时间】:2019-07-29 11:19:16
【问题描述】:

我正在 Unity 中构建一个游戏,其中我的角色在按下空格键时会滑动。他只能在跑步或冲刺时滑动。当玩家开始滑动时,玩家的速度应该会随着时间的推移而降低,这意味着他不能永远滑动或始终以相同的速度滑动。

我已经尝试做另一个具有恒定值的浮点数,并随着时间的推移(Time.deltaTime)随着该常数降低玩家速度。但是,它只将时间减少了一次,它需要每秒执行一次。

float playerSpeed=5.2f;

Update()
{
    if (Input.GetKey(KeyCode.Space) && (isRunning == true || isSprinting == 1))
    {
        isSliding = true;         
    }      
    else
    {
        isSliding = false;
    }
}

我预计玩家速度会在 2 秒内从 5.2 降至 0。

【问题讨论】:

  • 你能把减去播放器速度的代码也包括进去吗?
  • 短代码:isSliding = Input.GetKey(KeyCode.Space) && (isRunning || isSprinting == 1);
  • 只是一个建议,但我注意到您提到速度应该“每秒”减少。相反,我会在每个周期降低我的速度,在两秒的跨度内以百分比的形式将减速分散到 0。这将使幻灯片更加流畅。
  • 不应该名为 isSprinting 的属性/变量是布尔值吗?

标签: c# unity3d


【解决方案1】:

在修改了 phantasm 的答案后,我认为自己写一个更完整的答案可能会更好,即使它确实使用了该帖子中提到的概念。

您应该能够使用以下内容,对处于停止状态的精灵进行一些细微的修改,等等...这只是使用 Mathf.Lerp 概念的基础知识

private float playerSpeed = 5.2f;
private float slideDuration = 2.0f;
private float remainingSlideTime = 2.0f;

void update() {  
    bool isSliding = (Input.GetKey(KeyCode.Space) && (isRunning == true || isSprinting == 1));
    if(isSliding && remainingSlideTime > 0 && playerSpeed > 0) {
        remainingSlideTime -= Time.deltaTime;
        float speedReduction = playerSpeed * (Time.deltaTime/remainingSlideTime);
        playerSpeed = Mathf.Lerp(playerSpeed - speedReduction, 0, remainingSlideTime/slideDuration);
    }
}

当然,您不需要使用Mathf.Lerp 来完成您想要做的事情,在这种情况下,最好不要使用它...

private float playerSpeed = 5.2f;
private float slideDuration = 2.0f;
private float remainingSlideTime = 2.0f;

void update() {  
    bool isSliding = (Input.GetKey(KeyCode.Space) && (isRunning == true || isSprinting == 1));
    if(isSliding && remainingSlideTime > 0 && playerSpeed > 0) {
        remainingSlideTime -= Time.deltaTime;
        float speedReduction = playerSpeed * (Time.deltaTime/remainingSlideTime);
        playerSpeed = ((remainingSlideTime/slideDuration) > 0) ? playerSpeed - speedReduction : 0;
    }
}

【讨论】:

  • 这有效,非 Mathf.Lerp 解决方案有效。问题在我这边。在现有的 else 条件下,我还有 2 个 playerspeed 浮动冲突。我删除了它们以查看发生了什么并且它起作用了。谢谢大家的动力和非常好的建议!
【解决方案2】:

如果您想在条件为真时每秒/分钟/任何时间范围内执行某项操作,您可以查看How to damage a player after each seacond .. 这是我对另一个问题的回答的快速改编:

private float timeToDoStuff = 0.0f;
private float slidingDecrease = 0.0f;
void update() {  
    if (Input.GetKey(KeyCode.Space) && (isRunning == true || isSprinting == 1))
    {
        if(!isSliding) slidingDecrease = playerSpeed / 2;
        isSliding = true;         
    }      
    else
    {
        slidingDecrease = 0.0f;
        isSliding = false;
    }
    if(isSliding && Time.time >= timeToDoStuff) {
        playerSpeed -= slidingDecrease; // or whatever
        timeToDoStuff = Time.time + 1.0f; // for 1 seconds
    }
}

现在,当您仅每秒应用它时,它会在 2 秒内从 x 减少到 0。因此,如果您想将其减少 0.5 秒,您显然必须调整滑动减少的计算。

【讨论】:

  • 可能是我的错,但是当我执行此代码时,即使在玩数字时也没有任何反应。可能是其他影响这一点的变量。
  • @Mactadilis hm,可能是我在某个地方也犯了错误,因为我很快就适应了它。您可以尝试先使用一个固定值作为 slideingDecrease,然后添加一种动态计算它的方法
  • 现在我发现了冲突的变量,这也是一种几乎没有修改的工作方法。
【解决方案3】:

看看

float playerSpeed = 5.2f;
float slideTime = 2f;

/* ... game loop logic, etc... */

if(isSliding && playerSpeed > 0) {
    playerSpeed = Mathf.Lerp(5.2f, 0f,  slideTime);
}

/* ... more game loop logic ... */

编辑:

此函数在 ab 之间线性插值 t,其中 ab 是数字,t 是时间。请参考本文档:https://docs.unity3d.com/ScriptReference/Mathf.Lerp.html

【讨论】:

  • 这可能会为问题提供部分解决方案,但是如果您提供更多示例如何使用此功能,更多说明此功能的用法,将会更有帮助,最后还有一个参考页面的链接。
  • 这只是将玩家速度从 5.2 降低到 0。它并没有缓慢降低。另外,t 参数被限制在 0 和 1 之间,所以时间只能是最大 1,所以我从文档中得到。
  • @Mactadilis 您可能应该使用float 类型的timeRemainingInSlide 变量,您在每次迭代时将其递减Time.deltaTime,使用它来计算幻灯片中经过的时间百分比。这可以表示为 0 到 1 之间的值,四舍五入到最接近的第 10 位。另外,幻影建议的解决方案,我只是将其修改为使用他们发布的基本建议。在仍然使用Mathf.Lerp 方法的同时可以进行很多改进,这将使滑动停止更顺畅。
【解决方案4】:

我想对Mathf.Lerp方法做一些解释,
帮助有兴趣的人理解数学过程。

下面的脚本可以帮你搞清楚:

float start = 5.2f; // Could be any number.
float end = 0;  // Could be any number too.

float totalTime = 2; // The time it takes to transit from start to target.
float t; // The variable holding the current time passed.

void Update() {
    t += Time.deltaTime; 

    float T = t / totalTime; // The percentage of our "progress" towards totalTime.
    float currentFloat = Mathf.Lerp(start, end, T); 
    Debug.Log(currentFloat);
}

lerp的函数是:start + ((end - start) * T)
加上将您提供的 T 钳位在 0 和 1 之间。
所以我提供的值是:5.2 * (1 - T)

文档链接:https://docs.unity3d.com/ScriptReference/Mathf.Lerp.html

【讨论】:

    猜你喜欢
    • 2012-09-11
    • 2022-12-09
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 2017-12-17
    • 1970-01-01
    相关资源
    最近更新 更多