Как я могу создать список в соответствии с состоянием игры, если игра запущена или нет? - PullRequest
0 голосов
/ 07 октября 2019

У меня есть сценарий монобедового поведения:

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

public class CompareObjects : MonoBehaviour
{
    public GameObject mainGame;
    public string comparisonObjects;
    public float waitTime;
    public List<GameObject> allobjects = new List<GameObject>();
    public bool startComparingAtStart = false;

    private Coroutine comparer;

    private void Start()
    {
        if (Application.isPlaying == false)
        {
            allobjects = new List<GameObject>();
        }
        else
        {
            allobjects = FindObjectsOfType<GameObject>().ToList();
        }

        if (startComparingAtStart == true)
        {
            StartComparing();
        }
    }

    public void StartComparing()
    {
        mainGame.SetActive(false);

        if (comparer == null)
        {
            comparer = StartCoroutine(Compare());
        }
    }

    public void StopComparing()
    {
        if (comparer != null)
        {
            comparisonObjects = "";
            allobjects = new List<GameObject>();
            StopCoroutine(comparer);
            mainGame.SetActive(true);

            comparer = null;
        }
    }

    IEnumerator Compare()
    {
        while (true)
        {
            foreach (GameObject go in allobjects)
            {
                if (go.name != "Game Manager")
                {
                    comparisonObjects = go.name + " >>>>> " + go.scene.name + " >>>>> is active object";
                }

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

И сценарий редактора для кнопок в инспекторе:

using UnityEngine;
using System.Collections;
using UnityEditor;

[CustomEditor(typeof(CompareObjects))]
public class CompareObjectsButton : Editor
{
    private CompareObjects compareObjects;

    private void OnEnable()
    {

        compareObjects = (CompareObjects)target;
    }

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        CompareObjects myTarget = (CompareObjects)target;

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

        if (GUILayout.Button("Stop"))
        {
            myTarget.StopComparing();
        }
    }
}

Эта часть не работает:

if (Application.isPlaying == false)
{
    allobjects = new List<GameObject>();
}
else
{
    allobjects = FindObjectsOfType<GameObject>().ToList();
}

При запуске игры и нажатии кнопки «Начать сравнение объектов», если я нажму кнопку «Стоп», она сбросит список всех объектов на длину 0.

Но если вместо этого нажать кнопку «Стоп», я просто остановлю игру, список всех объектов будетбыть пустым, но длина будет более 5000 наименований. Это элементы будут пустыми, но я хочу, чтобы, когда игра не запускалась, список имел длину 0.

Не уверен, почему он поддерживает длину списка более 5000 элементов и как сбросить ее до длины 0.

Пытался использовать:

Application.isPlaying

Но это не работает.

Это то, что я пробовал до сих пор:

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

[ExecuteAlways]
public class CompareObjects : MonoBehaviour
{
    public GameObject mainGame;
    public string comparisonObjects;
    public float waitTime;
    public List<GameObject> allobjects = new List<GameObject>();
    public bool startComparingAtStart = false;

    private Coroutine comparer;

    private void Start()
    {
        if (Application.isPlaying == false)
        {
            allobjects = new List<GameObject>();
        }
        else
        {
            allobjects = FindObjectsOfType<GameObject>().ToList();
        }

        if (startComparingAtStart == true)
        {
            StartComparing();
        }
    }

    public void StartComparing()
    {
        mainGame.SetActive(false);

        if (comparer == null)
        {
            comparer = StartCoroutine(Compare());
        }
    }

    public void StopComparing()
    {
        if (comparer != null)
        {
            comparisonObjects = "";
            allobjects = new List<GameObject>();
            StopCoroutine(comparer);
            mainGame.SetActive(true);

            comparer = null;
        }
    }

    IEnumerator Compare()
    {
        while (true)
        {
            foreach (GameObject go in allobjects)
            {
                if (go.name != "Game Manager")
                {
                    comparisonObjects = go.name + " >>>>> " + go.scene.name + " >>>>> is active object";
                }

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

Но еслиСравнение работает, Coroutine находится посередине, и я выхожу из игры, нажимая кнопку воспроизведения, чтобы выйти из игры, весь редактор зависает, и мне нужно принудительно закрыть его в диспетчере задач.

1 Ответ

4 голосов
/ 08 октября 2019

Код if (Application.isPlaying == false) не работает в вашем случае, потому что он помещает в метод запуска MonoBehaviour, который по умолчанию вызывается только в режиме воспроизведения.

Чтобы сделать код работоспособным, вы можете переместить инициализацию allobjects в StartComparing / StopComparing методов или игра с ExecuteInEditMode или ExecuteAlways для запуска кода в режиме редактора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...