首页 > 解决方案 > 如何增加一个数字但不是一次(使用 Unity 引擎)

问题描述

所以假设玩家有 100 金币,他们又得到了 100 金币,我不希望显示值立即从 100 变为 200,因为它不是很明显,而是希望显示在整个过程中从 100 变为 200说,半秒之类的,这可能吗?抱歉这个菜鸟问题,但我能想到的唯一方法是(可能)不必要的复杂 for 循环,必须有一种更有效的方法来做到这一点......谢谢!

标签: unity3duser-interface

解决方案


每当通过脚本更改金额时,您始终可以使用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 方法而不是属性,该方法首先检查是否有足够的黄金来花费等,但这取决于您;)


推荐阅读