碰撞后如何启动计时器?
How can I start a timer after collision?
我想在我的游戏中创建一个奖励对象。当玩家拿起它时,计时器应该开始。
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
StartTimer();
}
}
public void StartTimer(){
}
这里有很多解决方案!取决于您的需求。根据您的情况,最喜欢的可能是
您可以使用 Coroutine
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
StartCoroutine (Timer());
}
}
private IEnumerator Timer()
{
yield return new WaitForSeconds (3f);
// Something that happens after 3 seconds
}
可以直接将碰撞消息本身转成Coroutine
public IEnumerator OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
yield return new WaitForSeconds (3f);
// Something happens after 3 seconds
}
}
或者您可以使用 Invoke
以便在延迟后执行方法
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
Invoke(nameof(AfterDelay), 3f);
}
}
public void AfterDelay()
{
// Something happens after 3 seconds
}
有关更多选项和详细信息,请查看
如果您说的启动计时器是指例如倒计时显示,那么你绝对应该使用协程,例如
public Text text;
private Coroutine timer;
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
if(timer == null) timer = StartCoroutine (Timer(3f));
}
}
public void OnCollisionExit2D(Collision2D col) //player left bonus before timer passed
{
if (col.gameObject.name == "Cube")
{
if(timer == null) StopCoroutine (timer);
timer = null;
}
}
private IEnumerator Timer(float durationInSeconds)
{
var timeLeft = duration;
while(timeLeft >= 0)
{
Text.text = timeLeft.ToString(F2);
yield return null;
}
// Something that happens after the timer reached 0
Debug.Log("Hello!");
}
- Unity 的实现方式是协程。
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
StartCoroutine(MyTimer());
}
}
IEnumerator StartTimer(){
yield return new WaitForSeconds(3f);
// DO STUFF AFTER 3 SECONDS
}
- 您可以创建一个 RunDelayed 助手来简化语法。到目前为止我最喜欢的。它使代码看起来更清晰。阅读 my blog post 这方面的内容以及如何使其在所有单一行为中都可访问(通过继承或扩展方法)。
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
RunDelayd(3f, () => {
// DO STUFF HERE AFTER 3 SECONDS
});
}
}
protected IEnumerator DelayedCoroutine(float delay, System.Action a)
{
yield return new WaitForSeconds(delay);
a();
}
protected Coroutine RunDelayed(float delay, System.Action a)
{
return StartCoroutine(DelayedCoroutine(delay, a));
}
- 您可以使用 C# 任务和后台线程。在 Unity 中,我尽量避免使用它们,因为它们与 WebGL 不兼容,并且您可能会在播放器中遇到问题。我知道 Google 的 Firebase 使用它们,因此对于更复杂的异步任务,值得一试。对于您的简单情况,我不推荐它们。
我想在我的游戏中创建一个奖励对象。当玩家拿起它时,计时器应该开始。
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
StartTimer();
}
}
public void StartTimer(){
}
这里有很多解决方案!取决于您的需求。根据您的情况,最喜欢的可能是
您可以使用 Coroutine
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
StartCoroutine (Timer());
}
}
private IEnumerator Timer()
{
yield return new WaitForSeconds (3f);
// Something that happens after 3 seconds
}
可以直接将碰撞消息本身转成Coroutine
public IEnumerator OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
yield return new WaitForSeconds (3f);
// Something happens after 3 seconds
}
}
或者您可以使用 Invoke
以便在延迟后执行方法
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
Invoke(nameof(AfterDelay), 3f);
}
}
public void AfterDelay()
{
// Something happens after 3 seconds
}
有关更多选项和详细信息,请查看
如果您说的启动计时器是指例如倒计时显示,那么你绝对应该使用协程,例如
public Text text;
private Coroutine timer;
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
if(timer == null) timer = StartCoroutine (Timer(3f));
}
}
public void OnCollisionExit2D(Collision2D col) //player left bonus before timer passed
{
if (col.gameObject.name == "Cube")
{
if(timer == null) StopCoroutine (timer);
timer = null;
}
}
private IEnumerator Timer(float durationInSeconds)
{
var timeLeft = duration;
while(timeLeft >= 0)
{
Text.text = timeLeft.ToString(F2);
yield return null;
}
// Something that happens after the timer reached 0
Debug.Log("Hello!");
}
- Unity 的实现方式是协程。
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
StartCoroutine(MyTimer());
}
}
IEnumerator StartTimer(){
yield return new WaitForSeconds(3f);
// DO STUFF AFTER 3 SECONDS
}
- 您可以创建一个 RunDelayed 助手来简化语法。到目前为止我最喜欢的。它使代码看起来更清晰。阅读 my blog post 这方面的内容以及如何使其在所有单一行为中都可访问(通过继承或扩展方法)。
public void OnCollisionEnter2D(Collision2D col) //player collide with bonus
{
if (col.gameObject.name == "Cube")
{
RunDelayd(3f, () => {
// DO STUFF HERE AFTER 3 SECONDS
});
}
}
protected IEnumerator DelayedCoroutine(float delay, System.Action a)
{
yield return new WaitForSeconds(delay);
a();
}
protected Coroutine RunDelayed(float delay, System.Action a)
{
return StartCoroutine(DelayedCoroutine(delay, a));
}
- 您可以使用 C# 任务和后台线程。在 Unity 中,我尽量避免使用它们,因为它们与 WebGL 不兼容,并且您可能会在播放器中遇到问题。我知道 Google 的 Firebase 使用它们,因此对于更复杂的异步任务,值得一试。对于您的简单情况,我不推荐它们。