Unity-如何在每一次良好的动作中显示文本几秒钟

时间:2018-11-18 13:45:53

标签: c# unity3d

我是Unity和编程领域的新手,所以我需要一些帮助。播放器移动良好后,我试图显示3秒的文字。它正在第一步中工作,文本消失了,但仍在闪烁。可能是因为它处于更新方法中,并且此项目仍处于锁定状态...但是,如何在每次正确移动后将其更改为在3秒钟内显示此文本呢?每个项目仅一次。谢谢

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameControl : MonoBehaviour
{
[SerializeField]
private GameObject someText
[SerializeField]
private GameObject goodMove;

// Use this for initialization
void Start()
{
    someText.SetActive(false);
    goodMove.SetActive(false);
}
void Update()
{
    if (item1.locked && item2.locked && item3.locked)
    {
        someText.SetActive(true);
    }

    if (item1.locked || item2.locked || item3.locked)
    {
        StartCoroutine(waiter());
    }
}
IEnumerator waiter()
{
    goodMove.SetActive(true);
    yield return new WaitForSeconds(3);
    goodMove.SetActive(false);
}

}

编辑:项目被拖动到正确位置时被锁定

...case TouchPhase.Ended:
            if (Mathf.Abs(transform.position.x - somePlace.position.x) <= 2f &&
            Mathf.Abs(transform.position.y - somePlace.position.y) <= 2f)
                    {
                        transform.position = new Vector2(somePlace.position.x, somePlace.position.y);
                        transform.localScale -= new Vector3(0.4F, 0.4F, 0.4F);
                        locked = true;
                    }
                    else
                    {
                        transform.position = new Vector2(initialPosition.x, initialPosition.y);
                    }
                    break;

2 个答案:

答案 0 :(得分:2)

它正在闪烁,因为您每帧都在呼叫StartCoroutine(waiter());。您可以使用布尔变量使它仅被调用一次。如果您是我,我将删除Update函数,并使用协程对其进行修复,并避免在触摸检测脚本中移动代码。

此外,下面的代码正在每一帧执行:

if (item1.locked && item2.locked && item3.locked)
{
    someText.SetActive(true);
}

最好创建另一个锁定变量,以便在执行if语句之前可以使用它来检查锁定变量何时已更改。注意下面的ItemChanged()函数,它就是这么做的。

public class GameControl : MonoBehaviour
{
    //Change YourItemType to whatver your item1, item2, item3 types are
    YourItemType item1, item2, item3;

    [SerializeField]
    private GameObject someText;
    [SerializeField]
    private GameObject goodMove;

    bool oldVal1;
    bool oldVal2;
    bool oldVal3;

    // Use this for initialization
    void Start()
    {
        someText.SetActive(false);
        goodMove.SetActive(false);

        StartCoroutine(LockChecker());
    }

    IEnumerator LockChecker()
    {
        oldVal1 = item1.locked;
        oldVal2 = item2.locked;
        oldVal3 = item3.locked;

        //Run this code forever as the Update function
        while (true)
        {

            //Check if item has changed
            if (ItemChanged())
            {
                if (item1.locked && item2.locked && item3.locked)
                {
                    someText.SetActive(true);
                }

                if (item1.locked || item2.locked || item3.locked)
                {
                    //Call the waiter function then wait for it to return
                    yield return StartCoroutine(waiter());
                }
            }

            yield return null;
        }
    }

    bool ItemChanged()
    {
        //Check if the booelan variable changed
        if (oldVal1 != item1.locked ||
            oldVal2 != item2.locked ||
            oldVal3 != item3.locked)
        {
            //Update old values
            oldVal1 = item1.locked;
            oldVal2 = item2.locked;
            oldVal3 = item3.locked;

            return true;
        }

        return false;
    }

    IEnumerator waiter()
    {
        goodMove.SetActive(true);
        yield return new WaitForSeconds(3);
        goodMove.SetActive(false);
    }
}

更好的是,将锁定变量声明为属性,然后使用getset评估器来检测锁定变量何时更改并启动协程。有一个示例here

答案 1 :(得分:0)

您是正确的,它可能会闪烁,因为一旦某个项目被锁定,它将继续被锁定,并且Update方法将继续触发您的协同程序。取而代之的是,我会在商品被锁定的那一刻向您的协同程序发出呼叫(并从您的Update中删除支票):

        if (Mathf.Abs(transform.position.x - somePlace.position.x) <= 2f &&
        Mathf.Abs(transform.position.y - somePlace.position.y) <= 2f)
                {
                    transform.position = new Vector2(somePlace.position.x, somePlace.position.y);
                    transform.localScale -= new Vector3(0.4F, 0.4F, 0.4F);
                    locked = true;

                    StartCoroutine(waiter());
                }