我有一名球员和一名敌人。当我右键击中敌人时,他的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 :(得分: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;
}
要修复它,您需要知道何时停止按击,然后重置hitcounter并禁用标签。
我会将showhitcounter更改为以下内容:
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
答案 1 :(得分:1)
刚刚完成我的解决方案并意识到已经有了答案。不能丢弃它。只需将其作为无内存分配的解决方案。
您不每次点击鼠标时都需要启动Coroutine,就像您在问题中的代码中所做的那样。我这样说是因为在每次鼠标点击后调用StartCoroutine()
时会有不断的内存分配。下面代码中的定时器基于帧速率,但可以使用DateTime.Now
轻松更改为实时。您也可以将代码放在Coroutine中的while循环中,然后从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;
}
}
}
}
答案 2 :(得分:0)
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;
}
}
#endregion