1

Недавно начала учиться делать игры на Unity. В обучающем уроке учитель создал скрипт Input и скрипт Gun. В Input он написал строку

[SerializeField] private Gun _shotGun;

И затем вызывал метод из Gun через _shotGun. Я понимаю, для чего это, но не понимаю, чем является _shotGun? Написано, что полем. Я думала - экземпляром класса...

Helena
  • 23
  • А можно, пожалуйста, ознакомиться с данным уроком и указанными в нём кодом? – 4500zenja Jan 20 '22 at 12:26
  • 1
    _shutGun - это переменная (поле, свойство) некого класса, которая имеет тип Gun, она приватная (то есть к ней можно получать доступ только с объекта. А также оно помечено атрибутом, что оно сериализируемое. – KoVadim Jan 20 '22 at 12:28
  • у Романа Сакутина урок смотрела – Helena Jan 20 '22 at 12:33
  • @Helena не стоит обращать внимание на инфоцыган, лучше подучите основы C# на метаните или на ютубе codeblog.. еще есть андрей широкорядов, там SOLID и паттерны хорошо объясняются на примерах. На SO есть еще вот это – Aarnihauta Jan 20 '22 at 12:52
  • основы, вроде бы, подучила уже) вот, в Unity пытаюсь это проецировать – Helena Jan 20 '22 at 12:54
  • @Helena не думаю, что сакутин/дударь/хаудихо поможет вам в изучении юнити, есть оф. документация с примерами, но там на английском, но никто не мешает использовать гугл переводчик. но это конечно всё моё субъективное мнение слушать которое не стоит ведь я не изучал юнити – Aarnihauta Jan 20 '22 at 13:00
  • 1
    @Aarnihauta да по Unity видеогайдов только ленивые не снимали. Типа "пилить игры - это суперпросто, каждый школьник справится, вот смотрите", они как бы занижают сильно порог вхождения в отрасль, но накапливают технический долг, когда новичек набыдлокодил, оно как-то работает, а что делать дальше - непонятно, потому что код в таком ужасном состоянии, что дорабатывать его просто нереально. И больше половины из таких новичков просто бросают это дурное занятие, потому что "непонятно, что дальше делать, сложна". Это и есть цена положенного болта на SOLID и ООП как на никому ненужную нудятину. – aepot Jan 20 '22 at 13:05

2 Answers2

1

Вам немного надо подучить основы C# и ООП.

//    название класса
class MyClass
{
    // приватное поле типа 'int'
    private int _myField;
// какой-то публичный метод
public void MyMethod()
{
}

}

Класс - это некий шаблон для создания объекта. Созданный объект из какого-то класса еще назвают экземпляром этого класса. Переменная или поле может содержать ссылку на этот экземпляр. Класс - ссылочный тип данных.

// создание экземпляра, переменная instance - экземпляр класса MyClass
MyClass instance = new MyClass();
instance.MyMethod(); // вызов публичного метода для данного экземпляра класса
// класс, наследующий базовый класс MonoBehavior
class MyController : MonoBehavior
{
    // приватное поле типа 'MyClass'
    private MyClass _instance;
void Awake()
{
    _instance = new MyClass();
}

void Start()
{
    _instance.MyMethod(); // то же самое, вызов метода для экземпляра MyClass
}

}

В вашем случае экзепляр new MyClass() создается в недрах Unity. Но суть работы уже с созданным экземпляром как в Unity, так и в чистом C# одна и та же.

Чтобы подробнее понять, как оно работает, изучите принципы ООП - инкапсуляция, наследование и полиморфизм. Они для всех языков программирования и всех фреймворков одни и те же.

Атрибут [SerializeField] в данном случае к вопросу ООП не относится, он выполняет другие задачи, не обращайте на него много внимания.

aepot
  • 49,560
  • Да я вроде знаю, что это. Просто конкретно в этом случае не поняла, чем является содержимое строки. Спасибо за развернутый ответ – Helena Jan 20 '22 at 12:46
  • @Helena если всё понятно, то вы можете выбрать и принять наиболее полезный ответ галочкой. – aepot Jan 20 '22 at 12:46
  • еще один вопросик: использование такой конструкции оправдано или все таки не совсем корректно? – Helena Jan 20 '22 at 12:52
  • @Helena какой именно? Переменная может существовать только внутри метода. Если нужно что-то хранить в объекте - без полей вам никак не обойтись. – aepot Jan 20 '22 at 12:54
  • я по примеру делаю. у меня есть такая строка: [SerializeField] private LaserGun _laserGun; но мне нечего на _lasergun повесить. у меня только два Transform gunpositon есть. с помощью _laserGun я получаю в Input доступ к методу Fire. _laserGun.Fire(); вся проблема в том, что не знаю, что на laserGun повесить. может, есть какой то другой способ обратиться к методу – Helena Jan 20 '22 at 13:04
  • @Helena если у вас появился новый вопрос, вы можете его задать отдельно. Подозреваю, что вы хотите понять, что такое "наследование", типа когда есть "пушка" и у нее есть наследники "дробан", "рельса", "пулемет Максим", и метод "Стрелять()" идет именно от "пушки". Поле в классе должно быть типа родителя, тогда в него можно будет положить, то есть присвоить любого наследника. – aepot Jan 20 '22 at 13:09
  • @Aarnihauta не надо никакой рефлексии новичкам. Тем более, оно в Unity вообще опасно, потому что будет тормозить всё. Mono - это не Core CLR, там нативная компиляция, и рефлексия там - очень дорого. Лучше проектировать объектную модель правильно, а не втыкать костыли. Рефлексия - в основном как раз для костылей. В данном случае достаточно метод сделать публичным public, что я и показал в ответе. – aepot Jan 20 '22 at 13:10
  • @aepot понял, зря я свою копейку вставил в тему, в которой ни разу не бывал. удалю коммент про рефлексию – Aarnihauta Jan 20 '22 at 13:11
  • 1
    спасибо за помощь! – Helena Jan 20 '22 at 15:13
0
[SerializeField] 
private Gun _shotGun;

_shotGun - это одновременно и то и другое:

  • это переменная, хранящая ссылку на экземпляр класса Gun (но нам не показали, где его инстанциируют и присваивают ссылку в эту переменную)
  • это приватное поле какого-то класса, который нам опять же не показали
class SomeClass
{
    [SerializeField] 
    private Gun _shotGun;
...

}

CrazyElf
  • 71,194