在短时间内显示文本图层
Posted
技术标签:
【中文标题】在短时间内显示文本图层【英文标题】:Showing a Text layer for a short amount of time 【发布时间】:2016-05-25 11:13:38 【问题描述】:我有一个玩家和一个敌人。当我右键单击敌人时,他的HP下降并且命中计数器上升。我想让它就像当你击中敌人时文本标签变得可见,当你停止攻击时它保持可见几秒钟,然后隐藏并将命中计数器设置回 0。
这就是我目前所拥有的。
public Text GUIHit;
public int HitCounter = 0;
void OnMouseOver()
if (Input.GetMouseButtonDown(1))
HitCounter++;
StartCoroutine(ShowHitCounter(HitCounter.ToString(), 2));
IEnumerator ShowHitCounter(string message, float delay)
GUIHit.text = message;
GUIHit.enabled = true;
yield return new WaitForSeconds(delay);
HitCounter = 0;
GUIHit.enabled = false;
发生的情况是它工作了 2 秒,但即使我仍在攻击它也会变得不可见并且命中计数器回到 0,协程也不会重置回起点。
【问题讨论】:
对此类计时器使用 Invoke 【参考方案1】:让我们分析您的代码:
void OnMouseOver()
if (Input.GetMouseButtonDown(1)) //you get passed that if when you hit first time
HitCounter++;
StartCoroutine(ShowHitCounter(HitCounter.ToString(), 2)); //you call your label with delay of 2 sec
IEnumerator ShowHitCounter(string message, float delay)
GUIHit.text = message;
GUIHit.enabled = true;
yield return new WaitForSeconds(delay); // still on your first hit you get to here and wait 2 seconds
HitCounter = 0; //after 2 seconds you reset hitcounter and disable label
GUIHit.enabled = false;
要修复它,您需要知道何时停止击中,然后重置击中计数器并禁用标签。
我会将 showhitcounter 更改为以下:
IEnumerator ShowHitCounter(string message)
GUIHit.text = message;
GUIHit.enabled = true;
void ClearLabel()
HitCounter = 0;
GUIHit.enabled = false;
我让 clearLabel 有单独的方法来清除标签。您的逻辑必须位于不同的位置并调用此方法。
一个地方会发生 onmouseleave 事件。 其他地方将在您的鼠标悬停并添加一个属性
public static DateTime TimeLeft get; set;
void OnMouseOver()
TimeSpan span = DateTime.Now - TimeLeft;
int ms = (int)span.TotalMilliseconds;
if (ms > 2000)
ClearLabel();
if (Input.GetMouseButtonDown(1))
HitCounter++;
StartCoroutine(ShowHitCounter(HitCounter.ToString(), 2));
你还需要在之前的某个地方初始化TimeLeft
【讨论】:
在if (Input.GetMouseButtonDown(1))
中设置TimeLeft = DateTime.Now
并在IEnumerator ShowHitCounter(string message)
中添加yield return null
使一切正常,非常感谢!【参考方案2】:
刚刚完成我的解决方案并意识到已经有了答案。不能丢弃。只是把它作为一个no内存分配的解决方案。
您不需要每次单击鼠标右键时都需要启动协程,就像您在问题中的代码中所做的那样。我之所以这么说是因为每次单击鼠标后都会调用StartCoroutine()
时会不断分配内存。下面代码中的计时器基于帧速率,但可以使用DateTime.Now
轻松更改为实时。您还可以将代码放在 Coroutine 中的 while 循环中,然后从 Start 函数调用它once。
public Text GUIHit;
public int HitCounter = 0;
bool firstRun = true;
float waitTimeBeforeDisabling = 2f;
float timer = 0;
void Update()
//Check when Button is Pressed
if (Input.GetMouseButtonDown(1))
//Reset Timer each time there is a right click
timer = 0;
if (!firstRun)
firstRun = true;
GUIHit.enabled = true;
HitCounter++;
GUIHit.text = HitCounter.ToString();
//Button is not pressed
else
//Increement timer if Button is not pressed and timer < waitTimeBeforeDisabling
if (timer < waitTimeBeforeDisabling)
timer += Time.deltaTime;
//Timer has reached value to Disable Text
else
if (firstRun)
firstRun = false;
GUIHit.text = HitCounter.ToString();
HitCounter = 0;
GUIHit.enabled = false;
【讨论】:
【参考方案3】:哦,好吧,这是另一个概念,只是为了它:)没有测试它,所以要小心处理,但问题是,启动协程等看起来太多了(而且也是贵)对我来说,只要你想要的东西。
private float holdOutTime = 2.0f;
private float lastHitTime = 0.0f;
void OnMouseOver()
if (Input.GetMouseButtonDown(1)) IncHitAndShowUI() //compacted
private void Update()
if (GUIHit.enabled) TestAndDisableHitUI(); //compacted
#region priv/helper methods
//would force it inline if it was possible in Unity :)
private void IncHitAndShowUI()
HitCounter++;
lastHitTime = Time.time;
GUIHit.text = HitCounter.ToString();
GUIHit.enabled = true;
//same here :)
private void TestAndDisableHitUI()
if (lastHitTime + holdOutTime >= Time.time)
GUIHit.enabled = false;
#endregion
【讨论】:
以上是关于在短时间内显示文本图层的主要内容,如果未能解决你的问题,请参考以下文章