Название: Carnage metal Разработчик: xMoonGuarDx Жанр: TBS (turn-based strategy) Среда разработки: Unity3D Платформа: PC Описание: (временное) Далекое будущие, уже не первое столетие идет колонизация человечества. Дик - капитан небольшой передвижной базы на одной из колонизированных планет. Промышляет перевозом грузов между городами. Времена нынче неспокойные, идут постоянные распри за ресурсы между организациями. Вот и сейчас Дик взялся за горячий заказ с доставкой важного груза - местной “принцессы”.
Игрок действует на двух картах: стратегическая и тактическая. У игрока конечная цель доставить груз из точки А в точку Б на стратегической карте. Стратегическая карта состоит из шестиугольников. На каждом из которых генерируется событие. На тактической карте происходит сражение. Поле состоит из шестиугольников. Каждый из шестиугольников имеет различные характеристики, некоторые из них могут быть разрушены под различными воздействиями (например вес юнита). На тактической карте игрок управляет набором роботов. Роботы делятся на типы и имеют ряд уникальных модификаций, которые влияют на их параметры. Маленькие роботы более маневренные, большие роботы имеют более широкий арсенал вооружений, следовательно с их помощью легче получить некоторые тактические преимущества. Игрок перед каждым боем комплектует команду роботов, в зависимости от типа задач, которые ему необходимо будет решить на тактической карте (не всегда все сводится к полному уничтожению противника).
Если верить тому, что я хочу реализовать, идея будет раскрыта при помощи размера роботов. Для одних задач будут требоваться маневренные роботы, для других будет в приоритете огневая мощь, в третьих количество самих роботов, где-то их потребуется больше, где-то меньше. В общем основная идея - это тактические бои с разными условиями, где и будут обыграны "размеры" юинтов путем вторичных характеристик (как пример, больше размер -> больше вес -> хуже проходимость на местности, как следствия нельзя будет пройти такие места, как мост или для типа местности для которой характерны узкие пространства имеет смысл брать более мощных юнитов в ущерб количеству юнитов)
16.09 - Составляется диздок. Идет параллельно всем задачам. 17.09 - 19.09 - Написание плагина unity для локализации 20.09 - Настройка окружения unity: создание широковещательной рассылки (событийная система), система управления менеджеров.
Так как графен не завезли, скорее всего игра будет геометрического формата, т.е. из кубов, треугольников и шаров xD Хотя глянул ассеты, есть весьма вкусные с небольшой стоимостью, может их закину. В общем искать надо, но т.к. преимущественно я программист, то и стремлюсь больше в эту сторону :) Вообще давно хотел написать что-то в жанре TBS. Посмотрим сколько для конкурса успею.
Сообщение отредактировал xMoonGuarDx - Вторник, 21 Июня 2016, 08:12
Суть плагина в том, что бы я из юнити мог описать все элементы текстовые, по ним составляется xml, которую потом кушает игра и может переключаться между языками. Т.е. просто стало лень руками составлять такую штуку, вот и прикрутил плагин. В дальнейшем хочу, так же как у l2 сделать подключение к гугл-таблицам и синхронизацию. Но это все после конкурса. Так же, если будет кому интересно, оформлю небольшую документацию, приведу в порядок и выложу в открытый доступ плагин, но опять же, после конкурса.
Я бы посмотрел на реализацию) В моем движке что то похожее сделано.
Если говорить о технических аспектах, то это не выглядит столь интересно. Поскольку для отрисовки GUI я использую API unity3d. Сама xml-ка составляется с помощью сериализации в .net. Единственный наворот, что пришлось сделать обертку текста в [CData] что бы любые символы отображать. Но это так, что бы говорить "он может в любой текст", по факту врятли это будет использоваться Из минусов, что я вижу, это конечно неудобство, когда будет много текстовых элементов (нужен поиск и категории), а так же если будет большой текст (надо дать возможность заполнять в больших текстовых полях значения)
В качестве основы для TBS в юньке буду использовать такой ассет, как Turn Based Strategy Framework. Это очень классный такой "шаблон", имеет неплохую кастомизацию на первый взгляд, если верить документации. А ещё очень активный создатель, который ответил мне в течении суток на мой вопрос. Из плюсов так же стоит отметить бесплатность ассета. Из текущих минусов, с которыми я столкнулся пока, так это невозможность делать юнитов, которые занимают два и более шестиугольников (как в героях 3 - драконы). А я все же хотел обыграть размер юнитов на поле, из разряда "я слишком жирный, я сюда не влезу". Я как раз по этому поводу писал разработчику, он указал, какие элементы надо будет переопределить и возможные проблемы, в общем это слишком много для двух месяцев на первый взгляд. Поэтому я решил сделать более интерактивными сами гексы (т.е. разрушение мостов под весом юнита, замедление на более мягкой почве более тяжелых юнитов, или замедление легких при сильном ветре. Т.е. придеться обыгрывать именно вторичные характеристики, которые связаны с размером.
Сообщение отредактировал xMoonGuarDx - Вторник, 21 Июня 2016, 07:33
Поскольку для отрисовки GUI я использую API unity3d
А чем API Unity не нравится?) По факту все расширения на ней рисуются Вот например написанные мной системы вещей и квестов, точнее их редакторы:
Отрисовка API Unity. Смысл в чём - нужно знать особенности) Как видно они похожи. Редактор кушает класс, проходится по его полям и представляет их в графическом виде. Конечно нужно не забывать про правильную сериализацию) Ещё приколюха в виде атрибута на зависимую сериализацию - поле с таким атрибутом сериализуется в зависимости от значения другого поля, вроде как Item Type и PotionData
По редактору скажу... В будущем было бы полезно добавить языки, а именно их список и возможность добавлять дополнительные языки. Тогда он вполне может пригодится кому-то ещё, возможно даже довольно большой аудитории
Сообщение отредактировал ShortKedr - Среда, 22 Июня 2016, 14:15
Все нравится, наоборот крутая штука Речь шла о том, что как раз графический вид для юньки, занял у меня львиную долю реализации (просто начинающий, первый раз смотрел что там можно вообще сделать), а не сама сериализация или логика.
ЦитатаShortKedr ()
В будущем было бы полезно добавить языки, а именно их список и возможность добавлять дополнительные языки
Да, это тоже отмечал. По факту это уже есть, логика под это написана. Просто GUI для добавления самого кол-ва языков пока не добавил. А так все поля языковые формируются автоматом, от заданного количества языков. п.с. редакторы классные. В description у квестов даже вижу вроде что-то скриптовое, любопытно. п.п.с. а ты что именно из предметов сериализуешь? Все? Просто вижу, что там подгружаются сами префабы, они сериализуются как-то? художник кстати тоже через юньку работает? Т.е. check library проверяет изменения в xml/json/etc на гите?
Сообщение отредактировал xMoonGuarDx - Среда, 22 Июня 2016, 14:35
xMoonGuarDx, спасибо) У квестов специальная связь со списком переменных. Во время игры такой текст можно распарсить через специальную функцию и получить строку со вставками переменных.
Сериализация, нет, не про json, я про unity сериализацию. В префабах можно довольно удобно хранить данные, но для этого нужно всё правильно связать с системой сериализации unity. Как известно, юнька не умеет сериализовать многие типы, например Dictionary<TKey, TValue>, следовательно данные не сохранятся. Проверить это можно в реализации инспектора для MonoBehaviour классов. Если интересно, есть интерфейс ISerializationCallbackReceiver для реализации нестандартной сериализации, в том числе можно Dictionary научить сериализоваться в unity. В целом же хранить данные в префабах используя сериализацию unity довольно удобно, можно спокойно хранить ссылки юньки на другие внутри-проектные префабы, текстуры, объекты и прочее...
Unity сериализует только то, что он привык отображать в инспекторе. Сериализует, так же, как поля Monobehaviour, то есть сохранённый пресет значений Кстати, первая иконка предмета в редакторе - это превью 3д модели
Check library проверяет правильность составленной библиотеки, т.е. повторы id, имён вызова и прочее. В общем-то нужно для работы системы во время игры)
Художник, да, он же не только художник :D Дизайном редактора он не занимался, это чисто моё конструктивное извращение
P.S. Ну, кстати, когда пишешь такой редактор, понимаешь, что Layout можно выбросить и просто рисовать, аналогично интерфейсу GUI
Сообщение отредактировал ShortKedr - Среда, 22 Июня 2016, 15:57
Как известно, юнька не умеет сериализовать многие типы, например Dictionary<TKey, TValue>, следовательно данные не сохранятся.
Тут не совсем в юньке дело, а в самой версии .net, которая заложена в неё. Да, именно из-за этого пришлось создавать собственный класс, просто это оказалось быстрее и проще, чем реализовывать интерфейс. Просто у класса и свойств задал парочку атрибутов [XmlRoot(string name)] и [XmlElement(string name)], так получилось быстрее для корректной xml. Хотя изначально вообще через XmlDocument создавал xml, но когда дошел до сохранения, стало влом описывать вариант сохранения и решил, что сериализация мощнее и быстрее) п.с. надо будет попробовать что-то подобное, как у тебя написать, после конкурса...
Сообщение отредактировал xMoonGuarDx - Среда, 22 Июня 2016, 16:01
xMoonGuarDx, тем не менее сериализовывать Dictionary можно, поэтому всё же UnityTechnologies не сделали сериализацию. Кстати это их интерфейс и предназначен он как раз для их сериализации)
Код
[Serializable] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver {
[SerializeField] private List<TKey> keys = new List<TKey>(); [SerializeField] private List<TValue> values = new List<TValue>();
public void OnAfterDeserialize() { this.Clear();
if (keys.Count != values.Count) throw new Exception("Keys and Values not have identity length");
for (int i = 0; i < keys.Count; i++) this.Add(keys[i], values[i]); }
Ох, что-то суровые рабочие будни наряду с учебой, не оставляют заветного времени, что бы заняться игрой. И вот вроде бы первый выходной, могу позволить себе что-нибудь написать, но вместо разработки игры, продолжаю допиливать компонент локализации, не знаю, что-то вставило меня это действо. Не удивлюсь, если вместо игры, будет готовая компонента xD
Немного картинок 1. Пусть у нас есть некоторый объект (как можно заметить, нужный атрибут уже добавлен)
2. Добавляем скрипт и тыкаем на кнопку
3. Получаем. Осталось задать id и дальше все будет сделано за вас. Т.е. подцепится перевод на нужном языке, в том числе в момент переключения языка в игре тоже. Конечно нужный id должен быть в xml файле с вашим переводом.
п.с. просматривает только самый верхний уровень объекта. Пока думаю над тем, делать ли вложенные. Но склоняюсь к тому, что нафиг надо. Что бы не получались перекрещивающиеся элементы. п.п.с. планирую когда-нибудь так же добавить синхронизацию с компонентом, которую я сделал выше. Что бы она(компонента) собирала все термы у сохраненных префабов, сравнивала с теми, которые уже есть и сообщала о том, чего ещё нет и необходимо определить.
Сообщение отредактировал xMoonGuarDx - Суббота, 25 Июня 2016, 17:31
xMoonGuarDx, здорово, я атрибуты тоже активно юзаю.
ЦитатаxMoonGuarDx ()
не знаю, что-то вставило меня это действо
У самого также
ЦитатаxMoonGuarDx ()
п.с. просматривает только самый верхний уровень объекта. Пока думаю над тем, делать ли вложенные. Но склоняюсь к тому, что нафиг надо. Что бы не получались перекрещивающиеся элементы.
Вложенные, это в смысле обработка внутренних объектных вложений? По идее её тоже нужно сделать. Сделай рекурсию, одной функцией сразу все вложение заполнишь.
Вложенные, это в смысле обработка внутренних объектных вложений? По идее её тоже нужно сделать. Сделай рекурсию, одной функцией сразу все вложение заполнишь.
Тут проблема в решении конфликтов. Например, на разных уровнях у пользователя будет один и тот же скрип. Что приведет к тому, что код не сможет определить, какой терм к чему относится. Как вариант, конечно, записывать не просто имя, указанное в атрибуте, но ещё и название объекта, на который повешен скрипт с атрибутом. Т.е надо тщательно проработать такой use case, думаю, что проблема скорее всего решаема.
Наткнулcя на статейку с блога по юнити, датированную апрелем, и это очень обнадежило меня. Говорят, что юнька в скором времени перейдет на .net 4.6 и c# 6. А это значит, что мы получим в своё распоряжение кучу сахара, и сможем делать свой код более выразительным ^^ Сама статья тут п.с. юбилейная 200-ая мессага :)
Сообщение отредактировал xMoonGuarDx - Воскресенье, 26 Июня 2016, 08:02
Например, на разных уровнях у пользователя будет один и тот же скрип. Что приведет к тому, что код не сможет определить, какой терм к чему относится.
До сих пор не могу понять почему он не сможет этого сделать :D Теперь я понимаю, что речь идёт про все объекты на сцене, но тут у меня ещё больше недоумения) Может вы не правильно что-то поняли. Какой терм и к чему он относится у вас определяется аттрибутом - что и чем заполнить) Небольшая вырезка кода:
Код
FieldInfo[] fi = obj.GetType().GetFields();
foreach (FieldInfo fieldInfo in fi) { object[] attributes = fieldInfo.GetCustomAttributes(typeof(LocalizationRequired), false); if (attributes.Length > 0){ LocalizationRequired lr = (LocalizationRequired) attributes[0]; Debug.Log(lr.localizationName); // Или как она у вас там зовётся) } }
attributes - это все аттрибуты типа LocalizationRequired у текущего поля. Для удобства можно использовать рекурсивную функцию с указанием объекта обхода, его типа и ссылкой на LocalizationComponent, что бы для вложенных объектов тоже её сразу вызывать.
Если речь идёт о другом, то просто обрабатываете все MonoBehaviour по цепочке:
Добавлено (26 июня 2016, 11:16) ---------------------------------------------
ЦитатаxMoonGuarDx ()
Говорят, что юнька в скором времени перейдет на .net 4.6 и c# 6
Это отличная новость :D
Добавлено (26 июня 2016, 11:29) --------------------------------------------- Я понял, что вы имели ввиду, так вот. Сделайте второй конструктор для LocalizationRequired, без параметров, добавьте какой нибудь bool флаг, который будет ставится на true только с первым конструктором. У полей классов с LocalizationRequired без параметров вызывайте FillTerms, но указывая уже этот класс. fieldInfo.GetValue знаете как пользоваться) Вот и решение проблеммы, нужно только сделать проверку, чем является поле
Код
if (fieldInfo.FieldType == typeof(string)) { //если string } else if (fieldInfo.FieldType.IsClass) { //если класс }
Сообщение отредактировал ShortKedr - Воскресенье, 26 Июня 2016, 11:39