Так как в Unity классовая система существенно отличается от оной в UDK, хочу спросить, как лучше всего реализовать абстрактные элементы геймплея.
Что я имею ввиду? Например, рецепт для крафта. Он содержит инфу об необходимых ингредиентах, условиях крафта, и об результате. Его далеко не обязательно делать в виде обычного геймОбжекта, так как на уровне ему делать нечего. С другой стороны, его нежелательно делать структурой, так как он может находиться в самых различных классах - в списке крафта игрока, в списке учителя крафтинга, в предмете, с помощью которого можно изучить рецепт.
Ну или предметы в инвентаре. Их же тоже не обязательно размещать на уровне, пока те непосредственно в инвентаре.
Была мысль делать подобное классами, однако, в меру отсутствия опыта, не знаю, получится ли сделать так.
Добавлено (16.12.2013, 07:17) --------------------------------------------- Впрочем, есть плюс и в хранении в виде префабов - тогда легче редактировать данные, да и не нужно создавать отдельный класс на каждый предмет/рецепт.
Когда-то тут будут ссылки на крутые проекты. Или нет.
в Unity один скрипт = один класс (в обычных обстоятельствах). есть статические элементы класса - которые доступны из любой области игрового мира. скрипт это почти всегда -- компонент, прикрепленный к объекту. т.е. методика обращения к элементам скрипта это - найти объект в пространстве, получить компонент, взять нужные данные из объекта. (статические классы могут быть доступны и без этого естессно.)
инвентарь - для ВИЗУАЛЬНОЙ (не текстовой) игры - это всегда игровой объект, даже если он "пока" в инвентаре. в плагине NGUI есть пример инвентаря для Unity и еще в нескольких плагинах и китах. в общих словах - это префаб, для которого хранятся данные в скрипте (базе рюкзака), когда активизируется рюкзак - предмет визуализируется (не знаю какой уровень очевидности для тебя пройден! ).
крафтинг - имхо, целая игровая система, где одним скриптом (классом) не обойдешься никак. т.е. скорее всего - на каждый предмет крафта будет свой класс (отдельный файл со скриптом) и будут отдельные классы для процесса крафтинга, для обучения ему, отслеживания в сценарии и тп и тд. для всех предметов крафтинга - будет предок класс, из него будут расти потомки разного вида, у них будут персональные значения полей - "учитель", "условия получения", "цена покупки", "рецепт", "текущий владелец" и тп не знаю что еще.. сделать сбалансированную классовую модель крафтинга - это и будет "создать свой Craft Kit пакет". в общем тут нужна система классов. просто хранить данные можно и в структуре. делать переменную этой структуры можно будет где угодно. тут если бы был пример всей цепочки можно было бы конкретнее показать. Мыслю - значит программирую... Конструктивная критика - умных ведет к совершенству... Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
Сообщение отредактировал KamiRonin - Понедельник, 16 Декабря 2013, 09:48
т.е. скорее всего - на каждый предмет крафта будет свой класс
1) Любая вещь инвентаря есть описание этой вещи. ID картинки, ID описания из файла локализации, Количество.
Ничего более. Ни при каких обстоятельствах не нужно мешать сюда код рендеринга ( очень любят мешать все до кучи )
Это класс-родитель любой вещи. На тот случай если нужно создать МНОГО разных наследуемых типов со своими заморочками ( у меня в данжелоте2 вещи делятся на артефакты со своей логикой, но все они наследуют базовые элементы от абстрактного класса вещи.
Отдельно создается класс инвентаря с кнопками в которые удобно грузится абстрактная информация вещи. В кнопке происходит рендеринг ячейки инвентаря на основе полученных данных вещи и нажатие по вкусу ( можно сделать глобальное нажатие из класса инвентаря ).
Сами же вещи можно хранить в списке. ( Одномерный массив отлично подходит и для поля ячеек, просто чуть чуть надо больше мозгами раскидывать ) ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
// создаем новые артефакты new Artifact("sword","sprite_sword,"меч","крутой меч",1); new Artifact("bow","sprite_bow,"лук","крутой лук",1,ITEMQUALITY.epic);
объект может быть и пустым. но как сделать инвентарный предмет видимый в игре и при этом чтобы у него отсутствовал игровой объект... только если инвентарь является менеджером объектов и просто по описанию строит их изображение. просто обычно в инвентаре - объект таскается и кидается на слоты или другие объекты.. стоит ли все отрабатывать так, чтобы не было объекта предмета вообще? не сложнее ли это?! в текстовых играх объект может быть просто словом.. и поэтому можно обойтись.
Цитатаseaman ()
Только унаследованный от MonoBehaviour. Кто Вам мешает от него не наследоваться?
абсолютно согласен. но нужно было с чего то начать дискуссию. в ScriptingReference любой класс рекомендуют оформлять в виде отдельного файла. причем имя файла должно совпадать с именем класса в обязательном порядке! и с наследованием от моно эт никак не связано. но конечно опыт показывает что в один файл можно запихать и несколько классов. эт да. тут на форуме была тема о том, как лучше для проектов организовывать скрипты. писать много или все совать в один..
Цитатаseaman ()
У меня 90% скриптов НЕ прикреплены к объектам. Что я делаю не так?
подловили. у меня (и в некоторых других примерах) скрипты связанные с квестами, крафтами и инвентарем - прикреплены к объектам... но это - Ваша правда -- дело вкуса. Если Вы пишете в основном статические классы или библиотеки инструментальных классов и функций, или делаете не мононаследующие структуры классов со статическими функциями - это же просто логика организации структуры выбранная Вами и все.
Цитатаpixeye ()
Что за... фигня?
1) Нужно понять, что ваши только что сделанные скрипты - классы таковы потому что наследуются от юнитивского MonoBehaviour 2) Любая вещь инвентаря есть описание этой вещи. ID картинки, ID описания из файла локализации, Количество.
Ничего более. Ни при каких обстоятельствах не нужно мешать сюда код рендеринга ( очень любят мешать все до кучи )
скрипты классы в C# потому что они всегда классы. а не потому что наследуются от моно. и про рендеринг .. может я что то пропустил ??
вещь инвентаря - это просто описание этой вещи, и просто её индивидуальный способ взаимодействия с другими объектами, и просто некие условия её например порчи, продажи и прочего. просто для меня например - писать все эти сопутствующие вещи - в одном скрипте на плейменеджере каком нибудь или инвентаре - это получается неоправданно перегруженный условиями скрипт! ведь он должен проверять все сопутствующие условия для каждого вида объекта. конечно от логики организации зависит. если сделать универсальные параметры "поломки" вещи (например отмычка или веревка) тогда можно и так. но разве не нагляднее в каждом предмете иметь свой "механизм" поломки и прочего. ну эт дело вкуса и способа восприятия целостности системы.
Добавлено (16.12.2013, 13:26) --------------------------------------------- pixeye, очень наглядно в "грубом примере"! что можно обойтись вообще без каких либо игровых объектов - просто выбор лука на пальцах, "в уме"!! и игродел сам решит, что делать потом с этим виртуальным луком - как визуализировать, ГДЕ, к кому прикрепить, как взаимодействовать! супер. чистая база объектов и больше ничего. из lootSpriteID потом достается картинка для инвентаря или еще для чего. нормально!! и главное четко на вопрос отвечает - спросили про абстрактные объекты вне сцены - вот ответ! молоток!! можно и так, почему нет?!!!! и в ngui отдельный класс для такой базы в примере был создан. еще 3D префаб к итему указывается по имени и все. потом одеваешь орка в любые браслеты.
Цитатаpixeye ()
у меня в данжелоте2 вещи делятся на артефакты со своей логикой, но все они наследуют базовые элементы от абстрактного класса вещи.
спросить хочу, а там функции кроме выбрал-купил-добавил_скил какие нибудь предусмотрены в работе с объектами? ну - соединение, поломка, апгрейд и тп Мыслю - значит программирую... Конструктивная критика - умных ведет к совершенству... Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
Сообщение отредактировал KamiRonin - Понедельник, 16 Декабря 2013, 15:11
перегруженный условиями скрипт! ведь он должен проверять все сопутствующие условия для каждого вида объекта.
ээ - использованием делегатов можно избавиться от большого кол-ва условий.
ЦитатаKamiRonin ()
но разве не нагляднее в каждом предмете иметь свой "механизм" поломки и прочего
У меня сейчас больше 40 предметов. Из них 16 ломаются. Я сомневаюсь что у каждой из 16 вещи будет свой индивидуальный механизм. в 90% будет копипаста. Допустим по какой то причине я изменил правила поломки. Следует из того что ты написал, что мне надо будет 16 раз менять свой код?) ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
спросить хочу, а там функции кроме выбрал-купил-добавил_скил какие нибудь предусмотрены в работе с объектами? ну - соединение, поломка, апгрейд и тп
Да. У меня был крафт ( сейчас заморожен ) - написал где-то за неделю. Сейчас есть апгрейд вещей по кристалликам. Есть уровень вещи, он влияет на значение шанса успешного апгрейда, есть цена апгрейда в деньгах и кристаллах. Через N уровней нужно использовать другой кристалл ( более редкий ), так же уровень влияет на базовое значение вещи ( атака, хп, защита ) и повышает прочность ( влияет на шанс поломки ) и значение бафа/черты которая присоединена к вещи ( например перк вампиризм N % шанс насосаться крови врага )
Так как изначально в данжелоте 2 я планировал сделать автогенерацию вещи на манер диаблы ( суффиксы, аффиксы ) добавляющие рандомные баффы и свойства, то написал довольно комплексную систему которую в итоге и упростил:)))) Так как оказалось все это для такой игры не так очевидно и фаново.
Однако остов остался. У меня есть отдельно класс свойство вещи ( абстрактный ) который содержит значения связанные со свойством ( id, способ применения, макс значение, текущее значение ) - это было рисково так как немного ограничивает мой выбор действий, но пока хватает с лихвой.
Я использую обширную систему эвентов которые позволили мне очень быстро и легко добавлять новые свойства. Например прослушивание эвента приема значения дамага монстра перед передачей его игроку.
Цитата
int dmg = calculateDamage (); event_attackDamage (ref dmg); HeroClass.Instance.ApplyDamage (dmg);
Что мне это дает. А вот что. Допустим у меня есть щит который снимает половину урона.
Не в даваясь в подробности, но смысл такой. Я выбираю монстра для атаки - в этот момент он у меня выделенный. При первой активации ( для моей игры это нормально ) прогоняются события инициализации. Учитывая наличие щита будет что то такое
А вот в эвент приема дамага конкретного монстра я добавляю этот метод от своего артефакта-щита
Код
public void shBlock_handler (ref int val) { if (Random.Range (0f, 100f) > Traits ["shBlock"].baseVal) return;
val = Mathf.CeilToInt (val * 0.5f);
}
Все очень просто: если условия выполнения допускаются то я просто возвращаю половину значения дамага который должен передать монстр.
Цитата
int dmg = calculateDamage (); - допустим тут значение 4 event_attackDamage (ref dmg); - после обработки щитом значение 2 HeroClass.Instance.ApplyDamage (dmg); отправка герою конечного дамага 2
ээ - использованием делегатов можно избавиться от большого кол-ва условий.
тут человек не знает как к классам подступить.. а ты сразу делегатами его! :)))) ну в принципе в качестве ориентира - на будущее... тоже полезно!
Цитатаpixeye ()
У меня сейчас больше 40 предметов. Из них 16 ломаются. Я сомневаюсь что у каждой из 16 вещи будет свой индивидуальный механизм. в 90% будет копипаста. Допустим по какой то причине я изменил правила поломки. Следует из того что ты написал, что мне надо будет 16 раз менять свой код?)
ну не знаю.. я код не видел. может у тебя все предметы ломаются одинаково - "отмычка порвана в клочья", "веревка заржавела и разбилась вдребезги" :))) ведь если универсализировать понятие поломки - типа "целостность веревки 65%" и все тут.. тогда вообще лафа..
Цитатаpixeye ()
Да. У меня был крафт ( сейчас заморожен ) - написал где-то за неделю. Сейчас есть апгрейд вещей по кристалликам. Есть уровень вещи, он влияет на значение шанса успешного апгрейда, есть цена апгрейда в деньгах и кристаллах. Через N уровней нужно использовать другой кристалл ( более редкий ), так же уровень влияет на базовое значение вещи ( атака, хп, защита ) и повышает прочность ( влияет на шанс поломки ) и значение бафа/черты которая присоединена к вещи ( например перк вампиризм N % шанс насосаться крови врага )
молоток!!! так держать! там класс вещи - такой же простой?? ну в смысле - обошелся без индивидуального класса на каждый предмет? Мыслю - значит программирую... Конструктивная критика - умных ведет к совершенству... Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
Сообщение отредактировал KamiRonin - Понедельник, 16 Декабря 2013, 13:45
молоток!!! так держать! там класс вещи - такой же простой?? ну в смысле - обошелся без индивидуального класса на каждый предмет?
Да - у меня нет ни одного индивидуального класса ни на монстра, ни на героя, ни на вещи, ни на артефакты) это позволяет мне максимально быстро добавлять новый контент на основе имеющихся ресурсов и скриптов. Я просто делаю описательный документ xml файл и это в игре:)
Посути полуручной редактор игры без интерфейса ( вбиваю xml сам )) ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
предельно просто!! на самом деле мысль понятна.. но ПОЧЕМУ Пошел таким путем - совсем я не понял. разве не легче было у Hero сделать метод TakeBlow(int мainSkill, List<additionEffects> addEff); который бы вызывал атакующий и передавал туда параметры. а внутри метода у хироу - просто +/- по всем его внутренним наличиям - что-то на основной хит бы ложилось (минусовало или плюсовало урон), а что-то на эффекты?!?!? :-/ в списке эффектов - заморозка, отравление и прочее!!
Да - у меня нет ни одного индивидуального класса ни на монстра, ни на героя, ни на вещи, ни на артефакты) это позволяет мне максимально быстро добавлять новый контент на основе имеющихся ресурсов и скриптов. Я просто делаю описательный документ xml файл и это в игре:)
ууухх.. какой однако резон, имхо, немного сомнительный!! что каждый день по 20 новых монстров или сабелек появляется?? прям не знаю.. Мыслю - значит программирую... Конструктивная критика - умных ведет к совершенству... Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
азве не легче было у Hero сделать метод TakeBlow(int мainSkill, List addEff); который бы вызывал атакующий и передавал туда параметры. а внутри метода у хироу - просто +/- по всем его внутренним наличиям - что-то на основной хит бы ложилось (минусовало или плюсовало урон), а что-то на эффекты?!?!? :-/ в списке эффектов - заморозка, отравление и прочее!!
Есть в этом логика)))) эх. Согласен что конкретно этот метод выгоднее делать от героя, а не от монстра. Но глаз замылен, кода много и иногда уже на автомате пишется лол))
Надеюсь когда нибудь кодить на пару, чтобы такого рода вещи замечались и оперативно правились)
ЦитатаKamiRonin ()
ууухх.. какой однако резон, имхо, немного сомнительный!! что каждый день по 20 новых монстров или сабелек появляется?? прям не знаю..
В игре сейчас ~30 монстров 20 из которых я добавил за один день:) Нужно так же учесть, что данжелот2 делается на вырост. Мы использовали примерно 25% от готового контента и всего половину от готовых монстров. Для меня очень важно иметь возможность оперативно добавлять новый контент на поток апдейтов в иос версии.
Игра коммерческая и рассчитывалось все заранее. Я не могу позволить себе потом в феврале где-то мучаться лишний раз в коде добавляя все новые и новые методы. ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
Посути полуручной редактор игры без интерфейса ( вбиваю xml сам ))
по сути ты сделал универсальный движок этого вида игры.. и просто в этот раз наполнил его контентом сам и вот так.. ну эт реально достижение!!!! респект!! просто насколько это ТОТ путь каким должны идти все кто пишет крафты?!
просто насколько это ТОТ путь каким должны идти все кто пишет крафты?!
Ну тут логика есть. Как считаю я : хочешь усложнить игру? добавь крафт. То есть мы принимаем факт, что если в игре есть крафт, то она уже не такая уж и простая, в ней куча вещей, все как в торчлайтах, диаблах и варкрафтах. А раз то встает вопрос о том, что нужно оперативно работать с большим объемом данных и желательно так, чтобы если что-то убрать не отвалилась вся система. Поэтому возникает необходимость в сильной абстракции и правилах)
Данжелот-1 в этом плане был полный фейл. Будучи "жестко" прописанным 1) мне было трудно чинить баги 2) даже для меня были неочевидны мои решения принятые N времени назад 3) я не починил всех багов, не смог добавить без боли контента, из-за отсутствия абстракций порой код часто дублировался или создавались методы там где они не должны были создаваться. Но вообще все это происходит из-за спешек и усталости)
Результатом в итоге недоволен. ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
чтобы не мучаться - правильно спланированная структура классов решает это дело.. сочувствую.. сам мучаюсь с отладкой модели классов.. я не смог пойти твоим путем - просто отложил игру. там лепить универсальность совсем не с руки было...
в общем, lentinant, вот тебе две модели - одна универсализм - глубоко абстрактные классы с облаком примочек вокруг них и более индивидуалистическая модель - с жесткой структурой заранее наполненных классов.
из-за отсутствия абстракций порой код часто дублировался или создавались методы там где они не должны были создаваться. Но вообще все это происходит из-за спешек и усталости)
ппц жаль! сочувствую. но тут есть система организации труда и средства моделирования структуры классов. абстракции могут быть жесткие но при этом дающие полную свободу в расширяемости кода.. в общем оффтопить не буду. лады.
надо на форуме продолжить тему организации структуры игры!! -- углубленное ооп (абстракции, наследования, полиморфизмы, делегаты, эвенты и тп.) -- планирование локализации кода (схему необходимых и обязательных элементов внутри структуры входящих компонент) -- оптимизация поддержки кода в проекте -- психологические аспекты интенсивной разработки игр и мультимедиа приложений. ("устал - смени род деятельности", "замылился взгляд - перформатируй документ" )
НО НЕКОМУ ЗАНИМАТЬСЯ!! у меня вообще нет времени.. хотя я бы мог куски добавить на любую из этих тем
Мыслю - значит программирую... Конструктивная критика - умных ведет к совершенству... Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
Я делаю игру где лут с моба чисто рандомный, только его уровень -3,+3 от лвла моба. Ну так пока он на полу это обжект с переменными. После поднимания предмета он удаляется а его переменные записывается в массивы. Если я выкидываю лут из сумки то создаю гейм обжект куда переписываю его данные. Для крафта сделаю тоже самое как и с лутом в сумке.
тут человек не знает как к классам подступить.. а ты сразу делегатами его! :))))
Кто вам такое сказал О_о Единственное, что у меня вызывало сомнения - "компонентный" характер скриптов. И я знаком с делегатами.
Цитатаallods ()
Я делаю игру где лут с моба чисто рандомный, только его уровень -3,+3 от лвла моба. Ну так пока он на полу это обжект с переменными. После поднимания предмета он удаляется а его переменные записывается в массивы.
Я так понял, массив структур? Не самый лучший метод. А как ты хранишь предметы у продавцов, например? Или какой предмет выпадет с сундука? Тоже в структурах? В общем, pixeye, KamiRonin, спасибо. Хотя наоффтопили вы тут знатно. Когда-то тут будут ссылки на крутые проекты. Или нет.