Unity. FindObjectOfType не находит объект базового класса

Не обращайте внимания на ошибки в коде, пришлось писать с телефона. Вопрос теоретический. Есть класс Main с большим количеством полей. И есть класс MainTemp, который наследует от Main эти поля. На сцене у нас присутствует несколько объектов с компонентом MainTemp. Теперь смоделируем ситуацию, когда нам нужно будет инициализировать объект с компонентом Main.(допустим это будет префаб, на котором уже висит скрипт Main) Обычно делаю это таким способом:

public class Main : MonoBehaviour
{
  static Main instance_;
  public static Main Instance 
  {
     get  
     { 
     if (!instance_) instance_ = FindGameObjectOfType<Main>().GetComponent<Main>();
    // далее код не срабатывает, он находит объект со скриптом       MainTemp...
     if (!instance) instance_ =   Resources.Load(“MainPrefab”).GetComponent<Main>();
return instance_;
   }
}


}

public class MainTemp : Main
{
  private void Start()
  {
  //мы не знаем существует ли объект с компонентом <Main> на   сцене
  Main main = Main.Instance;
  }
}

В этом примере, при запуске сцены, находит любой GameObject со скриптом MainTemp... То есть новый объект с компонентом Main создан не будет. Что-то не понимаю... Может кто-нибудь сможет подсказать варианты такой реализации? P.S. прекрасно знаю как реализовать связь между объектами и скриптами другими способами, интересует конкретно этот случай.


Ответы (2 шт):

Автор решения: Andrew

FindGameObjectOfType здесь не поможет по той причине, что MainTemp тоже является Main. Соответственно что первое находит, то тебе и возвращает.

Что делать?

Перебирать все обьекты на сцене и проверять их на то что они являются Main но не являются MainTemp:

if ( (gameObject is Main) && !(gameObject is MainTemp) )
{
   мы нашли главный обьект типа Main - gameObject который зайдет внутрь этого условия
}
→ Ссылка
Автор решения: Yaroslav

//мы не знаем существует ли объект с компонентом на сцене

Почему не знаете? Посмотреть в иерархию религия запрещает?

В первом if вы ищете объект на сцене! А если не находите то, грузите из ресурсов, но не создаете (Instantiate) его экземпляр на сцене, поскольку синглтон этого не может, он не MonoBehaviour.

Ну и метод start это не Start.

Почему сразу не создать GameObject с этим скриптом на сцене и не сделать в скрипте статическую ссылку для общего доступа...

public class Foo : MonoBehaviour
{
    private static Foo _main;

    public static Foo Main { get => _main; }

    private void Awake ()
    {
        _main = this;
    }

    public void DoSomething () { }
}

public class Sample : MonoBehaviour
{
    private void Start ()
    {
        Foo.Main.DoSomething();
    }
}

И FindGameObject и Resources.Load это ужасные практики. Ими вообще не нужно пользоваться!

→ Ссылка