Русский
Русский
English
Статистика
Реклама

Школа программирования

Интервью с СЕО FitBase будущее за автоматизацией

28.05.2021 18:18:56 | Автор: admin

Знаем, как сложно родителям выбрать профессию для своего ребенка. Этот выбор определит, будет ли он доволен своей жизнью и будет ли он с удовольствием просыпаться по утрам, чтобы пойти на работу. Для того, чтобы немного облегчить выбор родителей, команда школы программирования для детей Пиксель провела серию интервью с состоявшимися специалистами в мире IT. В предыдущем интервью мы рассказали о менеджере проектов АСУ.

Василий Суворов, CEO FitBaseВасилий Суворов, CEO FitBase

Как сделать классный продукт по автоматизации бизнес-процессов в сфере фитнеса, как набрать крутую команду программистов и где брать вдохновение на новые решения, расскажет CEO FitBase Василий Суворов.

Сколько тебе лет? Какой ВУЗ окончил?

Мне 33 года, окончил МГУС, факультет Информационные технологии.

Расскажи, почему ты решил заняться программированием.

Я плохой разработчик, я могу написать какие-то простые вещи на PHP или SQL-запрос. У меня лучше получается делать прототипы, писать технические задания и выяснять потребности наших клиентов. Вообще разработка тесно связана с автоматизацией любых задач. На мой взгляд, это основная задача инженера придумать как сделать процесс максимально автоматизированным. Это очень крутое чувство, когда что-то создаешь придумал, запрогал и видишь, как работает твое детище. И неважно, что это простой скрипт по парсингу данных или сложный продукт, который позволяет автоматизировать фитнес-клуб или большой завод.

Ты учился программированию самостоятельно или ходил на дополнительные курсы, кружки?

Я уже в школе начал самостоятельно увлекаться веб-дизайном и разработкой, в основном веба. В универе преподавали, на практике в основном по мануалам и на конкретных задачах.

Тогда не были распространены кружки, курсы по программированию. В веб-дизайне все просто открываешь сайт, который нравится и смотришь, как он написан (это то, что касается верстки). В помощь форумы, статьи и все, что возможно нагуглить. Еще у меня была книга PHP и MySQL. Разработка веб-приложений, автор Томсан Лора.

Расскажи о своей работе, какие у тебя обязанности, сколько зарабатываешь?

Я CEO компании, и мои главные задачи связаны с моей командой чтобы моя команда была сытая, была вдохновлена проектом, и чтобы у них не было препятствий для выполнения задач. Все это тесно связано с продуктом и лояльностью наших клиентов. Мне кажется, что моя основная работа связана с коммуникациями: с командой, клиентами, стартап- и фитнес-сообществами. Еще я пишу технические задания, рисую прототипы, считаю различные метрики, провожу интервью клиентов, занимаюсь позиционированием продукта и ищу слабые стороны в наших процессах. В общем, сейчас я не программирую совсем. Про зарплату не скажу, не имею права разглашать эту информацию. Получаю среднюю по рынку.

Команда FitBaseКоманда FitBase

Как ты подбираешь программистов в свою команду? Какими качествами должен обладать крутой специалист по твоему мнению? У меня плохой опыт поиска разработчиков через привычные для этого площадки вроде HeadHunter или Мой круг. Если нам требуются люди, я в первую очередь спрашиваю команду, есть ли кого посоветовать. И таких сотрудников у нас большинство. Из последних кейсов поиска сотрудников могу поделиться одним лайфхаком. Для поиска мобильного разработчика мы проанализировали сообщество фреймворка React Native, выявили там самых активных ребят, рассказали про продукт и предложили присоединиться к нему. В итоге мы нашли крутых мобильных разработчиков.

Рынок разработки перенасыщен предложениями, поэтому приходится не только мотивировать финансовой стороной, но и самим продуктом интересность, его социальные функции, имеет ли он глобальную цель. Мне кажется, что это важно.

Разработчик должен иметь хорошую фантазию он должен представлять, как будет работать его код еще до того, как он написан.

Знаю, у тебя есть сын. Ты бы отдал его в программирование? Знаешь какие-нибудь школы по программированию?

Да, мы пробовали отдавать его в робототехнику, но до нее долго добираться. Сейчас у нас открылась одна школа программирования рядом, летом начнет туда ходить. Ему это интересно. Еще он фанат Майнкрафта. Мне нравится, что есть игры, которые позволяют создавать свою собственную реальность.

Какие профессии в области IT наиболее перспективные по твоему мнению?

Я думаю, будущее за нейроинтерфейсами, робототехникой и автоматизацией.

Нейроинтерфейс это такая штука, которая позволяет связать мозг и компьютер напрямую. Мы не будем печатать или отдавать команды голосом, подумал и действие совершилось. Как рукой двигаем, так и компьютером, телефоном или роботом можно будет управлять. Это суперкрутой рынок. Илон Маск уже выпускает первые прототипы.

Расскажи, чем занимаешься в свободное от работы время? Ты проводишь много времени в кругу программистов. Развей миф о том, что программисты это сутулые бледные парни в огромных вязаных свитерах.

Я люблю активных отдых: бегаю, гоняю на велике, хожу в горы и походы. Этот миф идет с тех времен, когда программированием в основном занимались люди из научной сферы, которые решали стратегические и фундаментальные задачи по запуску ракет, освоению космоса и военные задачи. Сейчас разработчики это очень разные люди с разными интересами. Например, наш тимлид играет на барабанах.

Подробнее..

Разбор вступительных задач Школы Программистов hh.ru

26.10.2020 10:06:40 | Автор: admin
20 октября закончился набор в Школу программистов hh. Он длился два с половиной месяца. Мы благодарим всех участников, уделивших время попытке поступить к нам. Надеемся, вам понравились задания и вы получили удовольствие от их решения!

Приглашаем посмотреть задания, которые мы использовали для онлайн-этапа отбора, а также решения для них.
image

В этом году количество желающих превзошло все предыдущие, и на нашей платформе тестирования было создано более 3700 учетных записей. Участникам предлагалось решить два задания, а на их решение мы выделяли две недели и 15 попыток проверки на каждое.

CheckUp


После заполнения анкеты проходит первый этап отбора на автоматизированной платформе тестирования CheckUp. Это собственный продукт, прототип которого был разработан учениками нашей Школы пару лет назад. С тех пор он постоянно поддерживается, обрастает новыми функциями и помогает нам организовывать отбор в Школу.

Интерфейс отправки решений
Часть интерфейса CheckUp

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

Числа


Только факты: из 3700 учетных записей лишь 1318 отправили на проверку хотя бы одно решение. С одним заданием справились 483 участника, а с обеими задачами 283.
Из людей, которые отправили хотя бы одно решение для первого задания справились с ним 35% участников, для второго задания этот процент гораздо выше почти 60%. Возможно это связано с тем, что первое задание кажется легче, и попробовать решить его проще.
В общей сложности системой было проверено 8986 решений, а нами и участниками написано 3720 сообщений в чате.

То, ради чего все пришли


Как мы и обещали в чате поддержки CheckUp, в этой статье я подробно разберу задания этого года и дам ссылки на тесты, которые мы использовали для проверки.

Преобразования слов


На вход подается 2 подстроки. Нужно определить, можно ли превратить первую во вторую, заменяя одни буквы на другие, с учетом следующих правил:
  • участвуют только буквы русского алфавита а-я;
  • все буквы в нижнем регистре;
  • за один шаг нужно преобразовать все вхождения одной буквы в другую.


Например:
хабр бобр здесь преобразование возможно (х б: бабр, а о: бобр)
корм кров здесь тоже возможно, но, чтобы поменять местами о и р понадобится дополнительная буква, не используемая в подстроках (о я: кярм, р о: кяом, я р: кром, м в: кров)
бобр добр а здесь уже нет, потому что за шаг меняются все вхождения, и б не сможет стать одновременно и д и б.

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

1. Наш алфавит конечен
Во втором примере мы использовали дополнительную букву. Дело в том, что в нашем алфавите их всего 33, и если все они используются и в первой, и во второй подстроке нам негде взять букву для замены. Самый простой пример такого:
абвгдеёжзийклмнопрстуфхцчшщьыъэюя бавгдеёжзийклмнопрстуфхцчшщьыъэюя
Здесь используются все 33 буквы и мы не можем поменять местами б и а.

2. Необходимо преобразовать слово только в одну сторону
Было несколько решений, которые использовали проверку слов на изоморфизм, но она избыточна третий пример преобразовать нельзя. А вот если поменять местами слова добр бобр, тут преобразование возможно.

3. Для замены хватит всего одной буквы
Из первого пункта может сложиться ощущение, что если в левой подстроке есть весь алфавит, то преобразование всегда невозможно, однако это неверное заключение. Если во второй строке используется не весь алфавит, можно использовать ту букву, которой там нет:
абвгдеёжзийклмнопрстуфхцчшщьыъэюя бабгдеёжзийклмнопрстуфхцчшщьыъэюя
Здесь во второй подстроке, вместо буквы в стоит буква б, позволяющая сначала заменить а на в, а затем использовать освободившуюся а. (а в: вбв..., б а: вав..., в а: баб...)

4. Что делать со строками разной длины
На этот и следующий вопрос мы отвечали в чате, но их тоже укажу, на случай, если кому-то интересно.
Многие сообразили, что как ни преобразовывай буквы в таких строках, одинаковыми они не станут. Так и есть, для этих строк можно было сделать отдельную проверку и сразу возвращать 0. Фраза про строки разной длины в дополнительной информации к условию была добавлена для того, чтобы решения участников не падали с ошибкой на таких данных.

5. Изначально равные строки
Было несколько вопросов о том, возможно ли преобразование для строк, которые уже равны. Во-первых, 0 шагов это тоже действие. Во-вторых, в задании необходимо ответить на вопрос, можно ли превратить первую строку во вторую, то есть сделать их равными. Так как они уже равны, можно возвращать 1.

Если учесть всё это и вынести в отдельные условия, останется проверить только то, что каждой букве первой подстроки соответствует только одна буква второй.

Пример кода решения на Python:
def check_conversion(str_from, str_to):    if str_from == str_to:        # Если подстроки уже равны        return 1    if len(str_from) != len(str_to) or len(set(str_from)) == len(set(str_to)) == 33:        # Если длина подстрок не равна        # Или количество уникальных букв в обеих подстроках равно 33        return 0    symbols_map = {}    for symbol_from, symbol_to in zip(str_from, str_to):        if symbols_map.get(symbol_from, symbol_to) != symbol_to:            # Если мы пытаемся заменить одну букву на две разных            return 0        symbols_map.update({ symbol_from: symbol_to })    return 1str_from, str_to = input().split()print(check_conversion(str_from, str_to))


Активные вакансии


Петя решил узнать, когда программисту выгоднее всего искать работу на hh.ru. Конечно, когда открыто больше всего вакансий.
Он выгрузил в текстовый файл время открытия и закрытия всех подходящих вакансий за 2019 год.
Теперь нужно определить период времени, когда открытых вакансий было больше всего.
Считаем, что:
  • начальное и конечное время всегда присутствуют;
  • начальное время всегда меньше или равно конечному;
  • начальное и конечное время включены в интервал.

Например:

1
1 5

Здесь всего одна вакансия, соответственно, период, когда вакансий было больше всего тоже один, и занимает он все время жизни вакансии 5 секунд, ответ 1 5.

2
1 3
2 4

Здесь чуть посложнее, с 2 по 3 секунду были активны обе вакансии, такой интервал один, его длина 2 секунды, ответ 1 2.

2
1 2
3 4

Здесь вакансии не пересекались, то есть максимальное количество вакансий одна, однако интервалов, в которые была активна одна вакансия два. Несмотря на то, что в дискретном понимании, все 4 секунды вакансии существовали, непрерывным такой интервал не является, ответ 2 4.

Это задача на то, чтобы представить, как и в каком порядке происходили события. По сути, всё сводится к тому, чтобы собрать время начала и окончания всех вакансий, отсортировать его по возрастанию и пройтись по получившимся моментам времени, с каждой остановкой увеличивая или уменьшая количество активных вакансий, в зависимости от того, начальный это или конечный момент времени.

При этом, после изменения количества необходимо сравнить его с текущим максимальным и обновить максимальное, если текущее его превысило. Если сохранить информацию о том, в какой момент времени это произошло, её можно использовать для вычисления суммарной длительности.

Из тонкостей этого задания можно выделить две:

1. Данные на входе могут быть не отсортированными.
Условия не гарантируют сортировку входных данных, об этом нужно было позаботиться в решении, и это является, по сути, ключом к нему.

2. Данных может быть много, а потому лишние действия могут привести к превышению лимита времени или памяти.
В нашем большом тесте для этой задачи 100 000 вакансий, то есть 200 000 временных точек, что требует от решения быть максимально оптимальным и не использовать лишнего.

Пример кода решения на Python:
vacancies_count = int(input())time_points = []for moment in range(vacancies_count):    start, end = input().split()    # Добавляем информацию о начале и конце активности вакансии, и флаг,     # свидетельствующий о том, является ли этот момент концом активности.    # Флаг понадобится для сортировки и выяснения максимального количества вакансий    time_points.append([int(start), False])    time_points.append([int(end), True])# Учитывая особенности сортировки Python  для совпадающих по времени # моментов первым будет начало интервала, а вторым конец (False < True)time_line = sorted(time_points)max_vacancy_count = 0current_vacancy_count = 0for point_index in range(len(time_line)):    # Если текущий момент - это начало активности вакансии, добавляем,     # если конец - отнимаем    current_vacancy_count += -1 if time_line[point_index][1] else 1    if current_vacancy_count > max_vacancy_count:        max_vacancy_count = current_vacancy_count        # Предыдущий список максимальных, если он был, заменяется новым        max_vacancies_points = [point_index]    elif current_vacancy_count == max_vacancy_count:        # Если количество вакансий снижалось, а затем снова выросло,         # интервалов с максимальным количеством вакансий        # будет больше, чем 1, их индекс добавляется в массив        max_vacancies_points.append(point_index)total_time = 0for point_index in max_vacancies_points:    # Для интервалов с максимальным количеством вакансий  между открытием     # и закрытием не будет других моментов, то есть    # time_line[point_index + 1] - это конец интервала    # Добавляем 1, потому что начальное и конечное время включены в интервал    total_time += 1 + time_line[point_index + 1][0] - time_line[point_index][0]print(len(max_vacancies_points), total_time)


Ссылка на репозиторий, в котором лежат решения для всех трёх языков и наши закрытые тесты: github.com/gooverdian/school-2020-tasks

Мы знаем, что вы сделали...


Не могу не упомянуть несколько огорчающий факт. В этом году было гораздо больше списанных решений. Уже через две недели после старта набора, в двадцатых числах августа, стали появляться первые дубли решений с одним и тем же источником, причем автором этих решений стал таинственный добрый самаритянин, не принимавший участия в школе (или использовавший другие решения для своей учетной записи). Также было много попыток купить решения для наших задач, что уже совсем расстраивает. Итоговое количество списавших в этом году перевалило за 50. Поначалу, мы приглашали таких участников на интервью в обычном режиме, однако, быстро стало понятно, что абсолютному большинству из них не хватает знаний. В итоге, мы приняли решение перенести собеседования с такими участниками на более поздние сроки.

Если вдруг в этом разделе вы узнали себя: пожалуйста, знайте, что после онлайн-этапа с автоматической проверкой всегда будет оффлайн с живым интервью. Используйте свои навыки программирования, а не поиска решений в интернете. Подготовьтесь лучше, и вы справитесь самостоятельно.

Всем ещё раз большое спасибо за участие!
Подробнее..

Кружок робототехники VS технический центр

17.05.2021 16:18:04 | Автор: admin

Обучать детей техническому мастерству, либо программированию можно по-разному. Я нашёл наиболее эффективный способ, при котором вовлеченность детей в процесс максимальна и вы остаётесь не с пустыми карманами.

Детский технический центрДетский технический центр

4 года назад я открыл первый кружок робототехники в небольшом городе. За первые 3 месяца набрал 80 детей на занятия без особого труда и знаний в области маркетинга. Однако за 4 года утекло много воды и сейчас старые методы привлечения детей на занятия уже не работают. Долгие годы в России и странах СНГ активно развивались только спортивные направления, футбол, баскетбол, единоборства. Однако за последние годы количество интеллектуальных кружков и секций росло, как грибы после дождя. Начали формироваться крупные игроки, но до консолидации рынка детского технического образования ещё очень далеко. Вначале появились школы робототехники, после подключилась ментальная арифметика и скорочтение, направленная больше на ребят помладше. Позже подтянулись школы программирования.

За 4 года работы, кружки робототехники, открывающиеся под моим началом, менялись в соответствии с текущими трендами, не забывая о стратегии, обозначенной в самом начале пути - дать детям возможность развиваться технически, и когда придёт время, после школы не тыкать пальцев в небо, а точно знать, по какой специальности пойти учиться дальше и в какой университет или техникум поступать.

Ответ на вопрос "Что запускать, кружок робототехники или технический центр?" многим может показаться очевидным, однако всё не так просто, как кажется на первый взгляд. Ко мне обращается множество людей, по вопросам открытия технической детской школы, и почти все нацелены либо на робототехнику и электронику, либо на школу программирования. На старте пути я был таким же, воплотил в жизнь то, что было ближе - я неплохо разбирался в электронике и построил школу робототехники, но сейчас такой подход прокатит далеко не везде. В прошлых статьях я писал, на чистом альтруизме далеко не уехать - ваш детский центр должен приносить доход, чтобы вы могли обновлять техническую базу и кормить себя и семью. И речь здесь не о получении 20-30 тысяч дополнительного дохода в месяц, речь о получении минимум 100 тысяч рублей в месяц с детского центра. При таком раскладе, руки у вас не опустятся никогда, школа будет непрерывно развиваться, качество подаваемого материала расти, посещать занятия будет всё больше и больше детей.

Как думаете, чему так радуется парень справа?Как думаете, чему так радуется парень справа?

В школе робототехники я довольно быстро уткнулся в стеклянный потолок - заявки на занятия становились всё дороже, экспонента насытилась и прежние методики привлечения клиентов становились неэффективны. И тогда я начал запускать новые курсы. И речь здесь не о пустом добавлении направлений в текущую систему, я начал строить экосистему, где каждый новый продукт дополнял предыдущий. В детском центре, куда ходило 50 человек на робототехнику, и больше было набрать уже слишком дорого, я запустил программирование. Дети уже работали с компьютером, когда учились программировать микроконтроллеры на курсе робототехники, но там я столкнулся с проблемой - программировать нужно на С++, который в базе дети ещё понимали, изучили переменные и условия, но когда дело дошло до циклов, половина отвалилась. На массивах, особенно двумерных всё стало намертво. До сих пор я старался давать детям максимум практики, минимум теории, но здесь этот подход не сработал. Я всячески пытался обучить детей сделать что-то посложнее, чем робота, ездящего по линии, или руку на сервоприводах, но ничего не получалось. Вернее, результат был, но значительно увеличился процент оттока детей. Кто-то понял материал и пошёл дальше, но добрая половина не могла понять ничего, как бы я не старался. И вот тогда, именно для них был создан курс программирования, где на старте учимся делать сайты - базовый html и css, где практически нет ни какой логики. Ребёнок делает сайт и у него получается. Более того они получают ощутимый результат н каждом занятии. Когда первые два языка поняты полностью, переходим к Java Script, попутно добавляя нотки C++. Так как дети уже щупали код до этого, их мозг понемногу перестраивается на логику компьютера, и тут плюсы или скрипты даются гораздо проще.

4 года назад. 3Д моделирование под 3Д принтер. Ребята 5 класс.4 года назад. 3Д моделирование под 3Д принтер. Ребята 5 класс.

Далее я задумался, как можно привлечь девочек в технический центр? На робототехнику и программирование ходили в основном мальчики. Их было больше 95%. Но ведь девочек как минимум половина. То есть половина рынка лежит рядом и стандартным путём выйти на него не получится. Для девочек я запустил курс по графическому дизайну. На старте изучаем Фотошоп. Привязываем его к практике - работе в типографии или рекламном агентстве. Они учатся делать визитки, календари, блокноты. Разрабатывают дизайн в Фотошопе, после чего печатаем, ламинируем, сажаем на пружину на брошюраторе. Всё, что изготовили, забираем себе. Некоторым девочкам хватило квалификации, чтобы полностью задизайнить и изготовить школьный дневник.

Так в чём же здесь магия? Она начинает работать тогда, когда у вас есть база робототехников в 50 человек, и вы им говорите, что запускаете программирование отдельным курсом, куда каждый может прийти на первое пробное занятие. Из 50 человек пришло 25. Из 25, пришедших на первое пробное занятие, 18 осталось ходить на постоянной основе, не бросая при этом робототехники. Получается, что без дополнительных вложений в рекламу, к вам уже ходит не 50 человек, а 68. То же самое произошло и с дизайном. Первоначально я задумывал данный курс для девочек, но мальчикам там оказалось не менее интересно. За несколько недель я увеличил клиентскую базу на 50%, фактически не увеличивая её. Половина детей стала посещать 2 и более курсов. Рекордом был мальчик Женя, который ходил параллельно на робототехнику, программирование, авиамоделирование, репетиторство по физике и математике. Он посещал у меня параллельно 5 курсов. И ему это безумно нравилось.

Строим город из структора и освещаем его от подстанции - батареек. 4 класс.Строим город из структора и освещаем его от подстанции - батареек. 4 класс.

Но магия здесь не только в том, что можно расширить базу клиентов из текущей базы. Раньше, когда я звонил клиенту по заявке, предлагал ему робототехнику, рассказывал о всех плюсах, что получит ребёнок, если слышишь ответ "нет, не интересно", то говоришь - "ну ок". Теперь же, я могу предложить ему ещё и программирование, или дизайн, или может быть ЧПУ станок? А авиамоделирование нравится? А хотите в бесплатном пробном формате попробовать всё сразу, а потом уже решим? Большинство из новых ребят, таким образом, сходу начинает посещать несколько курсов одновременно. А это увеличение среднего чека фактически в два раза. Вот здесь и находится магия. Все остаются в плюсе - дети изучают материал более комплексно, а так как они посещают несколько курсов, на стыке этих знаний рождаются самые крутые проекты и решения. Хотите метеостанцию с веб интерфейсом в реальном времени? Пожалуйста. А хотите сеть метеостанций, которые каждый ребёнок устанавливает у себя дома? Пожалуйста. А может быть вам интересна деревянная картина с подсветкой? Нет проблем.

Дети довольны, родители так же рады, что их ребёнок нашел увлечение, и бежит на очередное занятие с удовольствием, а не из под пинка. Вы получаете геометрический рост клиентской базы, не прикладывая дополнительных усилий в маркетинге. Все остаются довольны.

Комплексный детский технический центр запустить сходу достаточно трудно, но это и не требуется. Стоит начинать сразу с робототехники и программирования на две возрастные категории - малыши (5-7 лет) и старшие ребята (8+ лет) Тогда вы получите не 2, а 4 курса сразу. Кстати, у малышей статистика еще интереснее. В прошлых статьях я рассказывал про формат робототехники для малышей. Так вот малышей на робототехнику ходило 20 человек, когда я запустил программирование, привязав сюжетные линии, сделав рабочие тетради, наподобие тех, что дети использовали на робототехнике, из 20 детей, 18 пошло ещё и на программирование. Здорово, правда?

Подведём итоги:

Школа робототехники сама по себе - не плохой вариант. Но детский технический центр с множеством курсов здесь безоговорочно выигрывает. Это как раз тот случай, когда 1+1=11.

Подробнее..

Моделирование дома в SketchUp и перенос его в Unity 3D

24.01.2021 00:17:21 | Автор: admin

Учебные материалы для школы программирования. Часть7

Spoiler

На прошлом уроке мы затронули тему самостоятельного создания объектов для игр. В т.ч. была упомянута программа SketchUp, которую мы часто использовали, для создания простых строений.

Сегодня, мы создадим здание и перенесем его в Unity. Хочу обратить ваше внимание на то, что для импорта готового здания, необходимо, чтобы SketchUp стоял на том же ПК. Без программы Unity не сможет импортировать модель.

Порядок выполнения

Откроем SketchUp и выберем шаблон Simple Template - Meters.

Выберем инструмент фигуры и нарисуем на земле квадрат по форме дома.

Теперь, выдавим его с помощью инструмента выдавить/вдавить (push/pull).

Сделаем стены. Для этого используем инструмент Сдвиг (Offset).

Повторим операцию ещё раз.

Образовалась довольно узкая рамка, которую можно использовать для создания стен. На этом этапе стоит добавить все запланированные перегородки.

Лишние линии убираются инструментом Ластик (Erase).

Выдвигаем стены.

Прорежем двери и окна. Для начала по периметру дома создадим направляющую линию. Последней линией контур не замыкаем, иначе образуется новая плоскость.

Нарисуем на стене квадрат и выделим его.

Нажимая Ctrl+C и Ctrl+V, копируем его по стене, привязывая к линии.

После копирования окон лишнии линии стираем.

С помощью инструмента Вдавить/выдавить вдавливаем окно до состояния "На грани" (On Face).

Теперь, инструмент запомнил глубину и можно вырезать окна двойным кликом.

Вырежем дверь похожим образом.

Используем инструмент "Ведёрко" (Paint Bucket) для наложения текстур. Выберем подходящую текстуру и зальём пол с фундаментом.

Аналогично поступим со стенами.

Чтобы наложить текстуру на замкнутый контур, нажмём Shift, чтобы наложить на все плоскости, имеющие такую же текстуру Ctrl.

Текстура на стену легла не идеально. Перейдём в свиток Текстура-Позиция, и перетягивая красный ползунок мы изменим позицию текстуры, а зелёным её размер.

Сейчас текстура этой стены отличается от остальных стен. Используем клик левой кнопки мыши по этой стене с зажатым Alt на инструменте "Ведёрко", чтобы запомнить настройки текстуры на этой стене.

И красим инструментом "Ведёрко" остальные стены.

Перейдем к созданию крыши. Для этого нужно заблокировать данный участок от редактирования, чтобы ничего не испортить. Выделим дом и вызовем свиток меню "Сгруппировать".

На одном из торцов дома создадим плоскость для крыши.

Попрошу заметить, что мы вышли из группы кликом по пустому месту на экране. Если плоскость маленькая, её можно увеличить инструментом "Растянуть" (Scale).

Рисуем на плоскости очертания крыши. Лишние линии можно стереть.

Инструметом Выдавить/вдавить придаём объем.

Используем "Сдвиг" на крыше, чтобы добавить объёма.

И вдавим плоскость немного внутрь.

Окрасим всё подходящими текстурами и удалим человека. Домик готов для импорта в Unity!

В настройках импорта в Unity надо выставить галочку Generate Colliders, а во вкладке Material Use External Materials.

При этом, импортируются все материалы и создадутся папки.

Теперь, у вас есть своя собственная модель дома, для использования в играх!

Подробнее..

Домино на Unity

05.01.2021 18:18:32 | Автор: admin

Учебные материалы для школы программирования. Часть 2

Unity 3D - современный инструмент разработки компьютерных игр и приложений, разобраться с которым под силу не только взрослому, но и школьнику. Гипотезу о том, что профессиональные инструменты могут быть доступны для широкого круга пользователей, независимо от возраста и предшествующего опыта, удалось доказать мне на примере собственного образовательного проекта для школьников.

Сегодня, я продолжаю делиться с вами материалами, чтобы проделанная нашей командой работа, принесла максимум пользы учителям, руководителям детских и юношеских кружков технического / цифрового творчества, увлеченным родителям и конечно же ребятам всех возрастов, которые мечтают стать разработчиками компьютерных игр!

Spoiler

Хочется напомнить, что занятия разрабатывались для детей 10-16 лет, поэтому многие этапы упрощены.

Первое занятие вы можете найти по ссылке http://personeltest.ru/aways/habr.com/ru/post/535916/

Делитесь инструкциями к занятиям с друзьями и коллегами, чтобы о возможности преподавать Unity, узнали как можно больше людей!

Домино

Цель данного занятия - научиться создавать и редактировать игровые объекты, компоненты и материалы. Итак, начнем!

Импортируем приложенный ассет. Скачать его можно по ссылке

Создаём новую сцену. На сцене создаём плоскость с помощью quad или plane, выставляем размер 200х200.

Создаём новый куб и придаём ему форму домино. На этом этапе нужно показать несколько способов, как это можно сделать инструментами или ручным вводом.

Spoiler

Unity - отлично интегрируется с уроками по математике и физике. Смело вплетайте сложные или "скучные" темы по этим предметам в ваше занятие по Unity. Такой прием поможет не только преподнести тему интересно, но и ответит на частый вопрос "а зачем мне это учить, если в жизни не пригодится?" - пригодится, отвечаем мы, и рассказываем на проекте Домино, например, о понятии линейного размера.


Далее, на наше домино надо закинуть Rigidbody, чтобы домино могли падать.

Для большего удобства был создан скрипт Reset, который по нажатию на пробел выставляет объекты в свои изначальные положения и сбрасывает им скорость. Листинг (для ознакомления преподавателя):

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Reset : MonoBehaviour {  Rigidbody rig;  Vector3 startPos;  Quaternion startRot;    // Use this for initialization  void Start() {    rig = GetComponent<Rigidbody>();    startPos = transform.position;    startRot = transform.rotation;  }    // Update is called once per frame  void  Update() {    if(Input.GetKeyDown(KeyCode.Space)) {      if(rig) {        transform.position = startPos;        transform.rotation = startRot;        rig.velocity = Vector3.zero;        rig.angularVelocity = Vector3.zero;      }     }  }}

На его примере можно показать, для чего нужны скрипты.
Делаем небольшой трамплин и шарик, который будет толкать домино. На сферу незабываем добавить Rigidbody.

Этот этап урока отлично подойдет, чтобы рассказать о глобальной и локальной системе координат, о центре объекта и его позиции (center / pivot).

Несмотря на малый, с первого взгляда, объём занятия, у ребят уходит 1,5-2 часа. Время затрачивается не только на выставление домино в желаемой последовательности (рекомендуем каждому воплотить свою задумку по "узору" расположения костей), но и на разбор важных, для дальнейшей работы, тем: система координат, точки отсчёта, понимание углов Эйлера (pitch, yaw, roll), и масштабирования объектов.

Если занятие пройдёт быстрее, чем ожидалось, добавьте скрипт GameLogic, создав препятствие для шарика. Закиньте скрипт на пустой или статичный объект (пол или трамплин).

Этот скрипт по нажатию на пробел выставляет шарик в изначальное положение и включает-выключает объект-препятствие.

В конце занятия у ребят получается простой игровой проект. Не взирая на слабую визуальную составляющую (но вы можете в своем уроке уделить внимание текстурам), падающие костяшки вызывают бурю положительных эмоций!

Подробнее..

Flappy Bird на Unity 3D

10.01.2021 16:05:45 | Автор: admin

Учебные материалы для школы программирования. Часть 3

Spoiler

Часть 1 вы можете найти здесь

Часть 2 вы можете найти здесь

Разрабатывая концепцию школы программирования, нам хотелось стать не только интересными для детей, но и понятными для родителей. Ведь решение о покупке курса принимается совместно. На старте проекта и тестировании бизнес модели, был сделан упор на родителя, казалось, что самое важное, удовлетворить запрос платящей целевой аудитории. Поэтому, первые открытые уроки и мастер классы были максимально интегрированы со школьной программой.

Для этого мы разбили группы по возрастам, посмотрели, какие учебники по геометрии, алгебре и физике выбирают близлежащие школы, определили перечень пересекающихся тем, выбрали те темы, которые наиболее наглядно можно раскрыть с помощью Unity, и приготовились к взрывному успеху! Но не тут-то было.

Для родителей, наша концепция показалась очень привлекательной, ведь каждый ломает голову над тем, как заинтересовать ребенка школьными предметами и повлиять на успеваемость. Но мы не учли, что любая польза меркнет, если отрок вышел с занятия без искрящихся глаз и улыбки до ушей. Все говорили, что идея классная, что такой курс стал бы отличным решением их проблем, но школьника занятие не зацепило, сложно, идти не хочет.

Следующим этапом, мы решили поговорить со второй половиной нашей целевой аудитории - детьми. Оказалось, ребята осознают, что надо научиться полезному, они "гуглят" курсы, смотрят кто чему учит. Но определяющим фактором для них выступает атмосфера занятия. Им важно, чувствовать себя в окружении единомышленников, совершать маленькие победы на каждом уроке, ощущать свободу и дружественность обстановки, и конечно же, здорово проводить время.

Решением стало снизить количество рассматриваемых тем из школьной программы, и добавить в проекты элемент узнаваемости, соревновательности и веселья! Так появилось занятие по сборке аналога игры Flappy Bird.

Цель занятия: научиться работать с 2д-физикой и Canvas при использовании последнего на разных разрешениях целевой платформы.

Рассматриваем с учащимися темы:

- включение AudioSource посредством Event-системы UI;
- детектирование тапа по экрану посредством Event-системы UI - Спрайты;
- система анимаций в разрезе 2D-игр;
- коллайдеры в 2D и их редактирование;
- сборка проекта под Android.

Поехали!

Создаём новый 2д-проект и импортируем приложенный ассет.
Проект практически готов, тем не менее, в нём отсутствует несколько ключевых элементов.
- отсутствуют движущиеся трубы;
- отсутствует прыжок по тапу по экрану;
- проект не настроен под компиляцию на Android.

Для начала научимся пользоваться спрайтами. В ресурсах игры лежит файл sprites.png, который импортирован как спрайт с пометкой Multiple, это позволяет посредством кнопки SpriteEditor разрезать его на несколько одиночных спрайтов.

На sprites.png также находится неразмеченная область, в которой лежит небольшой квадрат, светло-голубого цвета. Добавим его в новый спрайт. Спрайт закидываем прямо в окно инспектора, если он отображается некорректно, выставляем ему нужный для корректного отображения слой. Далее этот квадрат можно использовать для помощи игроку или, наоборот, ловушек.

Стоит рассказать ребятам об особенностях работы коллайдеров, накладываемых на спрайт. Например, на птице установлен Polygon Collider 2D, позволяющий точно подобрать форму коллайдера под спрайт без необходимости делать его выпуклым для симуляции физики, как в 3D.

Анимация спрайтов.

Следующим шагом будет создание движущихся труб. Трубы устроены следующим образом: пара труб с установленным между ними триггером со скриптом, убивающим игрока, расположены в одном объекте. Передвигать нужно именно этот объект. Записываем на него анимацию, выходим из режима записи и проверяем.

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

Для компиляции под Android важно не забыть про удобное управление. Для мобильных игр, в большинстве своём, оно должно осуществляться одним пальцем. Делается это довольно просто (решение не является оптимальным, но оно самое простое).

В Canvas создаём панель и делаем её абсолютно прозрачной.

Все элементы управления закидываем внутрь этой панели. Это обязательно. Если этого не сделать, панель и кнопки могут некорректно отвечать на нажатия.
На панель необходимо закинуть компонент EventTrigger, и создать новое поле OnPointerEnter. В это поле закидываем птицу и выбираем внутри метод Jump.

После этого птица корректно начнет реагировать на нажатия по экрану.

Компиляция проекта под андроид.
Зайдём в File->Preferences->External Tools. Внизу страницы находятся три поля - SDK, JDK и NDK. Рядом кнопки Browse и Download. Первая - для выставления нужной папки, в которую установлены sdk, jdk, ndk, вторая - перекидывает на страницу загрузки того или иного инструмента.

Сперва необходимо установить Android studio и необходимые пакеты инструментов и SDK. На момент написания этих строк, устанавливалось API уровня 16 и 25. Также для компиляции необходим JDK.
NDK для данного проекта устанавливать нет необходимости.

Далее необходимо зайти в File-> Build Settings , выбрать платформу Android и нажать Switch Platform.

Затем переходим в Edit -> Project Settings -> Player

В свитке Resolution and presentation выбираем расположение Landscape left, это заставляет экран всегда быть в одном положении и не поворачиваться, если включён автоповорот.

В свитке other settings необходимо выставить имя приложения в том же формате, что и стандартное. Тем не менее, изменить это поле обязательно, в противном случае компиляция не пройдёт успешно. Также необходимо выбрать минимальные и целевое API.

По желанию можно выставить иконку и компилировать. На выходе мы получим APK файл игры.
Если подключить телефон на андроиде в режиме отладки и нажать Build and Run, то игра автоматически установится на телефон и запустится.

Хочется напомнить, что представленные методические рекомендации к занятиям по Unity, разрабатывались для преподавателей информатики и программистов, работающих с ребятами.

Подробнее..

Деревья (плагин SpeedTree) на Unity 3D

24.01.2021 00:17:21 | Автор: admin

Учебные материалы для школы программирования. Часть6

Spoiler

Предыдущие уроки можно найти здесь:

  1. Spaceship

  2. Домино

  3. Flappy Bird

  4. Гравитационная комната

  5. Платформер

В Unity, в asset store, можно найти множество готовых объектов для будущей игры, но иногда, хочется сделать что-то своими руками. Для зданий, и других простых архитектурных объектов, мы часто использовали SketchUp, для "живых" анимированных объектов - Blender. На этом уроке, мы сами "вырастим" дерево в Unity!

Небольшое отступление для тех, кто следит за публикациями, но не решается попробовать включить в свои уроки новые инструменты. Попробуйте сделать первый шаг с 3D. Программ по 3D моделированию очень много, среди них есть настолько простые, что методом "тыка" можно освоить их за пару вечеров. Посмотрите обязательно:

  • Tinkercad - составление фигур из геометрических форм;

  • SketchUp - для более детально проработанных архитектурных объектов;

  • ZBrush - можно создавать сложные, крутые модели, а можно ограничиться "лепкой" колобка, что тоже очень занятно!

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

Порядок выполнения

Создадим новыи проект, в нем создадим терреин.

Добавим на него объект 3D Object Tree

Добавим дереву ветки, создав блок веток. Увеличим их количество примерно до 20 (интересующие параметры выделены синим). В каждом блоке изменяем параметр Frequency (цветом на скриншоте не выделен).

Изменим их расположение, поменяв кривые распределения, длины, и поменяем ползунок стремления ветвеи к свету.

Далее, добавим к этим ветвям еще несколько веток.

Не забудем про листву.

Следующий шаг - выставление материалов.

Для деревьев важно выставлять материалы с помощью шеидера Nature. Импортируем стандартныи ассет Environment, он содержит готовые материалы. Материалы коры нужно назначить всем веткам. Если материал не подходит, Unity предложит использовать корректныи материал.

Жмем Apply и "переконвертирования" материала. Будьте осторожны, Unity часто вылетает на этом этапе.

Итак, дерево готово! Его можно разместить на терреине благодаря Mass Place Trees.

При должном усердии, можно получить вот такой лес:

Подробнее..

Эффект дождя. Частицы в Unity 3D

31.01.2021 22:19:51 | Автор: admin

Учебные материалы для школы программирования. Часть9

Spoiler

Продолжаем совершенствовать проект, в котором уже есть сделанные нами деревья, дом и освещение. Сегодня мы добавим эффект дождя. Этот большой блок уроков - единственный в программе. Мы стараемся избегать сложносоставных проектов. Для многих, это покажется странным, ведь по-настоящему стоящую игру, с графикой, интересными персонажами, уровнями и механиками можно сделать именно разбив на множество задач, которые в процессе обучения будут решаться. В итоге - большой, качественный игровой проект, который не стыдно показать.

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

Когда делаешь курсы для детей - в первую очередь, идешь от эмоционального опыта, учитываешь психо-физиологические особенности юного возраста, потребность в постоянном переключении и т.д.

Взрослый человек придет на курс, чтобы решить стоящую перед ним задачу (трудоустройство, карьерный рост, развитие хобби). Ребенку всегда важно чувствовать себя комфортно, среда и занятия должны стать для него мотивирующим фактором, ведь сила воли у многих еще не очень развита, и ходить на занятия потому что надо - "ну такое".

Перейдем от слов к делу.

Порядок выполнения

На занятии рассмотрим несколько принципов работы с системой частиц, и создадим эффект дождя.

В проект импортируем приложенный ассет. Ассет содержит текстуры, звук и стандартный контроллер игрока.
Создадим простую карту, поставим игрока, и внутри него на высоте около 30 метров создадим три системы частиц.

Назовём их Rain, Dust и Storm.

Начнём с самого дождя. Приведём настройки к указанным параметрам, уменьшим время жизни, изменим цвет, размер и иерархию.

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

Также, стоит поставить галочку ColorOverLifetime и выставить ему такое значение, чтобы дождь плавно исчезал и появлялся.

Создадим и настроим материал в соответствии со скриншотом.

Теперь, настроим рендер. Первое, что нужно сделать это закинуть материал и выставить ему режим отрисовки, как Stratched Billboard с растяжкой по длине 2. Обязательно нужно поменять MaxParticleSize, иначе частицы не будут апскейлиться и будет эффект, как будто они нас облетают.

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

На этот раз, настроек чуть меньше.

Дальнейшие настройки мало чем отличаются от дождя, более того, цвет по времени применён тот же самый .

Самое интересное начинается в материале. Он отличается от остальных, т. к. будет анимирован.

Теперь, про саму анимацию. Покадровая анимация, в нашем случае, представлена одним материалом с наложенным на него текстурным атласом, в котором находятся все кадры анимации. Такой способ является стандартным во многих игровых движках и потому, такие текстуры можно легко найти в свободном доступе. Главное выставить правильное количество тайлов в листе.

Перейдем к грозовым облакам.

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

Первое, что сделаем, это закинем эммитеры тумана и дождя в эммитер облаков. Для корректной работы выставим режим изменения размера на иерархический, в данном занятии нам это не понадобится, но в случае изменения размеров данная галочка должна быть установлена.
Заметьте, что мы используем Bursts для создания двойных облаков.

Также, нельзя обойти стороной и Color Over Lifetime. Он придаст нашим облакам эффект грозовых.

Далее, всё по стандарту создаём материал и настраиваем. Использована стандартная текстура дыма из Unity, она отлично пойдёт в качестве облаков.

Рисуем методом Horizontal Billboard, данный тип не поворачивает спрайт на игрока.
На сцену добавляем звук ливня. Звук довольно сильно добавляет эффект, подчёркивая систему частиц.

Дождь готов!

Подробнее..

Жидкий персонаж на Unity 3D

04.02.2021 18:19:53 | Автор: admin

Учебные материалы для школы программирования. Часть11

Spoiler

На сегодняшнем занятии мы познакомимся с физикой на джоинтах движка BOX 2D, на примере создания персонажа, похожего на главного героя Gish или Slime Laboratory.

Порядок выполнения

Создадим новый 2д проект и импортируем в него приложенный ассет. Ассет содержит все необходимые ресурсы, включая спрайты для уровня, скрипты и меш для персонажа.

Для начала, создадим новую сцену и поместим в неё 10 сфер с радиусом 0.5, таким образом, чтобы получилась "ромашка":

Установим на каждую сферу Rigidbody2D массой 0.5 и CircleCollider2D. Центральная сфера имеет массу 0.05 и drag = 1 и не имеет коллайдера.

Добавим между соседними сферами по одному SpringJoint2D. Обратите внимание на параметр Frequency - это частота опроса пружины, чем частота выше, тем пружина будет сильнее возвращаться на своё место. Damping - демпфирование пружины (предотвращение колебаний, смягчающий эффект).

Таким образом, мы не даём нашей заготовке разлетаться на куски или, наоборот, излишне сжиматься. Тем не менее, форму она держать не будет.

Для придания формы используем среднюю точку. От каждой, из 9-и окружающих её сфер, создадим ещё по одному джоинту.

Данная конструкция позволяет нам держать форму, при этом, она может сработать некорректно, если при сильном ударе центр вылетит за пределы круга. Более того, данная модель не учитывает поверхностное натяжение между удалёнными точками. Для этого, создадим систему из джоинтов по такому принципу:

Итоговая система джоинтов должна выглядеть примерно так:

Камеру повесим на центральный объект и протестируем, как себя ведёт наша физическая модель. Изменяя её параметры, можно добиться разной вязкости и плотности.

Теперь придадим "лизуну" очертания. Для этого в ассет приложена 3д-модель со скелетом, каждая из 9-и костей которого управляет по одному вертексу по периметру.
Для неё написан скрипт Goo, который управляет привязкой и отвечает за перемещение нашего главного героя.

Закинем модель на сцену и назначим ей скрипт. Конфигурируем его таким образом. На сцене создадим уровень из спрайтов и назначим ему коллайдеры.

Разберём немного сам скрипт:

using System.Collections;using System.Collections.Generic;using UnityEngine; public class Goo: MonoBehaviour {    public ConstantForce2D ForceObject; // центральная точка как объект приложения силы    public float maxForce = 4f; // сила передвижения publicTransform[] bones; // массив костей    public Transform[] go; // массив сфер    public float sphereRadius; // радиус сферы, можно брать автоматически, но в данном случае выставляем вручную    public Transform center; // центральная точка как трансформ    ConstantForce2D[] frc; // все объекты приложения силы      // Use this for initialization    void Start() {        frc = newConstantForce2D[9]; // инициализируем        // находим все объекты приложения силы        for (int i = 0; i < 9; i++) {             frc[i] =go[i].GetComponent<ConstantForce2D>();        }    }    // Update is called once per frame     void Update() {        for (int i = 0; i < 9; i++) {             // выставляем кости по точкам с небольшим смещение            bones[i].position = go[i].position + (go[i].position - center.position).normalized * sphereRadius / 2f;            // добавляем всем точкам силу по горизонтали            frc[i].force = newVector2(Input.GetAxis("Horizontal") * maxForce, 0f);         }        // и центральной точке тоже        ForceObject.force = newVector2(Input.GetAxis("Horizontal") * maxForce, 0f);        // нажали пробел        if (Input.GetKeyDown(KeyCode.Space)) {            foreach(Transformrig ingo) {                rig.GetComponent<Rigidbody2D>().velocity += new Vector2(0, 6f); // прыжок            }        }    }}

После отключения MeshRenderer у сфер, можно увидеть, что всё адекватно работает. Для полноты картины, фон и камеру прикрепляем к центральному объекту. У риджитбади центрального объекта нужно запретить вращение по Z. Можно добавить, на свое усмотрение, пару глаз.

На серые объекты вешаем скрипт RandomColor и выставим ему палитру.

using System.Collections;using System.Collections.Generic;using UnityEngine; public class RandomColor: MonoBehaviour {    SpriteRenderer rndr;     public Color32[] colors;        // Use this for initialization    void Start() {        rndr = GetComponent<SpriteRenderer>();         rndr.color = colors[Random.Range(0, colors.Length)];    }}

Теперь при старте уровень приобретёт цвет.

На этом, сборка нашего проекта завершена!

Подробнее..

Стики и работа с Event System в Unity 3D

10.02.2021 22:13:33 | Автор: admin

Учебные материалы для школы программирования. Часть12

Предыдущие уроки можно найти здесь:

Этот материал состоит из двух частей:

В первой, рассмотрим создание удобных стиков, подходящих под любые разрешения экранов и любую диагональ.

Познакомимся с использованием Event System в разрезе работы с UI и реализации пользовательской обработки реакции на указатель мыши/тачпада.

Далее, перейдем ко второй, где создадим скрипт, реализующий доступ к другим объектам посредством Event System.

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

Обе части занятия являют собой продолжение работы над проектом "Жидкий персонаж".

Все материалы вы традиционно можете скачать тут. В папку залиты файлы для обеих частей.

Порядок выполнения

Создадим новую панель со следующими параметрами:

Панель отвечает за активную зону для нажатий. От её размеров зависит площадь, на которой будет работать стик.

Внутри панели создадим 2 Image согласно иерархии на скриншотах - Joy и Mushroom Joy тело нашего стика, Mushroom его грибок.

Их параметры:

Эти элементы являются вспомогательными для скрипта и потому, тип их привязки очень важен.

Создадим скрипт. Скрипт необходимо закинуть на панель. Его полный листинг выглядит так (если в таком формате совсем неудобно, пишите в комментах - перенаберу исходный код):

Разберём его подробнее
Для начала подключим пространство имён для обработки событий:

using UnityEngine.EventSystems;

За обработку нажатий отвечают методы OnPointerDown и OnPointerUp. Для их работы необходимы следующие интерфейсы: IpointerDownHandler и IpointerUpHandler.

Чтобы работать с информацией о конкретном нажатии (а в случае мультитача данных нажатий может быть несколько) объявляем поле private PointerEventData eventData;

При нажатии на экран вызывается OnPointerDown и складывает информацию о нажатии в eventData.

В дальнейшем это позволяет нам работать с eventData из метода Update().

Для того, чтобы понимать, актульна ли информация о нажатии, введена булева переменная OnScreen. Если мы нажали на экран, то переменная принимает значение true, объект Joy становится в точку нажатия и объекты Joy и Mushroom становятся видимыми.

Метод OnPointerUp отключает видимость Joy и Mushroom и переводит переменную OnScreenв false.

Остальная обработка возникает в Update().
Там мы выставляем Mushroom по глобальной точке нажатия и меряем её локальные координаты.

Принцип такой: нажали, грибок и джой выставились в току нажатия.
Передвинули палец/указатель и грибок сместился относительно джоя. Это смещение мы и берём из локальных координат. Его и используем как результат.

Теперь, в любом скрипте, который используем методы типа GetAxis строку типа Input.GetAxis("Horizontal")меняем наCustomStick.horizontal

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

Приложенный ассет имеет полностью готовый и настроенный стик в виде префаба и сцены. Помните, что система эвентов не будет работать без данного объекта, который создаётся автоматически при создании Canvas через меню.

Хочется напомнить, все материалы рассчитаны на использование в составе проекта с главным героем - желе.

Перейдем ко второй части.

Использование своих типов эвентов через код

Откроем проект Goo (жидкий желеобразный персонаж), созданный ранее. Проект используется как пример, можно использовать любой другой.

Создадим новый скрипт. Его листинг:

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

Если мы выложим его на пустой объект на сцене, мы можем увидеть привычное окно системы эвентов.

Рассмотрим пару вариантов использования этого скрипта. Вариант первый создание потайной двери-стены, открывающийся ключом. Для этого нам понадобится спрайт стены с обычным коллайдером и спрайт или модель ключа с коллайдером в режиме триггера.
Также можно добавить ещё один пустой объект и закинуть на него звук, создав тем самым AudioSource. Уберём у AudioSource галочку вопроизведения при старте и закинем в него ключ и стены.

Далее настроим сам ключ. В данной конфигурации ключ выключает стену, включает звук и выключает себя.

Это самый простой пример логики. Рассмотрим посложнее.

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

Создать её будет сложнее. Кратко, логику можно описать так: у нас есть стенка, которая включается, чтобы не дать игроку выйти. (изначально она выключена, чтобы игрок вошёл).

Стенку включает триггер, находящийся прямо возле неё. (Тоже изначально выключен)

По центру есть ещё один триггер, выключающий стенку и включающий триггер, включающий стенку.
Работает это так игрок проходит сквозь выключенную стенку и сквозь выключенный триггер стенки, ничего не происходит. Заходит в триггер по центру и ловушка срабатывает. Теперь выйти нет никакой возможности.

Создадим кнопку. Для этого импортируем приложенное извображение и разрежем на 2 спрайта.

Расположим их в мире в одной точке, зелёный выключим и назовём его "Вкл", Красный назовём "Выкл".

Создадим ещё один пустой объект, закинем на него коллайдер, выставим коллайдеру режим триггера и расположим на кнопке. Настроим следующим образом:

Этот триггер выключает два других триггера ловушки, выключая всю логику ловушки и оставляя стенку выключенной, выключает красный спрайт и включает зелёный.
Таким образом, кнопка нажимается и ловушка отключается.

Сюда же можно добавить звук нажатия кнопки, закинув его на пустой объект или на сам спрайт зелёной кнопки и оставив галочку Play On Awake.

На этом этапе занятие можно считать завершённым.

Пишите комменты, делитесь полезными ссылками, как можно улучшить проект!

Пожалуйста, поддержите инициативу - нажимайте нравится и поделиться!

Подробнее..

Синтезатор на Unity 3D

09.04.2021 12:18:12 | Автор: admin

Учебные материалы для школы программирования. Часть13

Предыдущие уроки можно найти здесь:

При тематическом планировании уроков, мы сталкиваемся с интересной задачкой: в нашей группе учатся и мальчишки и девчонки. У них разные вкусы, разные любимые герои, жанры. И если все занятия будут на тему гонок или Silent Hill - ряды девочек на ваших занятиях, - поредеют. Эту ситуацию мы решаем двумя способами:

  • спрашиваем мнение ребят и проводим голосование на уроке. Да-да, только дети смогут сделать вашу программу интересной, поэтому их мнение действительно значимо. Не для галочки. Опрос и обсуждение важно проводить регулярно, ибо все группы разные, темы меняются от возраста к возрасту, меняются в зависимости от того, во что сейчас играют и что смотрят в кино;

  • чередуем и комбинируем. Мы стараемся чередовать "спокойные" и "агрессивные" проекты. Например, в этом месяце мы делаем лабиринт ужасов, но после его защиты - приступаем к созданию острова с лесом и домиком. При комбинировании, мы предлагаем всем ребятам уделить внимание визуальной составляющей (раскрасить, добавить элементов, составить композицию и пр.), и девочки с большим энтузиазмом берутся за такую задачу.

Сегодня мы сделаем проект из категории: спокойный, для девчат. Мальчишкам тоже хорошо заходит - особенно момент, когда в конце урока получается звуковая какофония =)

Рассмотрим следующие темы:

  • выставление вращения объектов в локальной системе координат посредством конверсии из углов Эйлера в кватернионы;

  • события объектов OnMouseEnter и OnMouseExit;

  • метод POW класса Mathf - возведение в степень;

  • парсинг float из имени объекта через системный метод Parse ;

  • стек постэффектов от Unity Technologies;

  • функция движка RequireComponent.

Особое внимание обратим на:

  • изменение скорости воспроизведения и высоты звука через Pitch;

  • использование аудиомикшера и постэффектов на мастер-канале микшера, в частности, реверберации и эмуляции комнаты.

Порядок выполнения

Создаётся новый проект, импортируется приложенный ассет, открывается сцена piano (в проекте заранее заготовлена сцена, ключевыми объектами которой являются клавиши, расположенные на сцене в "Пианино/Клавиши").
Клавиши пронумерованы в соответствии с полутонами, начиная с ноты "до" и заканчивается нотой "фа" следующей октавы, т.е. "до", "до диез", "ре", "ре диез", "ми", "фа" и т.д.

Клавиши расположены с начала октавы в той же последовательности, что и на реальном пианино.

Весь проект умещается в один скрипт. Полный листинг содержит пояснения:

using System.Collections;using System.Collections.Generic;using UnityEngine;using System;[RequireComponent(typeof(AudioSource))] // необходимо для того, чтобы скрипт требовал установленный аудиосорсpublic class Piano : MonoBehaviour {public KeyCode Key; // энумератор для выбора клавиши клавиатуры, на которую реагирует скриптAudioSource src; // Аудиосорс, приват-переменная     void Start () {src = GetComponent<AudioSource>(); // получаем аудиосорс        src.pitch = Mathf.Pow(1.059462f, float.Parse(name) - 1f); // высота звука равна 1.059462f в степени (имя_клавиши - 1).}    void Update () { // Для уменьшения отклика стоит использовать FixedUpdateif (Input.GetKeyDown(Key)) { // если нажали клавишу.playNote(); // играем        }        if (Input.GetKeyUp(Key)) { // если отпустили клавишу.stopNote(); // не играем        }}    private void OnMouseEnter() { // если мышь над коллайдером клавиши        playNote(); // играем}    private void OnMouseExit() { // если мышь вышла из коллайдера клавиши         stopNote(); // не играем}    private void playNote() { // играемtransform.localRotation = Quaternion.Euler(-3, 0, 0); // ставим локальный угол поворота на -3 градуса по Хsrc.Play(); // Включаем звук с начала}    private void stopNote(){ // не играемtransform.localRotation = Quaternion.Euler(0, 0, 0); // ставим локальный угол поворота на 0 градусов по всем осям    src.Stop(); // Останавливаем звук    }}

Особое внимание стоит уделить строке:

src.pitch = Mathf.Pow(1.059462f, float.Parse(name) - 1f);//высота звука равна 1.059462f в степени (имя_клавиши - 1).

Число1.059462высчитано математически и является простой заменой логарифмической функции, делящей одну октаву на 12 полутонов. Таким образом, каждый последующий полутон в 1.059462 раза выше предыдущего по частоте, что при количестве 12 полутонов даёт умножение частоты на 2 с ошибкой в 0.00003 Гц на октаву. С учётом того, что динамический диапазон нашего пианино не превышает полторы октавы, звук практически не искажается.

Тем не менее, звуки пианино плохо ложатся в микс, при отпускании клавиши отсутствует затухание, потому было принято решение немного "размазать" всё реверберацией с небольшой задержкой и эмуляцией большой комнаты, которая добавит "хвостов" затухания резко прерывающимся звукам.

Создана новая группа аудиомикшера, на мастер-канал которой установлена реверберация со следующими параметрами.

А всем аудиосорсам в качестве output установлен мастер-канал аудиомикшера.

Каждой клавише пианино необходимо вручную выставить необходимую клавишу клавиатуры. Так как мы имеем дело с энумератором, необходимо выбрать из представленных вариантов. Клавиши установлены в следующем порядке:

Далее, немного оформляем сцену и добавляем следующие эффекты:

  • SSAO - подчеркнёт тени между клавишами, добавит глубины картинке.

  • Bloom - высветлит светлые участки ещё сильнее, сделает картинку более приятной на глаз, интенсивность нужно выбрать довольно низкую.

  • Антиалиасинг, чтобы убрать пикселизацию.

  • Винетка, чтобы затенить края, выделив основной объект.

    Можно добавить SSR, для легкого отражения на вертикальных плоскостях, что немного улучшит картинку.

Готово!

Подробнее..

Регдоллы на Unity 3D

16.04.2021 18:11:03 | Автор: admin

Учебные материалы для школы программирования. Часть15

Предыдущие уроки можно найти здесь:

Регдоллы - физика тряпичных кукол, основная задача которых - реалистичное падение тел со скелетом. Регдоллы применяются везде - от шутеров (падающие враги) до гонок. Допустим, в Goat Simulator регдоллы являются важнои частью геимплея.

Goat SimulatorGoat Simulator

В данном занятии рассмотрены следующие аспекты:

  • работа со стандартным генератором регдоллов;

  • понимание скелета гуманоидных моделеи;

  • исправление неверно выставленных коллаидеров на Rigidbidy посредством дополнительных объектов в иерархии.

Порядок выполнения

Создадим новыи проект и импортируем в него приложенныи ассет.
Ассет содержит стандартную юнити-модель робота Каила, модель лестницы и демо-сцену (но вы можете выбрать любую другую "человекоподобную" модель, и самостоятельно разработать дизайн окружения).

Создадим новую сцену, установим на нее плеин или квад в качестве пола. На пол поставим лестницу, на лестницу - модель робота Каила.

Самое время рассказать о скелете: во время занятия на доске был нарисован один из типов стандартного скелета, с небольшими пояснениями для регдолла - какая кость куда крепится и как используется (лайфхак для педагогов: интегрируйте это занятие в цикл уроков о человеке и его строении).

Перед созданием регдолл-системы необходимо выставить модель в Т-позу. Поворачиваем 2 этих объекта в локальнои системе координат до нужного угла.

должно быть так:

Далее, нажимаем в окне объектов Create->Ragdoll и конфигурируем его следующим образом:

Жмем Create и упираемся в одну проблему. Как можно заметить, модель имеет неверные коллаидеры.

Исправим их размер вручную, кроме того коллайдера, которыи находится на правои (от нас) руке. С ним поступим иначе. Это капсула на руке, и еи нельзя напрямую выставить угол наклона, но можно скопировать этот компонент на пустои объект, разместить его в пивоте руки и повернуть локально. Капсулу на самои руке удалим.

После всех этих манипуляции, модель должна падать корректно, а именно, мягко и естественно.

Готово!

Подробнее..

Судно на воздушной подушке на Unity 3D

16.04.2021 18:11:03 | Автор: admin

Учебные материалы для школы программирования. Часть14

Предыдущие уроки можно найти здесь:

Сегодня мы настроены на отдых и развлечения! Поэтому, этот урок будет простой и "короткий". Мы не будем работать с графикой (но вас никто не ограничивает в праве усовершенствовать проект), уделим внимание управлению и работе с физикои, на примере создания судна на воздушнои подушке.

Порядок выполнения

Создадим новыи проект, импортируем в него приложенныи ассет. В данном ассете содержится модели, звук и простая сцена.

Первое, что нам необходимо сделать - это установить на сцену модели карты и СВП, затем создать материал с нулевым трением и назначить его юбке СВП

На само судно устанавливаем Rigidbody со следующими параметрами:

Обратите внимание, что на коллаидерах установлена галочка Convex, а Rigidbody не имеет галочку использования гравитации. Вместо нее используется ConstantForce с довольно большим значением, направленная вниз.

Как видите, на скриншоте уже наложен скрипт. Но до того, как приступать к нему, необходимо установить рулевые лопатки.
Также, на модель в точках установки рулевых лопаток, установлены пустые геим-обджекты с названием Gizmo, в них и уложены сами лопатки.

Скрипт конфигурируется согласно позапрошлому скриншоту. Полныи листинг скрипта выглядит таким образом:

using UnityEngine;using System.Collections; public class Howercraft: MonoBehaviour {    public Rigidbody HowercraftRigidbody; // риджитбади     public Transform CenterOfMass; // центр масс    public float power = 25000; // мощность вперёд/назад    public float torque = 25000; // мощность влево/вправо    float finAngle; // угол отклонения лопаток     float pitch; // питч для звука    public Transform[] Fins; // массив с лопатками    public AudioSource mainEngine; // звук основного двигателя       public AudioSource pushEngine; // звук турбин     // Use this for initialization     void Start() {        HowercraftRigidbody.centerOfMass = CenterOfMass.position - HowercraftRigidbody.position; // устанавливаем центр масс    }     // Update is called once per frame    void Update() {                float inpFB = Input.GetAxis("Vertical"); // ввод вперёд/назад        float inpLR = Input.GetAxis("Horizontal"); // и влево/вправо              Vector3 vely = new Vector3(HowercraftRigidbody.transform.forward.x, 0, HowercraftRigidbody.transform.for ward.z); // находим вектор приложения силы          float gain = Mathf.Clamp01(HowercraftRigidbody.transform.up.y); // если перевёрнуты, силы будут равны нулю             HowercraftRigidbody.AddForce(vely * power * inpFB * gain, ForceMode.Force); // добавляем линейные силы              HowercraftRigidbody.AddRelativeTorque(0, torque * inpLR * inpFB * gain, 0, ForceMode.Force); // и поворот              finAngle = Mathf.Lerp(finAngle, -45 * inpLR, Time.deltaTime / 0.2f); // угол лопаток            foreach(Transform Fin in Fins) {            Fin.localEulerAngles = new Vector3(0, finAngle, 0); // выставляем угол         }        mainEngine.pitch = 0.9f + HowercraftRigidbody.velocity.magnitude / 60f; //высота звука основного двигателя               pitch = Mathf.Lerp(pitch, Mathf.Abs(inpFB) * 1.3f, Time.deltaTime / 0.5f); // высчитываем высоту звука турбины               pushEngine.pitch = 1f + 2f * pitch;        pushEngine.volume = 0.3f + pitch / 3f;    }}

При этом скрипт лучше давать последовательно, сначала физическии движок, потом звуковои.

Готово!

Подробнее..

Игровые механики на уроке геометрии или векторы на Unity 3D

20.04.2021 16:13:49 | Автор: admin

Учебные материалы для школы программирования. Часть16

Предыдущие уроки можно найти здесь:

В этой статье, мы обратим свой взор в прошлое, и вспомним, с чего начиналась детская школа программирования Step to Science. Первоначальная идея проекта состояла в том, чтобы быть не просто кружком технического творчества, а стать для детей ответом на вопрос, "зачем учиться в школе?"

К чему нам физика, алгебра и геометрия, если мы не планируем проектировать космические корабли, если для счета у нас есть калькулятор в телефоне, расплачиваемся мы чаще картой, так что даже сдачу в уме считать не надо.
Я тоже в детстве вела такие рассуждения, и у родителей не было иных способов донести до меня истину, кроме фразы "нет слова не хочу, есть слово надо" и ремня, который без лишней полемики мотивировал садиться за уроки.

С возрастом, перейдя на другую сторону баррикад, я поняла что хочу ребятам объяснить, показать, доказать, что учиться в школе действительно важно! И игровой проект, который мы разберем сегодня - один из цикла занятий по изучению школьных предметов через игры на Unity 3D.

Кроссплатформенный движок Unity дает огромные возможности учителю: через увлекательный процесс создания игр мы изучаем законы физики, геометрии, делаем расчеты, проектируем окружение, используем сторителлинг, сценарные механики. И конечно-же программируем. Вариантов интеграций Unity в другие образовательные и предметные области - бесчисленное множество!

Порядок выполнения

На примере создания 2D игры баскетбол, рассмотрим векторы (скорости, сил, локальнои и глобальнои систем координат). Разберем принципы представления систем координат и представления векторов. Также будет затронута работа с LineRenderer и многокамерность.

Поехали!

Создадим новыи проект и импортируем в него приложенныи ассет.
Ассет содержит в себе все ресурсы, необходимые для создания полноценного 2D приложения.

Для начала создадим небольшую сцену, в качестве фона выберем спраит спортзал и установим на него сетку. Обратите внимание, что необходимо выставить коллаидеры для щита и корзины.

Конечно, необходимо выставить правильныи Order in layer у спраитов. Добавим мяч, применим к нему Circle collider и Rigidbody.

Внутри мяча должен находиться пустои объект с Audio Source, настроенным на воспроизведение звука удара.

Чтобы воспроизводить этот звук, напишем простои скрипт, закинем его на мяч и сконфигурируем.

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Ball : MonoBehaviour {    public AudioSource hitSound;    public Rigidbody2D rig;    // Use this for initialization    void Start () {    }    // Update is called once per frame    void FixedUpdate() {    }    private void OnCollisionEnter2D(Collision2D other) {        if (other.relativeVelocity.magnitude > 1f) {            hitSound.Play();            hitSound.volume = Mathf.Clamp01(other.relativeVelocity.magnitude / 10);            rig.velocity *= 0.8f;        }    }}

В скрипте нет автопоиска Rigidbody, так что придется закинуть его руками. Если нажать на Play, наш мяч упадет, издавая звуки. Чтобы мяч отскакивал, создадим физическии материал и закинем его на коллаидер мяча.

Теперь подумаем о том, чтобы мяч показывал свое направление. Для этого создадим скрипт, которыи рисует стрелки: нам понадобятся два пустых объекта с LineRenderer, один в другом.

Создадим материал для стрелки:

И добавим скрипт, которыи будет выставлять вершины LineRenderer'ов, делая из них стрелки:

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Arrow : MonoBehaviour {   public Vector3 showVector;    public LineRenderer lrenderer1;    public LineRenderer lrenderer2;    Transform myTransform;    // Use this for initialization    void Start () {        //lrenderer1 = GetComponent<LineRenderer>();        myTransform = transform;    }   // Update is called once per frame    void Update () {        showVector = new Vector3(showVector.x, showVector.y, 0f);        lrenderer1.SetPosition(0, myTransform.position);        lrenderer1.SetPosition(1, myTransform.position + showVector);          if (showVector.magnitude >= 2f) { // длинная стрелка            lrenderer2.SetPosition(0, myTransform.position + showVector - showVector.normalized);        } else {            lrenderer2.SetPosition(0, myTransform.position + showVector * 0.5f);        }        lrenderer2.SetPosition(1, myTransform.position + showVector);        if (showVector.magnitude < 0.1f) {            lrenderer1.enabled = lrenderer2.enabled = false;        } else {            lrenderer1.enabled = lrenderer2.enabled = true;        }    }}

Закинем скрипт на объект-родитель стрелки и настроим его.

Теперь надо написать скрипт, которыи будет вектор скорости передавать в наш скрипт "показывания" стрелки. Он очень простои:

using System.Collections;using System.Collections.Generic;using UnityEngine;public class VectorVelocity : MonoBehaviour {    public Rigidbody2D rig;    public Arrow arrow;    // Use this for initialization    void Start () {     }    // Update is called once per frame    void Update () {        if (rig.bodyType == RigidbodyType2D.Dynamic) {            arrow.showVector =  rig.velocity / 5f;        }    }}

Закинем его на мяч, в скрипте укажем риджибади мяча и объект со скриптом стрелки.

Теперь вектор скорости показывается верно. Вектор скорости уменьшен в 15 раз, чтобы его было хорошо видно. А для того, чтобы было видно траекторию мяча - добавим ему Trail Renderer на любои привязанныи к мячу объект.

Теперь сделаем так, чтобы мяч можно было кидать. Для этого необходимо выставить ему тип Rigidbody как Kinematic и написать небольшои скрипт.

Листинг скрипта:

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.EventSystems;public class Spawner : MonoBehaviour {    public Rigidbody2D ball;    public TrailRenderer tr;    Quaternion oldRotation;    Vector3 oldPosition;    public bool readyToShoot = true;    // Use this for initialization    void Start () {        oldPosition = ball.transform.position;        oldRotation = ball.transform.rotation;    }    // Update is called once per frame    public void Respawn () {        ball.transform.position = oldPosition;        ball.transform.rotation = oldRotation;        ball.velocity = Vector3.zero;        ball.angularVelocity = 0;        ball.bodyType = RigidbodyType2D.Kinematic;        readyToShoot = true;        tr.Clear();    }    public void Shoot(Vector3 speed) {        if (!readyToShoot) {            return;        }        ball.bodyType = RigidbodyType2D.Dynamic;        ball.velocity = speed;        readyToShoot = false;    }}

Скрипт выкладываем на пустои объект в мире и устанавливаем ему наш мяч в качестве риджитбади и его треил.

Этот скрипт сам по себе ничего не делает. Чтобы он работал, необходимо организовать ввод. Создадим UI -> Panel на сцене, выставим панели нулевую альфу и установим на него скрипт TouchPanel.cs , приложенныи в проект.

Внутри панели должен лежать спраит со следующими параметрами (обратите внимание на привязку):

Для того, чтобы при компиляции не возникало ошибок из-за отсутствия класса спавнера, данныи скрипт приложен отдельным ассетом, и импортировать его можно только после создания спавнера.

Для того, чтобы сделать включение/выключение стрелок, используется скрипт Toggle, которыи реализован через эвент-систему юнити. Его необходимо закинуть на кнопку и сконфигурировать следующим образом.

Готово!

P.S. Делитесь ссылкой на статью с коллегами, друзьями и любопытными учениками. Будет здорово, если вы попробуете провести один из уроков в своей школе или в кружке детского технического творчества, и напишите пару слов обратной связи о том, как прошел урок по Unity 3D. Успехов!

Подробнее..

Тир. Стрельба рейкастами на Unity 3D

06.05.2021 18:22:32 | Автор: admin

Учебные материалы для школы программирования. Часть17

Предыдущие уроки можно найти здесь:

В этом проекте рассмотрим процесс работы:

- с рейкастами и векторами;
- с методами других пользовательских классов;
- с AudioSource и с Rigidbody через код;
- три основных составляющих выстрела, психологически действующих на игрока (звук, свет и свечение, анимация и след от выстрела);
- инстанцирование префабов.

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

Порядок выполнения

Создаём новый проект, импортируем приложенный ассет.
Помимо стандартных ресурсов пакет имеет сторонний плагин для рисовки декалей. Его работа в контексте данного урока не рассматривается.

Проект урока разбит на 2 части - тир и гранаты.

Тир

Тир - самый простой способ научить детей пользоваться рейкастами. Для упрощения, был заранее подготовлен ассет, содержащий все необходимые ресурсы, группе же перекидывается ассет, не содержащий скрипта мишени и её префаба.
Во время этой части урока необходимо объяснить, каким образом работает рейкаст и то, как можно взаимодействовать с другими скриптами из него.

Внутри проекта есть скрипт DecalShooter, который создаёт декали, и в котором расположен весь код стрельбы, включая рейкаст. В нём будет вводиться код взаимодействия с мишенью.
Для начала, необходимо подготовить саму мишень. Ею служит цилиндр, который необходимо уменьшить по Y до состоянии платины, удалить CapsuleCollider и поставить MeshCollider с галочкой Convex. Дополнительно, на цилиндр устанавливается текстура мишени, внутри цилиндра создаётся point light, подсвечивающий мишень, и объект с AudioSource для воспроизведения звука, а на сам цилиндр устанавливается Rigidbody с обработкой коллизий типа Continius Dynamic и галочкой isKinematik. У AudioSource не забудьте убрать галочку PlayOnAwake и закинуть звук попадания в мишень.

Следующим шагом становится создание скрипта Target, который сразу же накладываем на нашу мишень.

Мишень после этих действий необходимо добавить в новый префаб, чтобы при размножении мишени и внесении изменений не возникало необходимости править каждую. Теперь можно перейти к коду мишени.

using System.Collections;using System.Collections.Generic;using UnityEngine; public class Target : MonoBehaviour {    public GameObject light;    public Rigidbody rig;    public AudioSource src;     bool enabled = true;     // Use this for initialization     void Start() {        rig = GetComponent<Rigidbody>();        src = GetComponent<AudioSource>();     }     // Update is called once per frame     void Update() {     }     public void shoot() {        if (!enabled) {           return;        }         rig.isKinematic = false;         light.SetActive(false);         src.Play();         enabled = false;    } }

Код мишени содержит публичный методshoot, который необходим для того, чтобы другие скрипты могли обращаться к нашей мишени. Следующий шаг - проверка из файла DecalShooter попали ли мы в мишень и вызов методаshoot. В рейкаст необходимо включить следующий участок кода:

   if (Input.GetKeyDown(KeyCode.Mouse0)) {            time = 0.3f;             ShootSource.Play();             anim.Play("fire");             Muzzleflash.SetActive(true);            // Сама стрельба             RaycastHit hitInfo;            Vector3 fwd = transform.TransformDirection(Vector3.forward);                         if (Physics.Raycast(transform.position, fwd, out hitInfo, 100f)) {                GameObject go = Instantiate(                    DecalPrefab,                    hitInfo.point,                     Quaternion.LookRotation(                        Vector3.Slerp(-hitInfo.normal, fwd, normalization)                     )                ) as GameObject;                go.GetComponent<DecalUpdater>().UpdateDecalTo(                    hitInfo.collider.gameObject,                     true                );                Vector3 explosionPos = hitInfo.point;                Target trg = hitInfo.collider.GetComponent<Target>();                                if (trg) {                    trg.shoot();                }                                Rigidbody rb = hitInfo.collider.GetComponent<Rigidbody>();                                if (rb != null) {                    rb.AddForceAtPosition(fwd * power, hitInfo.point, ForceMode.Impulse);                    Debug.Log("rb!");                }             }            // Сама стрельба         }

Данный код пытается получить компонент из объекта hitInfo и, если это удаётся, вызывает методshoot. Мишень падает, свет от мишени выключается, звук попадания воспроизводится. Далее, желательно дать группе свободное задание по кастомизации своего проекта. Как альтернативу, можно предложить изменить код таким образом, чтобы мишень меняла цвет при попадании. Делается это заменой в Target строк:

light.SetActive(false);

на

light.GetComponent<Light>().color = Color.red;

Таким образом, свет меняется и не удаляется.

Гранаты

Эта часть урока должна ещё больше закрепить понимание векторов и работы рейкастов.

Для начала, создадим другой скрипт - дальномер.

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI; public class Lenght :  MonoBehaviour {    public Text Dalnost;    float rasstoyanie = 0; // переменная для расстояния до цели     // Use this for initialization     void Start() {     }     // Update is called once per frame     void Update() {        RaycastHit hitInfo;                if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hitInfo, 200)) {            rasstoyanie = hitInfo.distance;            Dalnost.text = rasstoyanie.ToString();        }    }}

Скрипт закинем в FPScontroller/FirstPersonCharacter. В Canvas создадим текст, закинем его в скрипт.
В этом скрипте реализован простейший рейкаст, и на его примере мы разбираем, как рейкаст передаёт информацию в структуру и как нам получать из структуры эту информацию.
При срабатывании рейкаста мы выводим дальность на экран.

Следующий шаг - бросок гранаты. Мы не используем никаких анимаций, мы создаём гранату на небольшом расстоянии от игрока и придаём ей скорость по направлению взгляда. Изменим скрипт, добавив в него поля для префаба гранаты и код броска.

using System.Collections;using System.Collections.Generic; using UnityEngine;using UnityEngine.UI; public class Length :  MonoBehaviour {    public Text Dalnost;    float rasstoyanie = 0; // переменная для расстояния до цели     public GameObject sharik;     // Use this for initialization    void Start() {     }     // Update is called once per frame     void Update() {        RaycastHit hitInfo;                 if(Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), outhitInfo, 200)) {            rasstoyanie = hitInfo.distance;             Dalnost.text = rasstoyanie.ToString ();            if(Input.GetKeyDown(KeyCode.Mouse1)) {                GameObject go = Instantiate(                    sharik,                     transform.position + Vector3.Normalize(hitInfo.point - transform.position),                     transform.rotation                );                Rigidbody rig = go.GetComponent<Rigidbody>();                rig.velocity = Vector3.Normalize(hitInfo.point - transform.position) * 10;            }         }    } }

Сразу же возникнет вопрос - зачем такое решение? К тому же, при направлении в небо бросок не произойдёт. Сделано всё это в учебных целях. Т.к. в рамках урока код пишется поэтапно, на данном участке объясняется, как найти вектор направления на объект по конечным и начальным координатам. Теперь дело за самой гранатой. Создадим скрипт Grenade.

using System.Collections;using System.Collections.Generic;using UnityEngine; public class Grenade :  MonoBehaviour {    public Transform explosionPrefab;     void OnCollisionEnter(Collision collision) {        ContactPoint contact = collision.contacts[0];                // Rotate the object so that the y-axis faces along the normal of the surface        Quaternion rot = Quaternion.FromToRotation(Vector3.up, contact.normal);        Vector3 pos = contact.point;         Instantiate(explosionPrefab, pos, rot);        Destroy(gameObject);    }}

Закидываем на сцену гранату, на меш Body ставим коллайдеру Convex, добавляем гранате RIgidbody и наш скрипт. Получившуюся гранату добавляем в префаб и удаляем со сцены.

Скрипт удаляет объект, на котором висит, но до этого инстантиирует объект, который мы выбираем в качестве эффекта взрыва.

Создадим эффект взрыва. В нём должен быть свет от взрыва, AudioSource с галочкой PlayOnAwake и звуком взрыва, Spital Blend на 90 процентов переведённый в 3д и увеличенный радиус распространения звука.
Для правильной отработки всех эффектов и разлёта Rigidbody нужно создать ещё один скрипт. Его мы назовём Explosion:

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Explosion :  MonoBehaviour {    public float radius = 5.0f;    public float power = 10.0f;    public GameObject svet;    void Start() {        Destroy(svet, 0.1f);        Vector3 explosionPos = transform.position;        Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);        foreach(Collider hit in colliders) {            Rigidbodyrb = hit.GetComponent<Rigidbody>();            if (rb != null) {                rb.AddExplosionForce(power, explosionPos, radius, 3.0f);            }        }    }}

Его нужно закинуть на эффект взрыва и создать префаб.
Данный префаб и используется в скрипте гранаты для создания взрыва.

Готово!

Подробнее..

Школы для разработчиков, корпоративные тренинги и онбординг-сервисы EdTech и TampD-стартапы, которые следует знать

31.01.2021 18:12:32 | Автор: admin

Мы запустили Актион Акселератор и ждем всех, кто делает MOOC-курсы, решения в духе Education 4.0, сервисы для обмена знаниями, онбординга и управления персоналом. Помогаем ресурсами и экспертизой независимым командам и тем, кто развивает что-то похожее in-house.

Участникам акселератора мы рекомендуем изучать сторонние EdTech и T&D-проекты смотреть, кто привлекает инвестиции и аудиторию. Сегодня делимся подборкой таких компаний.

Фотография: Max Duzij. Источник: Unsplash.comФотография: Max Duzij. Источник: Unsplash.com

Galvanize организует онлайн-курсы и очные тренинги для частных лиц и фирм, занимающихся разработкой программного обеспечения и data science. Управляет несколькими кампусами в США, где находится не только образовательная инфраструктура, но и коворкинги. Более восьми тысяч выпускников учебных программ Galvanize зарабатывают от 90 тыс. долларов в год в Amazon, Facebook, Google, Apple и нескольких сотнях других ИТ-компаний.

Команде удается поддерживать контакт с клиентами и оставаться в курсе того, какие им нужны навыки и специалисты. Отсюда высокая актуальность тренингов и конверсия студентов для выхода на работу 80% из них требуется менее шести месяцев, а рост заработной платы в среднем составляет 30 тыс. долларов. Эти моменты стали ключевыми в сделке с K12 крупным игроком в образовательной сфере, который выложил 165 млн долларов за проект в 2020 году.

Помимо Galvanize K12 выкупили еще одного организатора буткампов для разработчиков Tech Elevator, а потом переименовали себя в Stride, чтобы обозначить выход за рамки школьного образования и фокус на lifelong learning и персонализированном развитии карьеры собственных учеников. Кстати, за несколько лет до сделки Galvanize и сами приобрели двух производителей образовательного контента для аналитиков, дата-сайентистов и разработчиков, а глава последней компании возглавил Galvanize и довел его до сотрудничества с K12/Stride.

Из других примечательных особенностей запуск курса по машинному обучению вместе с IBM в 2017 году, когда компания решила познакомить аудиторию со своими облачными решениями и Watson API. Так появился IBM Cognitive Course.


Code Institute менее масштабный EdTech-проект из Европы. Он уступает Galvanize по численности сотрудников, но показатели трудоустройства учеников у CI даже выше до 94% выпускников выходят на работу менее чем за три месяца с момента завершения учебы.

Взаимодействие с бизнесом выстроено чуть иначе. Его представители контролируют качество контента напрямую. В экспертный совет входит и бывший CTO Red Hat, который сейчас работает в Google, ведущие инженеры PayPal, Mastercard, Dell и другихтехнологических компаний. Еще такой подход позволяет студентам получать дипломы Эдинбургского университета Нейпира там засчитывают CI-курсы в рамках классической программы по разработке ПО [Кстати, похожая система действует и в России в ИТМО экспертный совет оценивает стартапы магистров].

Фотография: Luca Bravo. Источник: Unsplash.comФотография: Luca Bravo. Источник: Unsplash.com

Команда работает над проектом шесть лет. Им управляет основатель и спикер Digital Marketing Institute. На старте Code Institute они провели seed-раунд на 500 тыс. евро, а в прошлом году привлекли 1,2 млн от двух венчурных фондов. Средства направят на развитие курсов и B2B-услуг.


Coassemble это SaaS-конструктор онлайн-курсов. С его помощью старшие специалисты компаний могут делиться опытом с коллегами и управлять процессом обучения: добавлять и редактировать контент, отслеживать завершаемость модулей и получать обратную связь. Как выглядят точечные разделы админки можно увидеть на YouTube-канале и в блоге проекта.

Основатели Coassemble из Австралии. Ранее они занимались разработкой приложений и корпоративных образовательных программ. С 2016 года они привлекали клиентов в основном из США и развивали стартап на свои деньги. За это время им удалось заработать ряд индустриальных наград. В 2020-м команда решила обратиться к венчурному финансированию и в рамках первого раунда подняла 4,4 млн долларов. На эти средства Coassemble планирует расширить штат своего представительства в Денвере и сделать продукт доступным для небольших компаний ранее команда сотрудничала только с крупным и средним бизнесом.


Pathlight предоставляет инструментарий для онбординга и обучения сотрудников в связке с бизнес-аналитикой. Для всего этого здесь предусмотрены дешборды, интеграции с продуктами вроде Salesforce, Zendesk и Slack. Сервис делает ставку на отслеживание бизнес-показателей компании в режиме реального времени и помогает соотносить их с тем, как развивается команда. Для коучинга и управления персоналом есть шаблоны и мониторинг KPI.

Фотография: Ant Rozetsky. Источник: Unsplash.comФотография: Ant Rozetsky. Источник: Unsplash.com

Один из основателей проекта сделал exit из маркетплейса для автомобилей Shift и компании, разработавшей помощника для водителей Automatic. Для Pathlight команда привлекла 1,1 млн в рамках seed-раунда в 2016-м и еще 7 млн долларов от венчурного фонда в прошлом году. Сегодня она может похвастаться несколькими сотнями корпоративных клиентов из сферы финансов, электронной коммерции и менеджмента с многочисленным штатом сотрудников. Сервис помогает им управлять проектамина дистанционке, автоматизировать формирование отчетов с помощьюNLP-инструментария и проводить точечные образовательные сессии.


EmployStream/Able помогает управлять процессом онбординга сотрудников, которые только присоединяются к новому коллективу или переходят из одного подразделения в другое. Руководству и HR-департаменту компаний-клиентов Able позволяет кастомизировать бизнес-процессы отбора и оформления персонала, их наполнение и отправку уведомлений.

Одна из фишекпроекта электронный документооборот и шаблоны, соответствующие требованиям законодательства США для трудовых договоров, в том числе с удаленщиками. Еще есть интеграция с Salesforce. Все это подходит для компаний, которые нанимают постоянно и в большом количестве. Able помогает им быстрее справляться со скринингом кандидатов, проверкой документов и сократить количество ошибок при их оформлении.

С 2014 года команда работала под названием EmployStream и привлекла 4,5 млн долларов инвестиций, а в 2020-м провела еще один раунд на 7 млн и ребрендинг продукта. Кстати, он годится не только для крупных компаний Able используют десятки хантинговых агентств.


P.S. В одном из следующих материалов мы расскажем о компаниях, предоставляющих инструментарий для VR-тренингов медицинского персонала, плюс посмотрим на eLearning системы для развития других навыков, прокачки эмоционального интеллекта и soft skills.

Актион Акселераторподходит для команд, разрабатывающих решения в области корпоративного образования и управления персоналом. Он включает пять направлений: от Обучения 4.0 до организации информационного взаимодействия внутри коллективов предприятий. Мы делимся с участниками инфраструктурой и экспертизой Актион-МЦФЭР, а победителям каждого трека выделяем по 500 тысяч рублей.

Заявки можно подавать и тем, кто находится на этапе идеи, начинает прорабатывать концепцию собственного сервиса или только собирается выводить его на рынок.

Подробнее..

Дом в лесу. Работа с освещением в Unity 3D

25.01.2021 20:08:49 | Автор: admin

Учебные материалы для школы программирования. Часть8

Spoiler

Продолжим "природную" тематику. Ранее, мы учились делать деревья, построили простой домик, а сегодня добавим чуточку света! Создав простую сцену, мы научимся основам работы с динамическим освещением, различными видами источников света и создадим фонарик.

Материалы к уроку здесь. Ну что, поехали!

Порядок выполнения

Начнем с нового проекта, и, для экономии времени и сил, добавим в него ассет Nature Starter Kit 2.

Откроем демо-сцену.

Удалим из неё камеру, добавим игрока от первого лица из ассета Characters, и импортируем дом из прошлого урока.

Видно, что дом абсолютно белый и мы проходим сквозь него. Перейдём в настройки импорта модели и выставим галочку Generate Colliders.

Далее, перейдём во вкладку материалов модели и сменим тип импорта материалов с Internal на External. Кликаем "принять", при этом происходит импорт материалов из папок SketchUp. В итоге, дом становится материальным и раскрашивается в нормальные цаета.

Но дом "просвечивает" по углам - давайте избавимся от этой проблемы:

Для этого выставим компонентам Mesh Renderer параметр Cast Shadows в значение Two sided. Теперь, свет проходит только через окна.

Уберём синеву и снизим яркость света. Для этого откроем панель Lighting и выставим Ambient Color значение пониже.

Теперь, найдём источник направленного света и изменим его цвет и интенсивность. Сделаем почти чёрный цвет с лёгким синеватым оттенком.

Добавим на вход светильник создадим сферу и новый для неё материал, выставим светимость материала в виде светло-серого цвета.

У сферы отключим отбрасывание теней.

Внутри сферы создадим Point Light, у которого увеличим дальность и выставим тип теней Soft Shadows.

Теперь, займёмся созданием фонарика. Для этого в игрока, во вложенный объект, который содержит камеру, добавим компонент Light и выставим его в режим Spot.

Добавим фонарику дальности и направим всего игрока на стену так проще настраивать.

Зачастую, не обязательно увеличивать интенсивность света, бывает достаточно добавить дальность это убережёт от "пересветов" на ближних дистанциях.
Также, свету можно добавить в параметр Cookie световое пятно. Импортированный пак содержит как минимум 2 готовые текстуры.

Это световое пятно добавит нашему фонарику необходимый эффект.

Теперь, сделаем так, чтобы фонарик можно было выключать. Для этого, создадим новый скрипт.

using System.Collections;using System.Collections.Generic;using UnityEngine; public class Flashlight : MonoBehaviour {   bool isOn = false;  public Light lightComponent;   // Use this for initialization  void Start () {   }   // Update is called once per frame  void Update () {    if (Input.GetKeyDown(KeyCode.F)) {      isOn = !isOn;      lightComponent.enabled = isOn;    }  } }

Закидываем его и указываем скрипту компонент, которым хотим управлять. При этом, мы должны отключить компонент света фонарика, чтобы при старте игры он был выключен.

Если учащиеся справились раньше, можно добавить звук включения / выклчюния фонарика: импортируем приложенный звуковой файл (в папке материалов к уроку), на объекте фонарика добавим компонент AudioSource и закинем в него звук, уберем чекбокс PlayOnAwake.

Код тоже придётся модифицировать, добавив обращение к AudioSource.

using System.Collections;using System.Collections.Generic;using UnityEngine; public class Flashlight : MonoBehaviour {   bool isOn = false;  public Light lightComponent;   // Use this for initialization  void Start () {   }   // Update is called once per frame  void Update () {    if (Input.GetKeyDown(KeyCode.F)) {      isOn = !isOn;      lightComponent.enabled = isOn;      GetComponent<AudioSource>().Play(); // Звук фонарика    }  } }

На этом этапе разбор динамического света и основных его источников можно считать завершённым.

В начале статьи, вы найдете ссылку на полный проект, но в случае с неустановленным SketchUp на ваш компьютер, модель дома не распознается.

Подробнее..

Бильярд на Unity 3D

31.01.2021 22:19:51 | Автор: admin

Учебные материалы для школы программирования. Часть10

Spoiler

Дорогой читатель! (произносить голосом Николая Дроздова)

Мы на юбилейном, десятом, проекте! Сегодня, стараясь избежать столкновения с полицией нравов, рассмотрим создание игры - бильярд. На этом занятии мы будем работать с системой материалов, освещением, и научимся использовать компоненты и скрипты без программирования.
В этой статье дано описание на примере полностью готового проета, но порядка выполнения работ это не меняет.

Порядок выполнения

Создадим новый 3D-проект, импортируем в него приложенный ассет. Ассет содержит звуки, скрипты и текстуры.

На сцену выставим плейн и зададим ему размер примерно 100х1х100. На плейн установим модель бильярдного стола.

Далее, создадим новый материал, применим ему текстуру ковра, уберём блеск, изменим тайлинг (см. скриншот) и закинем на Plane.

Настроим освещение: перейдем во вкладку Light, уберём скайбокс, и выставим заполняющий цвет потемнее.

Настроим туман, чтобы размыть края поля.

Добавим сверху стола источник света типа Spot и выставим ему мягкие тени.

Создадим новую сферу, добавим к ней Rigidbody и закинем, в поле физического материала коллайдера, материал Rubber.
Добавим скрипт Ball и настроим его.

Чтобы шар не был белым, создадим новый материал и настроим в соответствии со скриншотом.

Чтобы шар отражал мир, надо добавить на сцену новую Reflection Probe и запечь.

Удалим стандартную камеру. Следующим шагом будет добавление своей камеры на сцену. Для этого используем префаб FreeLookCameraRig. Настроим его, чтобы он следил за шаром, добавим скорости линейной и поворота.

Сразу же настроим камеру. Выставим ей очистку экрана цветом, в качестве цвета возьмём чёрный.

Далее необходимо создать 15 материалов по номерам шаров, как на скриншоте выше. Создадим новые сферы, добавим к ним Rigidbody и настроим физический материал коллайдера.
Выставим их на сцену, применим материалы и дадим им имена, соответствующие их номеру. В имени должна быть только цифра.

Для звука ударов шаров служит скрипт ImpactSound. Его необходимо добавить игроку и каждому шарику.

Теперь, необходимо добавить прицел. Создадим UI->Image, привяжем к ценру экрана и закинем в него картинку прицела.

На данном этапе, шар должен свободно кататься по полю по нажатию пробела, бить другие шары и издавать звук удара.
Далее, создадим пустой объект и закинем на него скрипт GameLogic.
Не забудьте создать AudioSource, выставить звук часов и галочки PlayOnAwake и Loop.

Скрипт следит за временем и ловит попавшие в него шары. Для того, чтобы скрипт мог это делать, необходимо выставить ему коллайдер и поставить галочку is Trigger.

Триггер большой, размером 200х1х200 метров, расположен чуть ниже уровня стола, триггер ловит шары и считает их, а в случае попадания шара игрока он перезагружает уровень. Для того, чтобы наш скрипт мог отличать игрока от других шаров, необходимо выставить игроку тег Player.

Скрипт требует двух текстовых полей для отображения времени и количества шаров.
Для начала создадим панель, закинем на неё Event Trigger и настроим на метод Shoot внутри скрипта игрока. Альфу выставим в ноль, чтобы панели не было видно.

Далее, создадим внутри ещё одну панель, привяжем её внизу экрана и создадим внутри два текста:

Настроим скрипт GameLogic, используя эти два текстовых поля. Также, закинем звук попадания в лузу.

Теперь добавим ещё один скрипт - Score.

Как видно, он тоже требует 2 текста. Можно продублировать прошлую панель, привязать её к верху экрана и настроить скрипт на неё.

По желанию, можно добавить ещё одну панель с парой кнопок для выхода из игры, закинуть скрипт RestartAndExit и настроить кнопки на него.

Таже можно добавить максимальный счёт. Создав ещё одно текстовое поле.

Закинем скрипт MaxScore на объект с GameLogic и настроим его на созданное текстовое поле.

На данном этапе игру можно считать готовой. Не забываем перезапечь освещение и отметить статью, как понравившуюся!

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru