我有一个玩家和一个敌人。当我正确地点击敌人时,他的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,协同线不会被重置回到一个起点。
发布于 2016-05-25 11:55:38
让我们分析您的代码:
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;
}要修复它,您需要知道何时停止击球,然后重置命中计数器和禁用标签。
我会把鞋柜换到下面:
IEnumerator ShowHitCounter(string message)
{
GUIHit.text = message;
GUIHit.enabled = true;
}
void ClearLabel()
{
HitCounter = 0;
GUIHit.enabled = false;
}}我使clearLabel具有单独的清除标签的方法。您的逻辑必须位于不同的位置,并调用此方法。
有一个地方会举办这样的活动。其他地方将在您的onmouseover,并增加一个财产
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。
发布于 2016-05-25 12:45:16
刚刚完成了我的解决方案,并意识到已经有一个答案。不能抛弃它。只是把它作为一种解决方案,使用,没有内存分配。
您的不需要每次点击右键时启动Coroutine,就像在问题中的代码中所做的那样。我之所以这样说,是因为每次鼠标单击后调用StartCoroutine()时,都会分配常量内存。下面的代码中的计时器是基于帧速率的,但是可以通过使用DateTime.Now轻松地改变为实时。您还可以将代码放入Coroutine中的while循环中,然后将其称为(一旦从函数开始)。
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;
}
}
}
}发布于 2016-05-25 13:09:14
Awh,好吧,下面是另一个概念,就是为了它:)
没有测试它和这样的处理谨慎,但问题是,启动一个协同线等看起来太多(和太昂贵),对我来说,什么都不想要的东西。
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;
}
}
#endregionhttps://stackoverflow.com/questions/37435425
复制相似问题