Содержание
- 1 Скрипты C#/JS | Unity3d
- 2 Записи сообщества Поиск
- 3 GameObject
- 3.0.1 Получение ссылки на игровой объект
- 3.0.2 Уничтожение игрового объекта
- 3.0.3 Активация/деактивация игрового объекта
- 3.0.4 Добавление новых компонентов и скриптов игровому объекту
- 3.0.5 Получение доступа к компоненту игрового объекта
- 3.0.6 Переименование игрового объекта. Считывание имени объекта
- 3.0.7 Сделать объект статичным
- 3.0.8 Установить слои игровому объекту, а также считать их
- 3.0.9 Установить тэг игровому объекту, а также его считывание
- 4 Transform
- 5 12 комментариев для “Скрипты в Unity3D. Урок 0. Основы”
Скрипты C#/JS | Unity3d
- Записи сообщества
- Поиск
Скрипты C#/JS | Unity3d запись закреплена
C# Clean Code Tips&Tricks #1
В данной рубрике будут простые и короткие примеры как сделать ваш код более красивым и читаемым.
Оператор ?? Называется оператором null-объединения, он возвращает левое значение, если оно не равно null, в противном случае возвращает правое.
Object x = null ;
Object y = x ?? 100;
В конечно результате y будет равен 100, так как x равен null.
Иногда мы обращаемся к объекту, а он может быть равен null, тогда надо перестраховаться и сделать проверку на null, которая будет выглядеть вот так:
if(_player.Gun != null)
_player.Gun.SomeMethod() ;
Но можно сделать данное выражение более красивым и приятным для чтения:
_player?.Gun.SomeMethod();
Скрипты C#/JS | Unity3d запись закреплена
Liskov Substitution Principle
На самом деле, один из тех принципов, после прочтения формулировки которого, мой мозг слегка взрывался и просился закрыть эту вкладку в браузере. Приведу несколько формулировок, одна с википедии, другая с сайта metanit:
Показать полностью…
«Пусть q(x) является свойством верным относительно объектов x некоторого типа T. Тогда q(y) также должно быть верным для объектов y типа S, где S является подтипом типа T.» © Wikipedia
«Если для каждого объекта o1 типа S существует объект o2 типа T, такой, что для любой программы P, определенной в терминах T, поведение P не изменяется при замене o2 на o1, то S является подтипом T.» © Metanit
Когда я читал это в первый раз, то мне показалось, что меня изнасиловали.
А теперь я попытаюсь дать вам определение этого принципа простыми словами и привести пример, который останется в вашей голове на всю оставшуюся жизнь.
Итак, принцип подстановки Барбары Лисков. Он же Liskov Substitution Principle. Он же LSP. Простыми словами принцип звучит так:
Объекты класса родителя должны иметь возможность замещаться объектами класса наследника так, чтобы целостность программы не нарушалась.
Т.е. Если у вас есть класс Enemy и она весит на объекте в игре, все работает и все прекрасно, потом вы решили создать класс Zombie, который наследуется от Enemy, и у вас должна быть возможность заменить класс Enemy на объекте на Zombie и ваша игра должна продолжить функционирование.
Драма в 3-х актах:
Акт 1.
Приходя утром на работу вы открываете свой трекер задач и видите следующее: нужно реализовать игровую бомбу. Вы садитесь кодить, сама задача показалась вам очень простой и буквально за пару часов вы справились. Делов-то добавить красивые эффект, таймер, красивый эффект и нанесение урона.
Акт 2. Первые проблемы.
На следующий день вы обнаруживаете, что у вас в игре есть враги, на которых не действует взрывчатка. Так, вы открываете класс бомбы и делаете проверку на тип врага. Если он устойчив к взрыву, то он получает 0 урона. Через некоторое время в игру добавляют тип врагов, которые наооборот чересчур чувствительны к урона, и вы опять открываете уже давно позабытый скрипт бомбы и дописываете еще одну проверку. Но ведь так хотелось бы забыть про него, мы ведь пишем новых врагов, а надо обратно лезть в бомбу и так далее. Тут вы понимаете, а если бы у меня было много систем, которые работали подобно бомбе, тогда, написав нового врага мне бы пришло редактировать каждый из них. Их ведь может быть десятки! Нет, так дело не пойдет, надо что-то с этим делать.
Акт 3. Решение проблемы.
Вы понимаете, что все ваши враги, это дочерние классы Enemy, в котором есть метод GetExplosionDamage(). Хммм, думаете вы, а что если просто сделать его виртуальным и в дочерних классах просто дописывать то, что надо. Таким образом вы сможете написать один раз нанесение бомбой урона через метод GetExplosionDamage(), а уже если надо, то в дочерних классах дописать получение 0 урона или наоборот двойной порции. Вот оно, решение найдено, теперь все работает отлично и гибко!
Надеюсь, что данный пример и разбор был вам полезен. Также, если под этим постов будет много лайков, то я начну прикреплять примеры кода в Unity, чтобы вам стало еще более понятно.
Всем спасибо за внимание.
Скрипты C#/JS | Unity3d запись закреплена
SOLID. Часть 2.
Open/Closed Principle
Принцип закрытости/открытости:
Объекты и сущности должны быть открыты для расширения, но закрыты для модификации.
Показать полностью…
А теперь капнем глубже и простыми словами. Примером будет выступать ситуация, в которой побывает почти каждый программист в геймдеве. Надо разработать логику атаки персонажа. Далеко ходить не будем, возьмем того же робота из прошлого примера. Вы наливаете себе чашечку кофе, уже представляете в голове, как у вас будет отдельный класс под атаку робота, ведь вы уже знакомы с принципом единственной ответственности, и начинаете творить. Спустя некоторое время, вы откидываетесь на спинку стула и смотрите на свое творение. Оно почти прекрасно, думаете вы, перетаскиваете вашу карточку в трекере заданий в done, и в отличном расположении духа отправляетесь домой. Но, спустя некоторое время, вы видите у себя в задачах, что робот теперь может не только пулями стрелять, но и огнеметом обзавелся. Так, думаете вы, надо подредактировать код, докинуть в него конструкцию switch или воспользоваться старым добрым if. Спустя несколько часов работы, все готово, робот теперь может и огоньком врага подогреть и пулями отпугнуть. Но еще через недельку, вам приходит задача, что он теперь может и лазером жахнуть, ладно, думаете вы, от еще одного if никто не умрет. Еще неделя, еще один тип атаки, еще if… Спустя несколько месяцев скрипт вашей атаки уже по размерам может посоревноваться с войной и миром. Такс, думаете вы, где-то я явно оплошал.
А вот как было бы правильно. Прочитав эту статью, вы набрались знаний и сели заново проектировать атаку робота. Так, думаете вы, логика атаки явно будет изменяться, так что надо предусмотреть ее модификацию, но сделать так, чтобы основной класс обработки атаки не раздувался. Поэтому вы прописываете базовую логику атаки, а-ля просто ее запуск по нажатию на клавишу. Но сам запуск логики мы будем производить через интерфейс, т.е. само нанесение урона, спавна каких-то эффектов и еще особенности, которые будут присущи какому-нибудь типу атаки, будут уже в классе, которые реализует интерфейс IAttackType. В этому интерфейсе будет всего одна функция Attack(). А классы LazerAttack, BulletAttack и т.д. будут реализовывать логику атаки. Таким образом у вас будет класс PlayerAttack, а в нем будет переменная типа IAttackType, которая будет в себе содержать ссылку, на нужный нам класс, который реализует интерфейс IAttackType. Таким образом, когда вас попросят реализовать еще какой-нибудь вид атаки, то вы просто создадите класс, который реализует интерфейс IAttackType и все. А когда вашего PlayerAttack не изменится. А подмену ссылки в зависимости от выбранного вам типа атаки, можете сделать в классе AttackTypeSelect. Теперь вы можете создать новые типы атак не модифицирую PlayerAttack и соблюдая принцип открытости/закрытости.
Также хочу предложить вам такой вот образ, который поможет вам запомнить саму структуру принципа. Представьте робота, у которого к руке приделан пулемет, потом к этой же руки приделывается огнемет и так далее. Теперь взгляните на эту руку, она выглядит громоздко и не практично. А, если мы сделаем так, что на руке у нас будет насадка, на которую мы поочередно сможем цеплять нужное нам оружие, то это будет вполне удобно, и рука робота не будет перегружена, а будет выглядеть красиво и лаконично. Так вот, этой насадкой и является наш интерфейс!
Все спасибо за внимание!
Скрипты C#/JS | Unity3d запись закреплена
Если вы программист, то, мне кажется, вы не раз слушали о SOLID, о да, эта аббревиатура очень известна в кругах разработчиков. И почти на каждом собеседовании вас попросят пояснить за этот набор букв. Так что же таит в себе SOLID, давайте неспела разберемся.
Показать полностью…
Сначала я думал вставлять код в данную статью, но это выглядит очень не аккуратно и громоздко, так что я отказался от этого. Я попытаюсь дать вам какой-нибудь хорошо запоминающийся пример, который вы вспомните, когда будете проходить собеседование или писать код. Но сначала немного теории.
SOLID — принципы объекто-ориентированногопрограммирования.
SOLID это аббревиатура пяти основных принципов проектирования в объектно-ориентированном программировании — Single responsibility, Open-closed, Liskov substitution, Interface segregation и Dependency inversion (принципы единственной ответственности, открытости / закрытости, подстановки Барбары Лисков, разделения интерфейса и инверсии зависимостей)
Аббревиатура SOLID была предложена Робертом Мартином, автором нескольких книг, широко известных в сообществе разработчиков. Эти принципы позволяют строить на базе ООП масштабируемые и сопровождаемые программные продукты с понятной бизнес-логикой.
Single responsibility (принцип единственной ответственности)
Open-closed (принцип открытости / закрытости)
Liskov substitution (принцип подстановки Барбары Лисков)
Interface segregation (принцип разделения интерфейса)
Dependency inversion (принцип инверсии зависимостей)
Single responsibility principle
Итак, начнем с одного из самых простых принципов, коим является принцип единственной ответственности. Он гласит, что у вашего класса должна быть только одна причина для изменения. А под обязанностью здесь понимается набор функций, которые выполняют единую задачу. Суть этого принципа заключается в том, что класс должен выполнять одну единственную задачу. Но, думаю, тут лучше всего перейти сразу к примеру, так будет понятнее. Полагаю, что подавляющее большинство читающих именно создатели игр, поэтому и пример будет основан на моменте из разработки игры.
Представьте робота. Он довольно современный, поэтому умеет ходить, стрелять, летать, и имеет какой-то запас жизней. Уже вполне себе игровой персонаж или противник. Вы садитесь программировать вашему роботу мозги, строчки кода вылетаю из-под ваших пальцев, потом вы стираете ладонью пот с лица и понимаете, да, вот он, мозг вашего детища под названием RobotController.
Всего один скрипт, но функционал та такой, он с помощью него и летает, и стреляет, и прыгает, да чего он только не делает. Но вот проходит какое-то время и вы понимаете, что хотите, чтобы летал он уже иначе, да и добавить ему систему защиты не мешало бы, и ваш код начинает расти. И потом опять и опять, вы что-то добавляете и что-то меняете, игра ведь развивается. И как-то, снова открывая мозг вашего робота для каких-то изменений, вы видите штук 30 переменных, столько же функций и понимаете, что ваше творение превратилось в свалку функций и переменных.
Но давайте вернемся назад во времени и вы подойдет к этой задаче с умом. Поймете, что каждому действию можно написать свой класс, ходить он будет в MoveLauncher, стрелять в AttackLauncher, и т.д., и у вас получится много маленьких и аккуратных классов, и потом, когда вы захотите что-то убрать или добавить, вам придется убрать один тип лаунчера и вставить другой. Система будет минималистична и понятна. Он стал словно модульным и каждый модуль отвечает за свою функцию(обязанность). Так что вы можете легко убрать какой-то и вставить новый. Мне сразу в голову приходит один телефон, который когда-то активно рекламировали.
И пускай ваш код, будет таким же, как и это телефон!
Надеюсь, что пример был не плохим и понятным, и вы запомните его! Теперь, когда будете создавать свой новый шедевр, вспоминайте иногда этого робота или телефон, но не злоупотребляйте этим принципом, так как он может уже сыграть не во благо, а во зло.
Всем спасибо за прочтение!
Скрипты C#/JS | Unity3d запись закреплена
Когда я общался с другими разработчиками, меня часто интересовал вопрос: какие вопросы вы задаете на собеседованиях на middle, junior или senior unity3d разработчик? И почти каждый раз упоминались принципы программирования, так что я решил посвятить небольшую статью именно им. Также они в целом будут полезны для того, чтобы сформировать правильный подход к написанию кода.
Показать полностью… Сейчас есть программисты, у которых 2-3 года опыта работы, но они не знают простых правил написания хорошего и качественного кода, это будет скорее вводная часть, потому что самый сок – это SOLID принципы, но их мы оставим для второй части.
Принцип программирования KISS — keep it simple stupid (делайте вещи проще).
KISS — это принцип проектирования и программирования, при котором простота системы задается как основная цель. Есть два варианта расшифровки аббревиатуры: «keep it simple, stupid» и более корректный «keep it short and simple».
В проектировании следование принципу KISS выражается в том, что:
не имеет смысла реализовывать дополнительные функции, которые не будут использоваться вовсе или их использование крайне маловероятно, как правило, большинству пользователей достаточно базового функционала, а усложнение только вредит удобству приложения;
не стоит перегружать интерфейс теми опциями, которые не будут нужны большинству пользователей, гораздо проще предусмотреть для них отдельный «расширенный» интерфейс (или вовсе отказаться от данного функционала);
В программировании следование принципу KISS можно описать так:
не имеет смысла беспредельно увеличивать уровень абстракции, надо уметь вовремя остановиться;
бессмысленно закладывать в проект избыточные функции «про запас», которые может быть когда-нибудькому-либо понадобятся;
не стоит подключать огромную библиотеку, если вам от неё нужна лишь пара функций;
декомпозиция чего-то сложного на простые составляющие — это архитектурно верный подход ;
Принцип программирования DRY — don’t repeat yourself (не повторяйте себя).
Если код не дублируется, то для изменения логики достаточно внесения исправлений всего в одном месте и проще тестировать одну (пусть и более сложную) функцию, а не набор из десятков однотипных. Следование принципу DRY всегда приводит к декомпозиции сложных алгоритмов на простые функции. А декомпозиция сложных операций на более простые (и повторно используемые) значительно упрощает понимание программного кода. Повторное использование функций, вынесенных из сложных алгоритмов, позволяет сократить время разработки и тестирования новой функциональности.
Следование принципу DRY приводит к модульной архитектуре приложения и к чёткому разделению ответственности за бизнес-логику между программными классами. А это — залог сопровождаемой архитектуры. Хотя чаще не DRY приводит к модульности, а уже модульность, в свою очередь, обеспечивает принципиальную возможность соблюдения этого принципа в больших проектах.
В рамках одного программного класса (или модуля) следовать DRY и не повторяться обычно достаточно просто. Также не требует титанических усилий делать это в рамках небольших проектов, где все разработчики «владеют» всем кодом системы. А вот в больших проектах ситуация с DRY несколько сложнее — повторы чаще всего появляются из-за отсутствия у разработчиков целостной картины или несогласованности действий в рамках команды. Следовать принципу «don’t repeat yourself» в рамках больших проектов не так просто, как это может показаться на первый взгляд. От разработчиков требуется тщательное планирование архитектуры, а от архитектора или тимлида требуется наличие видения системы в целом и чёткая постановка задач разработчикам.
В пректировании DRY тоже имеет место — доступ к конкретному функционалу должен быть доступен в одном месте, унифицирован и сгруппирован по какому-либо принципу, а не «разбросан» по системе в произвольных вариациях.
Принцип программирования YAGNI — you ain’t gonna need it (Вам это не понадобится).
Основная проблема, которую решает принцип YAGNI — это устранение тяги программистов к излишней абстракции, к экспериментам «из интереса» и к реализации функционала, который сейчас не нужен, но, по мнению разработчика, может либо вскоре понадобиться, либо просто будет полезен, хотя в реальности такого очень часто не происходит.
«Бесплатных» функций в программных продуктах просто не бывает. Если рассматривать материальную сторону, то любые ненужные, но фактически реализованные «фичи» оплачиваются либо Заказчиком (в бюджет закладываются расходы на те функции, которые не нужны), либо Исполнителем из прибыли по проекту. И тот, и другой варианты с точки зрения бизнеса неверны. Если же говорить о нематериальных затратах, то любые «бонусные» возможности усложняют сопровождение, увеличивают вероятность ошибок и усложняют взаимодействие с продуктом, — между объёмом кодовой базы и описанными характеристиками есть прямая зависимость. Больше написанного кода — труднее сопровождать и выше вероятность появления «багов», тут очень уместна поговорка: «лучший код — это ненаписанный код».
Принципы YAGNI и KISS очень похожи, если KISS нацелен на упрощение и полезен в плане работы с теми требованиями, которые имеют место быть, то YAGNI более категоричен и применяется для ограждения проектов по разработке ПО от «размывания» их рамок.
Принципы программирования SOLID.
SOLID – это принципы проектирования, которые позволяют нам справляться с большинством проблем проектирования программного обеспечения. Роберт К. Мартин составил эти принципы в 1990-х годах. ОНи предоставляют нам способы перехода от тесно связанного кода и небольшой инкапсуляции к желаемым результатам слабо связанных и инкапсулированных элементов. SOLID является аббревиатурой от следующего.
S: Принцип единой ответственности (SRP)
O: Принцип открытости и закрытости (OSP)
L: Принцип замещения Лисков (LSP)
I: Принцип разделения интерфейса (ISP)
D: Принцип инверсирования зависимостей (DIP)
Сегодня поговорим о том, как писать скрипты для Unity Editor. Статья рассчитана на тех, кто уже знаком с Unity3D, что-то успел сделать, но еще не решился попробовать писать скрипты для эдитора.
Если коротко — то в режиме эдитора скриптами можно сделать абсолютно всё тоже самое, что и в режиме игры.
Начнем с простого. Допустим, мы хотим в режиме эдитора создать 10 кубиков и расположить их в линию. Для начала давайте упростим задачу и забудем про эдитор, давайте сделаем так, чтобы эти кубики создавались при старте приложения.
Теперь попробуем выполнить этот код в режиме эдитора, для этого нужно к коду добавить всего лишь один волшебный атрибут [ContextMenu()] к функции Create10Cubes():
так чтобы код выглядел вот так:
Теперь, если мы нажмем правой кнопкой по заголовку скрипта, там появится пункт CreateCubes, при нажатии на который функция точно также будет выполнена.
Важное замечание: функция, помеченная атрибутом ContextMenu, не должна иметь параметров, вернее, если у нее будут параметры, вы не сможете вызвать таким способом.
Лично я применяю такой способ, когда нужно что-то сделать с группой объектов, например, выключить отбрасывание теней у всех детей объекта, у которых в названии встречается «withoutshadow»:
Вобщем способ хорош для одноразовых действий над кучей объектов — быстренько накидали нужный код в отдельном классе, кинули на нужный объект и тут же удалили этот класс к едрене фене.
Теперь давайте решим следующую задачу: мы хотим запечь occlusion culling. Для этого нам необходимо пометить галочкой Occluder Static все объекты, которые бубдут загораживать другие объекты, и галочкой Occludee Static все, которые будут скрываться за Occluder`ами. То есть нам нужно вычленить все статичные объекты, непрозрачным объкетам поставить обе галки (на самом деле все), прозрачным — только Occludee, а Occluder выключить.
Казалось бы, ну что такого, пробежался по сцене ручками — расставил кому нужно галочки — и все. Но проблема в том, что объектов в сцене может быть много и в процессе развития проекта сцена скорее всего будет меняться. Следить самому за всеми этими галочками — с ума можно сойти. Поэтому мы напишем маленький скриптик, который делает это за нас.
Для начала напишем полезный код, который выполняет нашу работу, а далее оформим это в отдельный виззард:
Задачи здесь две:
1) Найти интересующие нас объекты в сцене;
2) Расставить нужные галочки.
Оформим код в виде отдельной команды, для того чтобы его можно было вызывать из любого места и он не зависел от того, в каком виззарде он будет вызываться. Внимание: файл, содержащий следующий код, необходимо поместить в папку под названием Editor, это нужно для того, чтобы этот код не попал в основной билд:
Здесь мы предполагаем, что статичные объекты уже до этого каким то образом нашли (скорее всего ручками) и отметили их галочкой Static, а значит, в том числе и BatchingStatic.
Теперь давайте оформим отдельный виззард, чтобы можно было удобно вызывать эту команду:
Тут нам пригодится класс EditorWindow.
На этом пока закончим наш обзор, он получился далеко не полным.
В следующих статьях я планирую описать, как можно создавать кастомные инспекторы для ваших классов, как вмешиваться в процесс импорта ассетов, как можно поставить запекать тени на 20-ти уровнях по очереди и получить скриншоты с результатом себе на почту.
Два основных компонента у объекта в Unity3D — это Transform и GameObject.
GameObject
GameObject — основа, контейнер, который содержит в себе все компоненты любой объект в Unity3D. Чтобы удалить, к примеру, игровой объект — удалять нужно именно GameObject этого объекта. Для доступа к GameObject — используется переменная, которая присутствует по умолчанию в любом скрипте, унаследованном от MonoBehaviour (то есть в любом скрипте, созданном через Unity3D).
Получение ссылки на игровой объект
Данным способом можно из одного скрипта получить ссылку на другие игровые объекты и управлять ими, их дочерними объектами, а также их компонентами.
Уничтожение игрового объекта
Данным способом можно удалить игровой объект.
Активация/деактивация игрового объекта
Деактивация объекта аналогична снятия галочки инспекторе Unity3D, которая обведена красным цветом на скриншоте ниже.
Деактивация элемента деактивирует также все его дочерние объекты и останавливает выполнение в их скриптов.
Добавление новых компонентов и скриптов игровому объекту
Таким образом можно добавить абсолютно любой компонент, либо скрипт, который можно добавить в редакторе Unity3D.
Получение доступа к компоненту игрового объекта
Таким же образом можно получить доступ к любому компоненту игрового объекта.
Переименование игрового объекта. Считывание имени объекта
Сделать объект статичным
Данный код аналогичен установке/снятию галочки в редакторе Unity3D (на скрине ниже).
Установить слои игровому объекту, а также считать их
Установить тэг игровому объекту, а также его считывание
Transform
С трансформом всё немного проще — этот компонент не является основой, но тем не менее — является основной и, главное, неотъемлемой частью GameObject’а. Он отвечает за месторасположение объекта на сцене, его «вращении», размерах, а также содержит информацию о дочерних и родительском объектах.
Это единственные компонент, который невозможно удалить из GameObject.
Изменение положение объекта
За положение объекта на сцене отвечает элементы transform.position и transform.localPosition.
Они оба являются переменной типа Vector3 и имеют в себе 3 главных составляющих x,y и z, которые соответствуют координатам в трехмерном пространстве. Следует учитывать, что x, y и z невозможно менять напрямую — они только для чтения. Чтобы добавить единичку к x — нужно добавить к самому transform.position новый Vector3, который равен (1,0,0), что добавить к x единицу, а к y и z — нули.
Чем же отличаются transform.position и transform.localPosition?
Их главное (и единственное отличие) заключается в том, что position — показывает и принимает координаты объекта, относительно мировых координат, а localPosition — относительно родительского объекта. Если же игровой объект является «корневым», то есть у него нет родительских объектов, то position и localPosition будут равны.
Движение объекта
Сначала рассмотрим элементарные варианты.
Как мы уже говорили — position (буду далее использовать именно его, так как отличия от localPosition только в том, относительно чего эти координаты) является переменной типа Vector3. Поэтому для его изменения нужно либо прибавить к нему другой вектор, либо вычесть другой вектор, либо заменить его другим вектором.
Рекомендуется использовать функцию transform.Translate.
Это уже не переменная, как transform.position — это функция. У неё есть два входящих параметра:
- Vector3, который отвечает за то, в каком направлении будет двигаться объект;
- Space.Self/Space.World — то, относительно чего будет двигаться игровой объект. Space.Self — аналогичен transform.localPosition, а Space.World — аналогичен transform.position.
Вращение объекта
За вращение объекта отвечает компонент transform.rotation, transform.localRotation и функция transform.Rotate.
Здесь все аналогично transform.position. Кроме одного, несмотря на то, что в редакторе Unity3D Rotation представляет собой Vector3, то есть вращение относительно оси X, оси Y, оси Z. Но в коде оно представлено в виде кватернионов. Что такое кватернион — отдельная история. И обычно её изучают в вузах. По факту — знание кватернионов не обязательно для разработки игр. К счастью разработчики Unity3D это понимают и сделали две удобные для программистов вещи:
- Функция transform.Rotate(Vector3 vector, Space.World(либо Self));
- Функция Quaternion.Euler(float x,float y,float z), которая как раз возвращает кватернион;
Меньше слов — больше кода:
Вместо rotation можно применять localRotation, аналогично position.
Такой подход аналогичен transform.Translate и также является более производительным.
Поиск других объектов на сцене
Есть два подхода поиска объекта на сцене.
- GameObject.Find(«имяОбъекта»); Он же «пушка по воробьям». Несмотря на кажущуюся скорость — метод является достаточно прожорливым и при частом использовании на большой сцене может стать большой проблемой. Однако он же самый простой способ (хотя и ненадежный). А ненадежный он потому, что редактор Unity3D позволяет давать одинаковые имена объектам. А GameObject.Find возвращает только один элемент, который он найдет первым.
- transform.FindChild(«имяДочернегоОбъекта») — функция возвращает переменную типа transform нужного объекта. Для доступа к GameObject этого объекта особых усилий прилагать не нужно, так как ссылка на него уже содержится в transform (как и ссылка на transform содержится в GameObject’е).
Также можно запрашивать дочерние элементы по их номеру:
Также дочерний элемент может запросить родительский, а также родительский родительского и так далее:
В следующих статьях будет информация о том, что такое private, public, static, отправление сообщений игровым объектам.
12 комментариев для “Скрипты в Unity3D. Урок 0. Основы”
Отличный урок! Планируется ли продолжение?
Здравствуйте! Да, продолжение планируется и уже есть заготовки, но времени, увы, нет совсем =(
Присоединяюсь к предыдущем комментатору, очень жду продолжения.
Ну и отдельное спасибо за этот урок.
var objectBoxColl > ещё бы растолковать,нубу ,почему, где, и в каком случае слова пишутся с маленькой и большой буквы.
Типа — функции с маленькой, переменные с большой.
Почему object с маленькой а BoxCollider c большой.
И краткие примеры, как эти коды можно в коде применять..
//и кто такой «anotherTransformLink»
var anotherTransformLink = childGameObject.transform;
И коментарии бы типа:
var childTransform = transform.FindChild(«myChild1»); // находим myChild1 помещаем в childTransform
var childGameObject = childTransform.gameObject; // тут что происходит я хрен чё понимаю откуда что берётся
var anotherTransformLink = childGameObject.transform; // и зачем столько букав
А так-то нормуль, есть что законспектировать.
Здравствуйте! Спасибо за советы, я обязательно их учту при написании следующих статей.
Постараюсь вкратце ответить на ваши вопросы.
1) Слова в коде относятся к командам, классам, интерфейсам, или именам переменных. Обычно в C# с большой буквы пишется класс, интерфейс, или переменная с модификатором доступа ‘public’ (не забываем про функции). Где, как и в каких случаях что используется тяжело описать, так как это основы языка программирования C#.
Например:
var myObject = new MyObject().
Конкретно в данном случае — MyObject — это класс. А myObject — это конкретный экземпляр класса MyObject.
А вот другой пример:
public GameObject MyGameObject;
Это публичное свойство класса типа GameObject. Сам экземпляр данного класса называется MyGameObject и может быть доступен как и изнутри самого класса, так и из других классов, у которых есть ссылка на данный экземпляр класса.
2) Почему objectBoxCollider с маленькой, а BoxCollider с большой? ObjectBoxCollider — это имя класса, а objectBoxCollider — это его экземпляр..
К тому же Unity3d очень активно использует наследование (хотя бы взять любой скрипт — он наследован от MonoBehavior. Нужно знать как работает наследование и какой базовый функционал (и какие свойства) уже доступны «из коробки» у любого класса, который будет наследован от него.
Всё-таки Unity3D подразумевает, что у разработчика есть базовые знания C#, или JS. Я бы вам порекомендовал вначале почитать статьи с замечательного сайта https://metanit.com/sharp/tutorial/
Лучше чем там я объяснить всё равно не смогу 🙂
оО, о как, очень рад что сайт живой,ато вновь и вновь прочёсываю инет своими тегами, гляжу — котодомик))
думаю — та-ак, помню что там чтото полезное было пойду ещё загляну) а тут опаньки, живая планета,.
только вот пользователи сетей видать не очень жалуют домен «рф» и встречается он редковато,
буду значит наблюдать за сайтом,по возможности единомышленников подтягивать,
пс
C#
transform.position += new Vector3(1,0,0); // добавляем к X единице (смещаем на единицу)
transform.position += new Vector3(1,0,2)*Time.deltaTime; // двигаем объект в реальном времени с установленными значениями
по осям х и z
int speed = 5;
void Start()
transform.position += new Vector3(speed,0,0)*Time.deltaTime;//движение по оси х с заданием параметра(скорости) через переменную speed
transform.position += new Vector3(1,0,1)*speed*Time.deltaTime;// движение по заданным осям со скоростью установленной переменной speed
вот типа того бы, с пояснениями и дальнейшим развитием их применения
ещё поподробней бы про кватернионы и ейлеры, каким образом кватернион вывести в вектор3
про ригидбоди — нет нигде информации, как ограничивать угол поворота по осям,матф.кламп
как использовать драг по разным осям с разным значением
гравитация и енерция их ограничения и направления,
почему объект в вертикальном положении может подвергаться гравитации а в горизонтальном уже нет..+-
45ˆ
подробного про get set не хватает с примерами, пишут что много чего можно делать, а примеров нет, даже въехать сложно как выжать из него пользу чтобы фантазия стартонула….
учил с++ по Шилдту,3 изд,(в с# (юнити) нету чтоле *и& ?(ссылки, указатели) что то не встречал в скриптах)
так вот чего там нехватает — примеров хотябы с кошками и блошками
тут ещё надо въехать в API, как спаять школьный мелок с мышкой и клавой
а так — ждём продолжения ,всё довольно доходчиво преподносится..
Спасибо за отзыв! Приятно! 🙂
Стараюсь поддерживать актуальность сайта по мере сил и возможности.
Отдельное спасибо за темы для новых статей.
Спасибо очень сильно помог, ещё раз большое спасибо.
есть vector3 как взять по нему gameObject?
Здравствуйте. К сожалению никак. Vector3 это структура данных, которая содержит информацию о точках X,Y,Z.
Vector3, как и Vector2 стоит рассматривать наравне с int, string, bool, float..
Например. Контейнер gameObject всегда содержит ссылку на компонент (обязательный) transform.
А transform содержит много свойств, отвечающих за позицию и размер объекта на сцене. Одно из свойств, как раз position — является Vector3.
Через любой компонент можно получить ссылку на gameObject, как и через gameObject можно получить ссылку на любой компонент, который данный gameObject содержит внутри себя.
Например: var boxColl >();
Но Vector3 не является компонентом в Unity3D.
Являются компонентами только те объекты, которые можно добавить к gameObject’у, используя графический интерфейс редактора Unity3D.
Спасибо за хорошо изложенную информацию) Сделал по туторам три простеньких игру, просто повторяя все за автором курса. Но во многое не въехал. Тут почитал, многое встало на свои места сразу. У вас талант к ясному изложению. Не бросайте это дело)
Здравствуйте! Большое спасибо за ваш отзыв 🙂
К сожалению сейчас нет особой возможности вести блог.
Но если у вас есть какие-то конкретные вопросы по Unity3D, то я могу с удовольствием на них ответить.