2016-05-25 2 views
4

У меня есть игрок и враг. Когда я обращаюсь к врагу, его HP опускается, и ударная стрелка поднимается. Я хочу сделать это, когда вы нажмете на врага, текстовая метка станет видимой, и когда вы прекратите атаковать, она останется видимой еще на пару секунд, а затем скроется и снова установит hitcounter на 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, сопрограммному не получают сбросить обратно к исходной точке.

+0

использовать Invoke для таких таймеров – Fattie

ответ

2

Позволяет анализировать код:

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 мероприятие. Другое место было бы в вашем 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 где-то до

+1

Установка 'TimeLeft = DateTime.Now' в' если (Input.GetMouseButtonDown (1)) '' и добавление выход возврата null' в 'IEnumerator ShowHitCounter (строка сообщения)' сделал это все работает, спасибо большое! – Simon

1

Просто закончил с моим решением, и понял, что есть ответ уже. Нельзя отказаться от него. Просто поставьте его как решение с no выделение памяти.

Вы не нужно необходимо запустить Coroutine каждый раз, когда правая мышь нажата, как вы делали код в своем вопросе. Я говорю это из-за постоянного выделения памяти, когда после каждого щелчка мыши вызывается StartCoroutine(). Таймер в приведенном ниже коде основан на частоте кадров, но его можно легко изменить в режиме реального времени, используя DateTime.Now. Вы также можете поместить код в цикл while в Coroutine, затем вызовите его после из функции Start.

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; 
      } 
     } 

    } 
} 
0

АДД, тогда ладно, вот еще одна концепция, только ради этого :)
не проверял и такой характер, чтобы обращаться с осторожностью, но дело в том, начиная сопрограмму и т.д. выглядит слишком много (и слишком дорого) для меня, для чего-то, чего вы хотите.

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
Смежные вопросы