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 шт):
FindGameObjectOfType здесь не поможет по той причине, что MainTemp тоже является Main. Соответственно что первое находит, то тебе и возвращает.
Что делать?
Перебирать все обьекты на сцене и проверять их на то что они являются Main но не являются MainTemp:
if ( (gameObject is Main) && !(gameObject is MainTemp) )
{
мы нашли главный обьект типа Main - gameObject который зайдет внутрь этого условия
}
//мы не знаем существует ли объект с компонентом на сцене
Почему не знаете? Посмотреть в иерархию религия запрещает?
В первом 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 это ужасные практики. Ими вообще не нужно пользоваться!