майнкрафт на юнити 3д исходный код
Создание Minecraft на Unity3D. Часть вторая. Генерация мира
Авторизуйтесь
Создание Minecraft на Unity3D. Часть вторая. Генерация мира
Это вторая часть руководства по созданию собственной Minecraft-подобной игры. В ней мы напишем генератор мира и добавим персонажа, который сможет перемещаться по миру, ставить и удалять блоки. В предыдущей части мы создали куб с текстурой.
Добавляем функциональность мыши
Прежде чем мы приступим к программированию, давайте добавим на нашу сцену направленный свет. Нам нужен источник света, чтобы лучше видеть наш 3D-мир.
Вы можете поменять направление света, если хотите:
Позиционируем источник света
Теперь мы можем перейти к написанию нашего первого скрипта. Мы хотим реализовать функционал добавления нового экземпляра куба около стороны, на которую мы щелкаем правой кнопкой мыши, и удаления существующего блока по нажатию левой клавиши. Во вкладке Project перейдите в папку Code и создайте два C#-скрипта.
Добавляем в проект C#-скрипт
Мы назовем их WorldGenerator и ClickOnFaceScript.
Прежде чем мы продолжим, вам крайне рекомендуется ознакомиться со скриптингом в Unity.
Теперь откройте WorldGenerator.cs в MonoDevelop (которая уже установлена вместе с Unity) двойным щелчком по нему и введите следующий код:
Мы используем статический метод, чтобы создать клон нашего куба. Unity позволяет нам задать имя и позицию клона. Больше информации о методе Instantiate вы можете получить здесь.
В Minecraft, если вы находитесь достаточно близко к кубу и кликаете по нему левой кнопкой мыши, он исчезает и появляется в вашем инвентаре. Когда вы кликаете правой клавишей на любую из сторон куба, новый экземпляр появится на той стороне, по которой вы кликнули, в случае, если у вас достаточно материала в инвентаре. В данном уроке мы не будем ставить перед собой ограничения, так что у нас будет бесконечное количество кубов и бесконечная дистанция клика.
1 октября – 30 ноября, Онлайн, Беcплатно
Откройте ClickOnFaceScript.cs и введите туда этот код:
Теперь переместите скрипт на каждую из шести сторон куба на сцене.
Применяем скрипт к GameObject
Скрипт должен появиться на каждой стороне во вкладке Inspector.
Давайте запустим игру. Нажмите и проверьте, что отладочные сообщения появляются, когда вы кликаете по кубу во вкладке Game.
Тестируем нажатия кнопок мыши
Запомните! В режиме игры любые изменения, которые вы произвели с элементами во вкладке Scene, будут отменены. Не меняйте ничего, пока игра запущена. Нажмите еще раз, чтобы остановить игру.
Теперь у нас есть все что нужно, чтобы создавать новые кубы по клику правой клавишей мыши. Мы должны определить точную позицию нового GameObject, который будет появляться при клике. На нашей сцене расстояние между центрами двух соседних блоков равно единице.
Для простоты мы назовем центр куба, по которому кликают, буквой C, а центр блока, который должен появиться — N. Мы рассматриваем эти центры как позиции в 3D-пространстве.
Мы можем обобщить сказанное выше в простую формулу: N = C + delta, где delta — это смещение, требуемое для расчета центра нового блока. Каждая из шести сторон содержит свой экземпляр ClickOnFaceScript и разное значение delta.
Мы должны изменить ClickOnFaceScript.cs, чтобы реализовать функционал, описанный выше. Откройте скрипт и измените файл таким образом:
Вернитесь в редактор и поменяйте значения delta в соответствии с картинками:
Вся необходимая информация обведена
Проверьте, что все работает. Запустите игру несколько раз, задавая разные позиции камере (изменяя ее Transform во вкладке Inspector), чтобы проверить, что введенные нами значения delta верны.
Настраиваем позицию камеры и нажимаем на стороны кубов
Создаём персонажа
Если все работает, как задумано, мы можем перейти к созданию персонажа, чтобы мы могли свободно двигаться в нашей игре. К счастью для нас, Unity предоставляет готовый пакет с контроллером персонажа от первого лица, так что нам не нужно будет создавать его с нуля. Перейдите в Assets → Import Package и выберите Character Controller.
Импортируем пакет Character Controller
В окне Importing package выберите следующее:
Во вкладке Project перейдите в Standard Assets → Character Controllers, выберите First Person Controller.prefab и перетащите его во вкладку Hierarchy.
Заготовка First Person Character Controller
Расположите его близко к центру сцены.
Настраиваем местоположение заготовки
Мы должны защитить нашего персонажа от падения, прежде чем перейти к тестированию. Мы вернем значение обратно, когда закончим алгоритм генерации мира.
Гравитация не нужна!
Проверьте, что все работает.
У First Person Controller на нашей сцене есть Camera, прикрепленная, как дочерний GameObject. Когда мы запустим игру, эта камера станет главной на сцене, так что нам больше не нужна другая. Каждая камера содержит компонент AudioListener. Это и есть причина, по которой сообщение «There are 2 audio listeners in the scene. Please ensure there is always exactly one audio listener in the scene.» появляется во вкладке Console. Отключите объект Main Camera во вкладке Hierarchy.
Отключаем главную камеру
Мы почти закончили! Откройте скрипт WorldGenerator.cs и модифицируйте его:
Скрипт будет запускаться только тогда, когда он прикреплен к какому-нибудь GameObject на сцене. Создайте пустой Empty GameObject и перетащите WorldGenerator.cs на него.
Перетаскиваем WorldGenerator.cs на новый GameObject
Перетащите объект Voxel на соответствующее поле в скрипте. Эта версия алгоритма генерации мира хранит все блоки в памяти, так что не рекомендуется задавать большие значения полям Size X, Size Y и Size Z, иначе вам грозит низкая производительность или, что еще хуже, Unity может вылететь.
Размеры больше указанных выставлять не стоит
Прежде чем мы увидим нашу разработку в действии, не забудьте поправить поле Gravity в скрипте, прикрепленном к Character Controller.
И всё-таки гравитация важна
Готово! Нажмите и веселитесь!
Хинт для программистов: если зарегистрируетесь на соревнования Huawei Cup, то бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.
Перейти к регистрации
Unity выложила исходный C#-код на Github
Код был выложен вчера, официальный анонс состоится только в понедельник.
Ложка дегтя: код может быть использован только в справочных целях. Полную лицензию на использование можно посмотреть здесь.
Впрочем, это ничуть не остановило товарища, уже оформившего пулл-реквест с фиксом производительности.
Далеко не секрет, что крупные студии (например, авторы Cities: Skylines) имеют доступ к исходному коду (и C#, и C++) уже довольно давно — для этого необходимо приобретать отдельную лицензию. Раньше это было критически необходимым, если вам требовалось модифицировать стандартный процесс рендеринга (начиная с версии 2018, можно будет менять все под себя при помощи SRP и кода на C#).
За данную инициативу дружно благодарим Aras Pranckevičius, который занимался подготовкой кода к публикации последние несколько недель.
Движок Unity становится более модульным и проходит масштабное обновление: в нем появился пакетный менеджер, появилась система задач C# (позволяющая писать безопасный многопоточный код), была переработана система ECS (Entity Component System) с учетом низкоуровневых оптимизаций, а к версии 2018.3 наконец-то появятся (sic!) Nested Prefabs.
Глубокий уход Unity в сторону data-oriented design происходит под чутким надзором Майка Эктона (Mike Acton, бывший глава разработки движков в Insomniac Games), присоединившегося к компании прошлой осенью вместе с другим соратником по Insomniac, чей подход к игровой оптимизации приобрел широкую известность после доклада на CppCon 2014 «Data-Oriented Design and C++»).
Интересное недавнее интервью CTO Unity, главой R&D и Эктоном можно прочитать на английском по ссылке. По всей видимости, публикация исходного кода — это еще один важный шаг для нового курса компании.
Цикл уроков “Unity3D Minecraft”
Для кого они?
— для тех, кто уже знаком с движком Unity3D и знает все основы
Чему вы научитесь?
— многим интересным алгоритмам
— различным приемам работы с Unity3D
— создавать аналог Minecraft
Урок 1. Создание ландшафта
Теперь нам следует подумать, как мы будем генерировать ландшафт (выбор алгоритма). Можно будет использовать шум Перлина и его модификации, но для начала можно будет использовать данный алгоритм (http://www.ixbt.com/video/3dterrains-generation.shtml). Ознакомтесь с ним и переходите далее.
private var _field: GameObject[,,]; // наш ландшафт (является трехмерным массивом)
private var _height: int[,]; // высота данного места ландшафта
private var _maxSize: int = 32; // максимальная ширина ландшафта
private var _maxH: int = 64; // максимальная высота ландшафта
private var _maxR: int = 16; // максимальный радиус сферы
private var _spheresCount: int = 16; // количество сфер
var _prefabCube: GameObject; // префаб куба
function Start ()
<
// Инициализация массивов
_field = new GameObject[_maxSize, _maxH, _maxSize];
_height = new int[_maxSize, _maxSize];
// Создание поля (высота равна 0)
var i: int;
var j: int;
for (i = 0; i 0 && _x>=0 && _z>=0 && _x Примечания:
— Алгоритм заполнения промежутков можно было бы улучшить, чтобы еще была земная кора, но тогда время запуска увеличится.
Unity3d и развеивание некоторых мифов
Несколько комментариев
Данный подраздел статьи является комментарием к комментариям — текст в кавычках не мой.
«Поддержка кеширования ассетов на клиенте продается за отдельные очень большие деньги (это которая не в браузере, а отдельно на диске)».
В 3.2 есть кеширование для всех (с ограничениями, конечно).
«Автор аккуратно опустил две очень серьёзные проблемы:
— Игры на Unity требуют большого трафика,
— Нельзя использовать сложные динамичные сцены».
«Игры на Unity имеют элементарную игровую механику — сложный бой с несколькими игроками будет весьма тормозить».
«Под сложным боем Я имел в виду совместную игру нескольких игроков. Для Unity это является узким местом. Опускать этот момент нельзя, т.к. основное требование к современным играм — это высокая степень социализации. Игроки хотят играть в игры со своими друзьями. Отметьте, что в социальных сетях игр на Unity практически нет».
Отметьте, что большинство игр в социальных сетях имеет асинхронный принцип работы. Т.е. когда Петя в универе, я пришел и сломал ему грядку – Петя пришел домой, зашел на свою страничку в контакте, разозлился и отправил отряд мстителей ко мне на грядку. А я, естественно, в момент нападения никак не взаимодействую с Петей напрямую. Фраза о том, что «совместная игра нескольких игроков является узким местом Unity» звучит, мягко говоря, неприлично – особенно если говорить о действительно небольшом количестве игроков в одной комнате, либо о стороннем сетевом решении.
«И как результат:
— Игры на Unity у людей с низким трафиком превращаются в кошмар,
— Игры на Unity имеют элементарную игровую механику — сложный бой с несколькими игроками будет весьма тормозить».
Вообще, минимальное приложение в вебплеере будет весить чуть больше 500кб, а дополнительные ресурсы можно подкачивать в Asset Bundles (которые пакуются 7z). Если мы говорим именно о трафике, возникающем при обмене игровыми сообщениями – здесь снова играет роль выбранное решение для сети.
«Unity хорош, но прежде чем бросаться писать осмыслите 2 минуса
1: ЗД не панацея и применять его надо осторожно. Посмотрите на топ аппстора — там в основном 2д игры. Посмотрите на соц игры в которые играют сотни миллионов — там нет 3д. Только небольшое количество игровых механик по настоящему требует 3Д.
2: Сделать сочную притягательную графику на 3Д гораздо сложнее чем на 2Д и удается это только профессионалам. Любители и новички делают с 3Д картинку вызывающую страх и ужас…».
Здесь явно присутствует непонимание того факта, что на Unity можно замечательно делать 2д игры. Чем и занимается целая толпа разработчиков в аппсторе (и некоторый процент игр был\есть в top100, между прочим) и казуальщики.
«В Юнити есть deferred освещение, встроенный редактор шейдеров».
Небольшая ошибочка. По-умолчанию никакого подобного инструмента не поставляется, но есть один качественный бесплатный — Strumpy Shader Editor и один платный редактор шейдеров — ShaderFusion. Шейдинг в 3.х шагнул на встречу разработчику (появились surface shader’ы), поэтому написание собственных шейдеров (без визуального редактора) не представляется чем-то невероятным. Портирование шейдеров проходит, в целом, отлично (к примеру, без проблем можно взять и быстренько переделать под юнити что-то отсюда).
«Он [Unity3d] закрыт. Т.е. исходных кодов вам не дадут даже по лицензии».
Исходники можно купить, если вы очень уж серьезный разработчик (правда, стоимость исходников начинается от 100к, я предполагаю, а также я вижу очень призрачную вероятность того, что эти исходники вам понадобятся).
А на лицензии (1500$, если мы говорим про Unity PRO), кстати, несколько раз в год бывают скидки, обычно
20%. Ограничения базовых версий (Unity за 0$, Unity iPhone за 400$) не так велики – значительное количество проектов можно разработать и на них.
«Кто-нибудь пробовал Unity для Android / iOS? Как впечатления?»
Впечатления отличные.
Недавно, например, проходил конкурс от компании Qualcomm на создание augmented reality приложения (можно было использовать квалкомовский Unity SDK) и призы составляли неплохие 125, 50 и 25 тысяч долларов за первое, второе и третье места соответственно.
Обе платформы разработчики активно допиливают и оптимизируют.
На мощных мобилках поддерживается Open GL ES 2.0 (попиксельное освещение, шейдеры) – это, по-моему, отлично. Можно пытаться делать что-то похожее по качеству на Epic Citadel.
Ещё немного мыслей
Пока я выписывал мысли на бумагу, появилась новая статья на тему Unity от этого же автора (автор молодец!).
«Серьезные сцены удобнее отдать делать artist’ам в 3DS Max’е том же. Единственное что плохо — что из FBX (промежуточный формат между максом и юнити) Unity не импортирует источники света. Пришлось писать плагин к Unity на С++. А это доступно только в платной версии. Вобщем намучались с этим движком.»
Скажите, а зачем было писать плагин на С++, если источники света нормально переносятся в юнити в виде геймобъектов-пустышек (dummy)? Можно договориться с художниками о том, как правильно обзывать источники света и написать небольшой скрипт в юнити, который бы при импорте модельки эти источники бы создавал. И сборка уровня в юнити, и сборка уровня в 3д пакете имеют свои плюсы и минусы – и выбор больше, на мой взгляд, зависит от предпочтений разработчиков.
«Возможно, все-таки стоит взяться за реализацию своего майнкрафта с блекджеком — все возможности вроде есть».
Говорят, что с сетью в Unity3d дела плохи, и двиг не годится для большого числа коннектов. На самом деле все проще – и тот кто знает, что говорит, имеет в виду именно встроенный networking. Потому что вместо встроенного решения можно использовать практически всё что угодно:
Естественно, можно написать что-то свое на произвольной технологии (c++, Java, Erlang, c#, whatever) и прикрутить какой-то еще существующий networking solution. Что-то основанное на TCP\UDP подходит отлично. Если работать по HTTP протоколу, то наиболее частый выбор это php – хотя, как вы понимаете, тот же Erlang или нечто другое тоже подойдет.
Оптимизация
Грабли
Интересные дополнения к Unity3d
Минусы
Заключение
Минусы можно найти везде, если покопаться. На тему проблем и заморочек в Unity можно дискутировать очень долго, способ решенить проблему есть почти всегда. Я думаю, что юнити замечательный инструмент, и если в 2011м Unity Technologies не подкачает – всё коммунити будет водить хороводы и радоваться «как хорошо что любимый инструмент развивается!».
На носу Unity 3.2 – присоединяйтесь к юнитологам!
Практическое руководство по взлому (и защите) игр на Unity
Когда речь идёт о программном обеспечении, термин «взлом» зачастую ассоциируют с пиратством и нарушением авторских прав. Данная статья не об этом; напротив, я решительно не одобряю любые действия, которые прямо или косвенно могут навредить другим разработчикам. Тем не менее, эта статья всё же является практическим руководством по взлому. Используя инструменты и методы о которых далее пойдёт речь, вы сможете проверить защиту собственной Unity игры и узнаете, как обезопасить её от взлома и кражи ресурсов.
Введение
В основе взлома лежит знание: необходимо понимать особенности компиляции Unity-проекта, чтобы его взломать. Прочитав статью, вы узнаете, каким образом Unity компилирует ресурсы игры и как извлечь из них исходные материалы: текстуры, шейдеры, 3D-модели и скрипты. Эти навыки будут полезны не только для анализа безопасности проекта, но также для его продвинутой отладки. В связи с закрытостью исходного кода, Unity часто работает как «черный ящик» и порой единственный способ понять, что именно в нём происходит — это изучение скомпилированной версии скриптов. Кроме прочего, декомпиляция чужой игры может стать серьёзным подспорьем в поиске её секретов и «пасхальных яиц». Например, именно таким образом было найдено решение финальной головоломки в игре FEZ.
Находим ресурсы игры
Рассмотрим для примера игру, собранную под ОС Windows и загруженную через Steam. Чтобы добраться до директории, в которой находятся нужные нам ресурсы, откроем окно свойств игры в библиотеке Steam и в закладке «Local files» нажмём «Browse local files…».
Извлекаем текстуры и шейдеры
Графический интерфейс программы не отличается удобством, а также она страдает от нескольких критических багов. Не взирая на это, программа вполне способна извлечь большинство текстур и шейдеров из игры. Полученные в результате текстуры будут иметь формат DDS, который можно «прочитать» с помощью Windows Texture Viewer.
С шейдерами ситуация обстоит сложнее: они извлекаются в уже скомпилированным виде и, насколько мне известно, решений для их автоматической трансляции в удобочитаемый формат не существует. Тем не менее, это обстоятельство не мешает импортировать и использовать полученные шейдеры в другом Unity-проекте. Не забывайте, однако, что подобная «кража» нарушает авторские права и является актом пиратства.
Извлекаем 3D-модели
Трёхмерные модели в типовой Unity-сборке «разбросаны» по различным ресурсам, а некоторые из них и вовсе могут генерироваться во время игры. Вместо копания в файлах, существует интересная альтернатива — получить данные о геометрии прямиком из памяти графического ускорителя. Когда игра запущена, вся информация о текстурах и моделях, видимых на экране, находится в памяти видеокарты. С помощью утилиты 3D Ripper DX можно извлечь всю эту информацию и сохранить в формате, понятном 3D-редакторам (например, 3D Studio Max). Учтите, что программа не самая простая в обращении — возможно, придётся обратиться к документации.
Взламываем PlayerPrefs
Защищаем PlayerPrefs
Помешать пользователю редактировать значения в системном реестре мы не в силах. А вот проверить, изменялись ли эти значения без нашего ведома — вполне реально. В этом нам помогут хеш-функции: сравнив контрольные суммы хранимых данных, мы сможем убедиться, что никто и ничто, кроме нашего кода эти данные не изменяло.
Приведенный выше класс — упрощенный пример реализации, работающий со строковыми переменными. Для инициализации ему необходимо передать секретный ключ и список PlayerPrefs-ключей, значения которых должны быть защищены:
Затем его можно использовать следующим образом:
Взламываем исходный код
Данных подход особенно эффективен для наших целей: Unity очень скупо оптимизирует исходный код игровых скриптов, практически не изменяя его структуру, а также не скрывает названия переменных. Это позволяет с легкостью читать и понимать декомпилированый материал.
Защищаем исходный код
Раз Unity не заботится о сохранности нашего кода — сделаем это сами. Благо, существует утилита, готовая автоматически зашифровать плоды нашего интеллектуального труда: Unity 3D Obfuscator.
И хотя программа отлично справляется со своими обязанностями, многие классы, адресуемые извне родной библиотеки, всё же не могут быть зашифрованы без риска нарушения связанности — будьте осторожны!
Взламываем память игры
Cheat Engine — широко известная программа для взлома игр. Она находит ту область оперативной памяти, которая принадлежит процессу запущенной игры и позволяет произвольно её изменять.
Эта программа пользуется тем фактом, что разработчики игр очень редко защищают значения переменных. Рассмотрим следующий пример: в некой игре у нас есть 100 патронов; используя Cheat Engine, можно выполнить поиск участков памяти, которые хранят значение «100». Затем мы делаем выстрел — запас патронов составляет 99 единиц. Снова сканируем память, но теперь ищем значение «99». После нескольких подобных итераций можно с легкостью обнаружить расположение большинства переменных игры и произвольно их изменять.
Защищаем память игры
Использовать нашу новую структуру можно следующим образом:
Если вы выводите значения переменных на экран, хакеры всё ещё смогут перехватить и поменять их, но это не повлияет на действительные значения, хранящиеся в памяти и использующиеся в логике игры.
Заключение
К сожалению, существует не так уж много способов защитить игру от взлома. Будучи установленной на пользовательское устройство, она фактически раскрывает все ваши текстуры, модели и исходный код. Если кто-то захочет декомпилировать игру и украсть ресурсы — это лишь вопрос времени.
Невзирая на это, существуют действенные методы, которые позволят серьёзно усложнить жизнь злоумышленникам. Это не значит, что нужно вдаваться в панику, шифровать весь исходный код и защищать каждую переменную, но по крайней мере задумайтесь, какие ресурсы вашего проекта действительно важны и что вы можете сделать для их защиты.