Реализация выпадания вещей
| |
Vigilem | Дата: Пятница, 03 Января 2014, 15:57 | Сообщение # 1 |
частый гость
Сейчас нет на сайте
| Добрый день, уважаемые форумчане! Совсем недавно я перебрался на Unity, а конкретней на Unity 4.3.1. Я думаю, Вы можете представить мой восторг от работы с Юнькой, если до этого я работал с технологиями, инструментарий для которых приходилось писать самому. А теперь: огромной набор инструментов для выполнения любой задачи. Минимум кода, максимум возможности повторного использования кода, множество вещей делается банальным Drag'n'Drop.
Задача: В процессе ознакомления с Юнькой столкнулся с задачей реализовать выпадения вещей. Но т.к. к хорошему привыкаешь быстро, захотелось, что бы я мог настраивать выпадание вещей в минимум движений (Drag'n'Drop).
Неверный ход решения: Проблем то, создал структуру. Код public struct DropItem { Transform item; // Здесь мы храним данные о нашей вещи; int chance; // Здесь храним шанс выпадения (1-99); }
Создал публичное поле класса: public DropItem[] dropList; Проблем не должно быть. Но нет... Оказывается инспектор Unity не может выводить поля для ввода элементов массива структур, чему я не очень обрадовался, честно говоря. Как Вы видите, инспектор абсолютно не реагирует на появление публичного поля у класса. Но я же хотел Drag'n'Drop ;( Пришлось искать другое решение. И так, приступим.
Правильный ход решения: 1) Создаём отдельный класс DropItem Код using UnityEngine; using System.Collections;
public class DropItem : MonoBehaviour { public Transform item; public int chance;
public DropItem(Transform _item, int _chance) { item = _item; chance = _chance; }
public void CreateDropItem(Vector3 position) { var drop_item = Instantiate(item) as Transform; drop_item.position = position; } }
Класс создан. Сохраняем. 2) Теперь создаём на сцене Пустой Объект, добавляем к нему наш DropItem.cs. Получаем: Сохраняем наш объект, убираем со сцены. Готово, часть задуманного реализована. Теперь мы можем перетягивать необходимую вещь в поле Item, и указывать шанс выпадения в поле Chance (Кстати, в скрипте мы не проверяем валидность этого поля, а стоило бы). 3) Теперь нам нужно как-то связать наш DropItem с сущностью, у которой планируется выпадание вещей. У меня это вражеские юниты, за их поведение отвечает public class EnemyScript. В его публичные поля я добавляю public DropItem[] dropList; Результат несложных манипуляций: Теперь с помощью простого перетаскивания мы можем добавлять вещи в DropList (На основе которого будет происходить "выпадание вещи").
4) Что осталось? Правильно: метод, который будет считать и вызывать ранее созданный метод DropItem::public void CreateDropItem(Vector3 position); Метод, который считает вероятность выпадение, при удовлетворение условия - создаёт вещь на месте уничтоженного объекта. Метод должен принадлежать тому же классу, что и DropList. Код public void CheckDrop() { if (dropList.Length > 0) { int rnd = (int)Random.Range(0, 100);
foreach (var item in dropList) { if (item.chance < rnd) { item.CreateDropItem(gameObject.transform.position); return; } } } }
Вывод: 1) Поставленная задача была реализована. Желаемый механизм Drag'n'Drop для добавления вещей в список "дропа" создан и работает. 2) Программисты, как никто другой, очень быстро привыкают к хорошему. Хотелось бы узнать, как реализовали это Вы?
|
|
| |
nwsx | Дата: Пятница, 03 Января 2014, 19:15 | Сообщение # 2 |
постоянный участник
Сейчас нет на сайте
| шанс надо было во флоуте делать (от 0 до 1)
Westboro Dungeon Journey на Google Play
Сообщение отредактировал nwsx - Пятница, 03 Января 2014, 19:15 |
|
| |
Vigilem | Дата: Пятница, 03 Января 2014, 22:25 | Сообщение # 3 |
частый гость
Сейчас нет на сайте
| Цитата nwsx ( ) шанс надо было во флоуте делать (от 0 до 1) nwsx, для моего проекта это не целесообразно. Я считаю, что есть смысл хранить шанс во float, если список вещей, которые могут выпасть, переваливает за 20. И то, в этом случае подхватывать список вещей лучше с файла или БД.
|
|
| |
KamiRonin | Дата: Среда, 08 Января 2014, 12:25 | Сообщение # 4 |
почти ветеран
Сейчас нет на сайте
| обычно делается лут - рандомный. для этого создается закулисная база с описаниями лута, в том числе и ссылкой на 3D объект в ассетах (префабах). ну если хочется этим управлять на drag&drop'e то можно сделать отдельный класс - база лута и засунуть туда префабы один раз на всех орков (эт и есть преимущество подхода). управление выпадением ложится на скрипт орка или менеджера игры.
Мыслю - значит программирую... Конструктивная критика - умных ведет к совершенству... Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
|
|
| |
Vigilem | Дата: Среда, 08 Января 2014, 17:56 | Сообщение # 5 |
частый гость
Сейчас нет на сайте
| KamiRonin, здесь представлен вариант как раз таки со случайным выпаданием вещей, лишь указывается список выпадаемых вещей и шанс
|
|
| |
KamiRonin | Дата: Среда, 08 Января 2014, 18:56 | Сообщение # 6 |
почти ветеран
Сейчас нет на сайте
| Цитата Vigilem ( ) здесь представлен вариант как раз таки со случайным выпаданием вещей, лишь указывается список выпадаемых вещей и шанс ага, сорри. перечитал и точно - все что нужно один в один!!
просто среагировал на то, что у каждого Enemy будет отдельный дроп лист, который нужно заполнять на каждого Enamy персонально!!!!
то что я имел в виду - это центральная база, сформированная заранее для всех Enemy этого вида. в каждом энеми указывать свои дропы не нужно (а если у меня враги генерируются программно, с рандомным заполнением твоего списка как быть??? у тебя бы пришлось писать новый метод в классе Enemy... или дропИтем).
я бы сделал СТАТИТИЧЕСКИЙ метод у централизованной базы дропов - в котором был параметр вид врага, количество дропов и позиция - где сбрасывать лут. в скрипте Enemy не было бы никакого списка с дропами! и их не нужно было заполнять вручную! на каждого врага! там был бы метод DoDie() в котором -- DropItem.StaticMethod_DropingItems("ork", 3, transform.postion); и все. плюсы - универсальность, заполнение списка ЕДИНОЖДЫ на всех врагов, однострочный вызов без лишних переменных, легко читаемый код, возможность генерировать множество Enemy программно без лишних движений по заведомому заполнению списка лута в каждом!! мне кажется все минусы такого решения перевешиваются начисто!!
еще раз сорри, что неверно выразился - я сразу написал -- БАЗА лута, мой рандом относился ко всей базе возможных лутов, а не только к тем трем что ты в Enemy засунул! удачи! хорошо оформил тему и запрос к сообществу!
Мыслю - значит программирую... Конструктивная критика - умных ведет к совершенству... Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
Сообщение отредактировал KamiRonin - Среда, 08 Января 2014, 18:56 |
|
| |
allods | Дата: Четверг, 09 Января 2014, 17:00 | Сообщение # 7 |
почти ветеран
Сейчас нет на сайте
| Цитата KamiRonin ( ) я бы сделал СТАТИТИЧЕСКИЙ метод у централизованной базы дропов - в котором был параметр вид врага, количество дропов и позиция - где сбрасывать лут. в скрипте Enemy не было бы никакого списка с дропами! и их не нужно было заполнять вручную! на каждого врага!
То что сделал я
А качество лута можно определить по левлу моба или/и редкости/силе моба
|
|
| |
SlavaLia | Дата: Вторник, 07 Марта 2017, 09:52 | Сообщение # 8 |
был не раз
Сейчас нет на сайте
| Хоть теме два года - копну её)
Цитата Vigilem ( ) Как Вы видите, инспектор абсолютно не реагирует на появление публичного поля у класса. Но я же хотел Drag'n'Drop ;(
для этого достаточно указать, что структура сериализуется [System.Serializable] .
Код [System.Serializable] public struct DropItem { Transform item; // Здесь мы храним данные о нашей вещи; int chance; // Здесь храним шанс выпадения (1-99); }
После этого она отобразится в инспекторе и будет сохраняться в компоненте.
Сообщение отредактировал SlavaLia - Вторник, 07 Марта 2017, 09:53 |
|
| |
|