我环顾四周,并尝试了不同的方法来实现这一目标,但是我没有得到正确的结果。我知道我要的很多,但是我碰到了这堵砖墙,如果可以的话,我将不胜感激。
当玩家挖掘资源时,如果他们从起始位置移动,我希望它停止挖掘。我已经发布了完整的课程,以便您可以看到我在做什么,并希望有人可以指出正确的方向。
using System.Collections;
using UnityEngine;
public class Mining : MonoBehaviour, IInteractable
{
private Coroutine gatherRoutine;
private Vector3 playerPosition;
[SerializeField]
private float timeToGather;
[SerializeField]
private LootTable lootTable;
[SerializeField]
[Tooltip("Leave blank if there is no achievement attached to this object")]
private string achievementName;
[Header("Interaction Cursor")]
[SerializeField]
private float interactDistance;
[SerializeField]
private Texture2D cursorTexture;
[SerializeField]
private CursorMode cursorMode = CursorMode.Auto;
[SerializeField]
private Vector2 hotSpot = Vector2.zero;
private void OnMouseEnter()
{
if ((Vector3.Distance(Player.MyInstance.MyTransform.position, transform.position) < interactDistance) && !Player.MyInstance.MyIsGathering)
{
Cursor.SetCursor(cursorTexture, hotSpot, cursorMode);
Player.MyInstance.MyInteractable = GetComponent<IInteractable>();
}
else
{
Cursor.SetCursor(null, Vector2.zero, cursorMode);
}
}
private void OnMouseExit()
{
Cursor.SetCursor(null, Vector2.zero, cursorMode);
}
public void Interact()
{
if (Vector3.Distance(Player.MyInstance.MyTransform.position, transform.position) < interactDistance && Player.MyInstance.MyHasPickaxe == true)
{
playerPosition = Player.MyInstance.MyTransform.position;
gatherRoutine = StartCoroutine(Gather(timeToGather));
}
else
{
GameManager.MyInstance.SendMessageToChat("You need to equip a 'Pickaxe' to mine this resource.", Message.MessageType.warning);
}
}
public void StopInteract()
{
Player.MyInstance.MyIsGathering = false;
Player.MyInstance.animator.SetBool("Mining", Player.MyInstance.MyIsGathering);
if (gatherRoutine != null)
{
StopCoroutine(gatherRoutine);
}
}
private IEnumerator Gather(float time)
{
Player.MyInstance.MyIsGathering = true;
Player.MyInstance.animator.SetBool("Mining", Player.MyInstance.MyIsGathering);
yield return new WaitForSeconds(time);
Player.MyInstance.MyIsGathering = false;
Player.MyInstance.animator.SetBool("Mining", Player.MyInstance.MyIsGathering);
lootTable.ShowLoot();
if (achievementName != null)
{
AchievementManager.MyInstance.EarnAchievement(achievementName);
}
Destroy(gameObject);
Cursor.SetCursor(null, Vector2.zero, cursorMode);
}
}
答案 0 :(得分:0)
您必须使用与启动协程完全相同的参数来停止协程。
StopCoroutine采用以下三个参数之一,该参数指定停止哪个协程:
- 命名活动协程的字符串函数
- 之前用于创建协程的IEnumerator变量。
- 协程以停止手动创建的协程。
注意:请勿混合使用三个参数。如果在StartCoroutine中将字符串用作参数,请在StopCoroutine中使用该字符串。同样,在StartCoroutine和StopCoroutine中都使用IEnumerator。最后,将StopCoroutine与用于创建的协同程序一起使用。
因此,您应该预先分配gatherRoutine
gatherRoutine = Gather(timeToGather);
StartCoroutine(gatherRoutine);
及以后
StopCoroutine(gatherRoutine);
或者,您可以使用StopAllCoroutines()
来停止协程而不必处理参数(仅在该类中只有一个协程的情况下才应使用)。
public void StopInteract()
{
Player.MyInstance.MyIsGathering = false;
Player.MyInstance.animator.SetBool("Mining", Player.MyInstance.MyIsGathering);
if (gatherRoutine != null)
{
StopAllCoroutines();
}
}
或者您可以使用bool来做
private interuptRoutine = false;
public void Interact()
{
if (Vector3.Distance(Player.MyInstance.MyTransform.position, transform.position) < interactDistance && Player.MyInstance.MyHasPickaxe == true)
{
playerPosition = Player.MyInstance.MyTransform.position;
// before starting the routine set the interupt flag to false
interuptRoutine = false;
StartCoroutine(Gather(timeToGather));
}
else
{
GameManager.MyInstance.SendMessageToChat("You need to equip a 'Pickaxe' to mine this resource.", Message.MessageType.warning);
}
}
public void StopInteract()
{
Player.MyInstance.MyIsGathering = false;
Player.MyInstance.animator.SetBool("Mining", Player.MyInstance.MyIsGathering);
if (gatherRoutine != null)
{
// only set the interupt flag
interuptRoutine = true;
}
}
private IEnumerator Gather(float time)
{
Player.MyInstance.MyIsGathering = true;
Player.MyInstance.animator.SetBool("Mining", Player.MyInstance.MyIsGathering);
// does the same as WaitForSeconds but manually and interupts the routine
// if interuptRoutine was set to true
var timePast = 0;
while(timePast <= time)
{
if(interuptRoutine) yield brake;
timePast += Time.deltaTime;
}
Player.MyInstance.MyIsGathering = false;
Player.MyInstance.animator.SetBool("Mining", Player.MyInstance.MyIsGathering);
lootTable.ShowLoot();
if (achievementName != null)
{
AchievementManager.MyInstance.EarnAchievement(achievementName);
}
Destroy(gameObject);
Cursor.SetCursor(null, Vector2.zero, cursorMode);
}