如何在特定时间后遍历每个对象?

时间:2019-10-07 01:26:28

标签: c# unity3d

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public class CompareObjects : MonoBehaviour
{
    public float waitTime;

    private GameObject[] allObjects;

    public void Compare()
    {
        allObjects = FindObjectsOfType<GameObject>();

        foreach (GameObject go in allObjects)
        {
            Debug.Log(go.name + " >>>>> " + go.scene.name + " >>>>> is active object");
            StartCoroutine(Comparing());
        }
    }

    IEnumerator Comparing()
    {
        yield return new WaitForSeconds(waitTime);
    }
}

这个想法不是要阻塞整个编辑器并等待foreach循环完成,而是要使其在第一个项目上循环一秒钟,然后再继续进行下一个,依此类推。

现在的方式是使编辑器窒息,冻结它直到循环结束。

到目前为止,我所做的事情还没有奏效:

我为检查器中的按钮创建了一个新的编辑器脚本:

using UnityEngine;
using System.Collections;
using UnityEditor;

[CustomEditor(typeof(CompareObjects))]
public class CompareObjectsButton : Editor
{
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        CompareObjects myTarget = (CompareObjects)target;

        if (GUILayout.Button("Compare Objects"))
        {
            myTarget.StartComparing();
        }
    }
}

然后在“比较对象”中:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public class CompareObjects : MonoBehaviour
{
    public float waitTime;

    private Coroutine comparer;
    private GameObject[] allObjects;

    public void StartComparing()
    {
        if (comparer == null)
        {
            comparer = StartCoroutine(Compare());
        }
    }

    public void StopComparing()
    {
        if (comparer != null)
        {
            StopCoroutine(comparer);

            comparer = null;
        }
    }

    IEnumerator Compare()
    {
        while (true)
        {
            allObjects = FindObjectsOfType<GameObject>();

            foreach (GameObject go in allObjects)
            {
                Debug.Log(go.name + " >>>>> " + go.scene.name + " >>>>> is active object");

                yield return new WaitForSeconds(waitTime);
            }
        }
    }
}

但是它只做一个对象,而不是所有对象。

1 个答案:

答案 0 :(得分:2)

StartCoroutine的行为与启动新线程相同,因此,当您调用Compare时,您要做的就是遍历游戏对象并创建事件对象,这些事件对象在主线程中运行时不会不能阻止创建它的方法运行,因此最终只有新的事件对象等待指定的时间,而main方法继续循环遍历其余游戏对象并创建更多事件对象,因为它本身并未调用任何方法睡眠功能,相反,您应该执行以下操作:

public void StartComparing()
{
    if (comparer == null)
    {
        comparer = StartCoroutine(Compare());
    }
}

public void StopComparing()
{
    if (comparer != null)
    {
        StopCoroutine(comparer);

        comparer = null;
    }
}

IEnumerator Compare()
{
    while (true)
    {
        allObjects = FindObjectsOfType<GameObject>();

        foreach (GameObject go in allObjects)
        {
            Debug.Log(go.name + " >>>>> " + go.scene.name + " >>>>> is active object");

            yield return new WaitForSeconds(waitTime);
        }
    }
}

private Coroutine comparer;

private GameObject[] allObjects;

public float waitTime;

StartComparing将启动Compare的协程,该协程将遍历所有对象,因此,第一个对象然后等待指定的waitTime然后是第二个对象,依此类推,以此类推直到调用StopComparing

经过测试的代码,这里是一个小小的(字面意义上的)预览,您将看到更改速度后它记录对象的速度变慢了:

enter image description here