unity3d - 如何增加一个数字但不是一次(使用 Unity 引擎)
问题描述
所以假设玩家有 100 金币,他们又得到了 100 金币,我不希望显示值立即从 100 变为 200,因为它不是很明显,而是希望显示在整个过程中从 100 变为 200说,半秒之类的,这可能吗?抱歉这个菜鸟问题,但我能想到的唯一方法是(可能)不必要的复杂 for 循环,必须有一种更有效的方法来做到这一点......谢谢!
解决方案
每当通过脚本更改金额时,您始终可以使用Coroutine将显示“淡化”为实际金额。协程(默认情况下)基本上是临时的小循环Update
。但在我看来,它们更好地控制和维护,有时更有效率。
public class GoldController : MonoBehaviour
{
// Reference the target Text component here via the Inspector
[SerializeField] private Text goldDisplay;
// How long it should take to fade the amount in the display
// Adjust this via the Inspector
[SerializeField] private float fadeDuration = 0.5f;
// Here you store the amount you are fading on
private float displayedGoldAmount;
// Here the amount is actually stored
private int actualGoldAmount;
// This stores the current fade routine
private Coroutine routine;
// Via this public property others can increase or decrease the amount
public int CurrentGoldAmount
{
get => actualGoldAmount;
set
{
actualGoldAmount = value;
// evtl stop an already running fade
if(routine != null) StopCoroutine(routine);
// Start a new fade
routine = StartCoroutine (FadeRoutine());
}
}
private IEnumerator FadeRoutine()
{
var current = displayedGoldAmount;
var target = actualGoldAmount;
var timePassed = 0f;
while(timePassed < fadeDuration)
{
// Get a linear growing factor between 0 and 1
// It will take fadeDuration seconds to reach 1
var factor = timePassed / fadeDuration;
// Optional easing towards beginning and end to make it a bit "smoother"
factor = Mathf.SmoothStep(0, 1, factor);
// Linear interpolate between the start and target value using the factor
displayedGoldAmount = Mathf.Lerp(current, target, factor);
// Update the display with the displayed amount
// using F0 displays it rounded to int
goldDisplay.text = displayedGoldAmount.ToText("F0");
// Increase by the time passed since last frame
timePassed += Time.deltaTime;
// Tell Unity to "pause" here, render this frame and
// continue from here in the next frame
yield return null;
}
// To be sure to end with the exact value set the target fix here
// This also covers the case for fadeDuration <= 0f
displayedGoldAmount = target;
goldDisplay.text = displayedGoldAmount.ToText("F0");
// If we achieve to reach this we don't need the reference anymore
routine = null;
}
}
反对Update
这里的好处是,如果您不更改数量,则不会使用任何资源来运行Update
-> 协程仅在必须时运行。
所以从另一个脚本你只需要做
theObject.GetComponent<GoldController>().CurrentGoldAmount = 100;
或者
theObject.GetComponent<GoldController>().CurrentGoldAmount += 200;
您当然可以使用适当的 setter 方法而不是属性,该方法首先检查是否有足够的黄金来花费等,但这取决于您;)
推荐阅读
- node.js - Node.js Mongo DB 查找查询工作异常
- python - 如何用 Pulp Python 模块解决这个 MILP 问题?
- icons - Kentico 管理页面中没有图标
- sql - Oracle - 这个查询可以优化吗?
- python - 使用 Django 和 AJAX 的动态 HTML 页面的最小示例
- generic-programming - 埃菲尔:形式泛型参数的无效约束
- r - 基于第二个数据集中的 2 个变量加入(或合并)数据集
- php - 使用 CakePHP 在另一个视图上显示搜索结果
- sql-server - 无法插入加密数据?
- linux - 如何根据“sys_read”来“sys_seek”?