我是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;
答案 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);
}
}
更好的是,将锁定变量声明为属性,然后使用get
和set
评估器来检测锁定变量何时更改并启动协程。有一个示例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());
}