【问题标题】:Having Troubles with Unity C# Time Delay / Coroutines遇到 Unity C# 时间延迟/协程问题
【发布时间】:2023-02-06 02:20:56
【问题描述】:

我正在尝试编写一个脚本,当您按下一个按钮以使其实例化一张随机稀有度的卡片时,我需要在一小段延迟后删除这些卡片,尽管我认为延迟不起作用,因为这些卡片似乎会立即消失

代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CardMasterScript : MonoBehaviour
{
    public GameObject[] CardArray = new GameObject[8];
    public float RollNumber;

    public void RollCard()
    {
        RollNumber = Random.Range(0.1f, 100);

        Debug.Log("Number Rolled: " + RollNumber);

        if(RollNumber <= 47.9)
        {
            var card = Instantiate(CardArray[0]);
            StartCoroutine(TimeDelay());
            Destroy(card);
        } else if(RollNumber > 47.9 && RollNumber <= 77.9)
        {
            var card = Instantiate(CardArray[1]);
            StartCoroutine(TimeDelay());
            Destroy(card);
        } else if( RollNumber > 77.9 && RollNumber <= 87.9)
        {
            var card = Instantiate(CardArray[2]);
            StartCoroutine(TimeDelay());
            Destroy(card);
        } else if(RollNumber > 87.9 && RollNumber <= 94.9)
        {
            var card = Instantiate(CardArray[3]);
            StartCoroutine(TimeDelay());
            Destroy(card);
        } else if(RollNumber > 94.9 && RollNumber <= 97.9)
        {
            var card = Instantiate(CardArray[4]);
            StartCoroutine(TimeDelay());
            Destroy(card);
        } else if(RollNumber > 97.9 && RollNumber <= 99.4)
        {
            var card = Instantiate(CardArray[5]);
            StartCoroutine(TimeDelay());
            Destroy(card);
        } else if(RollNumber > 99.4 && RollNumber <= 99.9)
        {
            var card = Instantiate(CardArray[6]);
            StartCoroutine(TimeDelay());
            Destroy(card);
        } else if (RollNumber > 99.9 && RollNumber <= 100)
        {
            var card = Instantiate(CardArray[7]);
            StartCoroutine(TimeDelay());
            Destroy(card);
        }
    }
    
    public IEnumerator TimeDelay()
    {
        yield return new WaitForSeconds(0.5f);
    }
}
  • 如果你知道如何解决这个问题,请帮助我解决这个问题,提前谢谢你!

起初我认为这是实例化的问题,它根本没有实例化卡片,但现在我不太确定问题出在哪里。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    你必须在这样的等待时间后调用销毁

    public IEnumerator TimeDelay(){    
        yield return new WaitForSeconds(0.5f);
        Destroy(obj);
    }
    

    和其他提示:销毁方法包含延迟参数

    Destroy(obj,0.5f);
    

    https://docs.unity3d.com/ScriptReference/Object.Destroy.html

    【讨论】:

      【解决方案2】:

      销毁是独立于协程发生的。当您启动协同程序时,您将程序“拆分”为两个分支。目前你的第一个分支只打开半秒钟的闹钟,而你的另一个分支删除你的对象。

      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      using UnityEngine.UI;
      
      public class CardMasterScript : MonoBehaviour
      {
          public GameObject[] CardArray = new GameObject[8];
          public float RollNumber;
      
          public void RollCard()
          {
              RollNumber = Random.Range(0.1f, 100);
      
              Debug.Log("Number Rolled: " + RollNumber);
      
              if(RollNumber <= 47.9)
              {
                  var card = Instantiate(CardArray[0]);
                  StartCoroutine(TimeDelay());
              } else if(RollNumber > 47.9 && RollNumber <= 77.9)
              {
                  var card = Instantiate(CardArray[1]);
                  StartCoroutine(TimeDelay());
              } else if( RollNumber > 77.9 && RollNumber <= 87.9)
              {
                  var card = Instantiate(CardArray[2]);
                  StartCoroutine(TimeDelay());
              } else if(RollNumber > 87.9 && RollNumber <= 94.9)
              {
                  var card = Instantiate(CardArray[3]);
                  StartCoroutine(TimeDelay());
              } else if(RollNumber > 94.9 && RollNumber <= 97.9)
              {
                  var card = Instantiate(CardArray[4]);
                  StartCoroutine(TimeDelay());
              } else if(RollNumber > 97.9 && RollNumber <= 99.4)
              {
                  var card = Instantiate(CardArray[5]);
                  StartCoroutine(TimeDelay());
              } else if(RollNumber > 99.4 && RollNumber <= 99.9)
              {
                  var card = Instantiate(CardArray[6]);
                  StartCoroutine(TimeDelay());
              } else if (RollNumber > 99.9 && RollNumber <= 100)
              {
                  var card = Instantiate(CardArray[7]);
                  StartCoroutine(TimeDelay());
              }
          }
          
          public IEnumerator TimeDelay()
          {
              yield return new WaitForSeconds(0.5f);
              Destroy(card);
          }
      }
      

      在您的情况下,实际上并不需要使用协程,因为 Destroy 方法具有内置延迟参数。

      简化您的代码可能如下所示:

      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      using UnityEngine.UI;
      
      public class CardMasterScript : MonoBehaviour
      {
          public GameObject[] CardArray = new GameObject[8];
          public float RollNumber;
      
          public void RollCard()
          {
              RollNumber = Random.Range(0.1f, 100);
      
              Debug.Log("Number Rolled: " + RollNumber);
      
              if(RollNumber <= 47.9)
              {
                  var card = Instantiate(CardArray[0]);
              } else if(RollNumber > 47.9 && RollNumber <= 77.9)
              {
                  var card = Instantiate(CardArray[1]);
              } else if( RollNumber > 77.9 && RollNumber <= 87.9)
              {
                  var card = Instantiate(CardArray[2]);
              } else if(RollNumber > 87.9 && RollNumber <= 94.9)
              {
                  var card = Instantiate(CardArray[3]);
              } else if(RollNumber > 94.9 && RollNumber <= 97.9)
              {
                  var card = Instantiate(CardArray[4]);
              } else if(RollNumber > 97.9 && RollNumber <= 99.4)
              {
                  var card = Instantiate(CardArray[5]);
              } else if(RollNumber > 99.4 && RollNumber <= 99.9)
              {
                  var card = Instantiate(CardArray[6]);
              } else
              {
                  var card = Instantiate(CardArray[7]);
              }
              Destroy(card, 0.5f);
          }
      }
      

      【讨论】:

        【解决方案3】:

        在Quick方式中,在Destroy方法的第二个参数中输入延迟值就足够了。

        Destroy(card, .5f); // Delay Time
        

        第二种方法是将函数本身写在Coroutine 中。因为延迟时间不是在协程外执行的。

        private IEnumerator DelayRun(GameObject gameObject)
        {
            yield return new WaitForSeconds(.5f);
            
            Destroy(gameObject);
        }
        

        第三种方式是指定一个延迟时间的动作,它允许你在延迟后执行任何命令。只要确保您使用System 库即可。

        using System;
        
        ...
        
        void Start()
        {
            StartCoroutine(DelayRun(.5f, () => Destroy(card)));
        }
        
        private IEnumerator DelayRun(float delay, Action action)
        {
            yield return new WaitForSeconds(delay);
            
            action.Invoke();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-01
          • 1970-01-01
          • 2023-02-11
          • 1970-01-01
          • 2021-11-01
          • 2020-08-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多