Pull to refresh
6
0

Пользователь

Send message

Зачем нужна cs когда есть scylladb. Автор попробуй с ней сравнить hbase

Тут принцип другой. Они карту не рисовали и иконки, они тупо рендерили все меши как есть. В этом случае, они жертвуют быстродействием против простоты, и здесь это оправдано. Они же не всунули какие-то дополнительные меши внутрь префабов.
Но если карта рисованная и схематичная, как например в WOW. То такое решение избыточно.
Тыц Вы автор сего. Так вот вы сделали схематично, что совсем не тоже самое как в этом примере.
Оптимизирую UI. Миникарту в реальном проекте. Обратите внимание на первые 2 скриншота. В первом случае я заполняю карту спрайтами во втором тоже самое но через шейдер, всего 256 точек. На ЦПУ примерно 600 фпс улетели в трубу.
Преобразованием вершин в экранные координаты будет заниматься конечно вершинный шейдер.

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

Вы можете это где-то продемонстрировать. Уж больно интересно как вы будете рендерить миникарту с другими слоями UI.
Как будет выглядеть ваш Update.
Все выше написано исходя из того что вы сделали большой цикл в пиксельном шейдере по всему массиву спрайтов.
И как будет выглядеть цикл в вашем вершинном шейдере. Как вы решите вопрос с глубиной, когда 2 точки налезут друг на друга.
Я с ваши категорически не согласен.Вы пробовали это вообще? Во время решения задачи, один коллега предложил попиксельно вписывать все это в текстуру. Ваш подход это напомнил. Ваш способ, скорей проиграет способу со спрайтами. Но давайте распишем алгоритм а вы поправите где я не прав.
1. Нужно генерить меш, скорей всего средствами юнити. Генерим ведь один меш? Верно. Берем 4 вершины, и преобразовываем их для UI, правильно? Иначе что случится при смене расширения? Дополнительно угол, верно?
2. Теперь нормали, ведь вы не хотите чтобы из-за нормалей меш было части полигонов не отображались, верно?
3. Теперь нужно наложить mat? И не простой, а семейства UI, иначе будут проблемы с масками.
4. Mat наложили, но он белый? Следовательно теперь нужно накинуть UV. Сложность этого алгоритма, боюсь даже представить.
5. Теперь все это запускаем, у нас на миникарте все двигаются. Что нужно сделать, с шага 1 все повторить и так каждый update. Ведь вряд ли возможен случай когда на миникарте не кто не двигается.
Можете сделать тест, против обычных спрайтов. Я например сильно сомневаюсь, что это хоть как-то эффективно
Так вы же хотите со всей сценой. Толку от одной миникраты. Как дадут добро выложу. Коллеге хватило этого теста, чтобы попробовать сделать небольшую аркаду на GPU, в один дравколл с 1000 объектов. Как сделает, поделюсь результатами.
Мы на реально и оптимизировали. С этого все и началось. Реальный выложить не могу, НДА, вот поэтому собрал на скорую руку тестовые сцены. Если бы у нас разница была в рн 5 10 фпс, думаете мы бы занимались подобным?
Через моно я в шейдер кормлю информацию о мире. Альфа на границах дает обводку, вот я ее и смягчаю через интерполяцию с базовой текстурой.
Границы, это пробел между текстурами. Он в выбранном атласа не очень удачный.
Чем в проекте меньше подписок тем лучше(с). На самом деле, подобное решение крайне сложно поддается дебагу, в большой команде это вообще похоже на ад и целое кладбище костылей. Приведу пример. Встречал программиста, который злоупотреблял методами SendMessage(). Логика такова — «кому нужно тот получит». И вот он ушел с той команды. И… Как дебаг ерланга (что за мессадж, от кого пришел, кому должен, зачем должен и тд.) В итоге систему частично выпилили. Я бы порекомендовал использовать евентовую систему в виде классов. MVC одним словом. Тогда даже если есть подписка, всегда можно поймать откуда ушел класс, куда и зачем (например юзать поле Sender или что-то типа него).
Да согласен, интерфейс нужно детальней описать и примеры тоже. Photon Server это сетевое решение от Exit Games аналог SmartFoxServer только тот на Java, а этот на C#. По поводу Instance, нужен именно доступ к юнити расширению PopOrCreate, поэтому и продублировано. Было бы множественное наследование)
На ключевых моментах сделаны пометки
иначе как бы это выглядело на примере одной функции. Специально писал код так, чтобы можно было просто его читать. Иначе вышло бы что-то вроде.
public virtual T Pop<T>(K groupKey) where T : V // достаем из пула
    {
        T result = default(T);// значение по умолчанию
        if (Contains(groupKey) && objects[groupKey].Count > 0) // Если есть в контейнере и контейнер не пустой
        { 
            for (int i = 0; i < objects[groupKey].Count; i++) // перебираем контейнер
            {
                if (objects[groupKey][i] is T) // если тип соответствует
                {
                    result = (T)objects[groupKey][i]; // присваиваем результату соответствие
                    Type type = result.GetType(); // получаем тип
                    RemoveObject(groupKey, i); // удалем из базы данных
                    RemoveFromCache(result, type); // удаляем из кеша
                    result.Create(); // вызываем псевдо-конструктор
                    break; // дальше что-то искать нет смысла, обрываем
                }
            }
        }
        return result; // получаем результат
    }

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

Подозреваю вы не пользовались этой системой. Просто фрагмент кода из Rain. Доставал рефлектором
Rain vision
protected virtual bool TestVisibility(RAINAspect aAspect, float aSqrRange, Matrix4x4 aSensorSpace)
{
    Vector3 position = aAspect.Position;
    Vector3 vector4 = position - this.Position;
    if (vector4.sqrMagnitude > aSqrRange)
    {
        return false;
    }
    Transform transform = aAspect.Entity.Form.transform;
    if (aAspect.MountPoint != null)
    {
        transform = aAspect.MountPoint.transform;
    }
    if ((!this.CanDetectSelf && (transform != null)) && ((transform == this.AI.Body.transform) || transform.IsChildOf(this.AI.Body.transform)))
    {
        return false;
    }
    bool flag = true;
    if ((this.HorizontalAngle == 360f) && (this.VerticalAngle == 360f))
    {
        flag = true;
    }
    else
    {
        position = aSensorSpace.MultiplyPoint(position);
        Vector3 vector5 = new Vector3(position.x, 0f, position.z);
        Vector3 normalized = vector5.normalized;
        float num = Mathf.Acos(Mathf.Clamp(normalized.z, -1f, 1f)) * 57.29578f;
        if (num > 180f)
        {
            num = 360f - num;
        }
        if (!Mathf.Approximately(normalized.sqrMagnitude, 0f) && (num > (this.HorizontalAngle / 2f)))
        {
            flag = false;
        }
        else
        {
            Vector3 vector6 = new Vector3(0f, position.y, position.z);
            normalized = vector6.normalized;
            float num2 = Mathf.Acos(Mathf.Clamp(normalized.z, -1f, 1f)) * 57.29578f;
            if (num2 > 180f)
            {
                num2 = 360f - num2;
            }
            if (num2 > 90f)
            {
                num2 = 180f - num2;
            }
            if (!Mathf.Approximately(normalized.sqrMagnitude, 0f) && (num2 > (this.VerticalAngle / 2f)))
            {
                flag = false;
            }
        }
    }
    if (!flag)
    {
        return false;
    }
    if (this._lineOfSight)
    {
        Vector3 direction = aAspect.Position - this.Position;
        RaycastHit[] hitArray = Physics.RaycastAll(this.Position, direction, direction.magnitude, (int) this._lineOfSightMask);
        for (int i = 0; i < hitArray.Length; i++)
        {
            if ((hitArray[i].collider.isTrigger || (hitArray[i].transform == this.AI.Body.transform)) || hitArray[i].transform.IsChildOf(this.AI.Body.transform))
            {
                continue;
            }
            if (aAspect.MountPoint != null)
            {
                if ((hitArray[i].transform != aAspect.MountPoint.transform) && !hitArray[i].transform.IsChildOf(aAspect.MountPoint.transform))
                {
                    goto Label_0331;
                }
                continue;
            }
            if ((aAspect.Entity.Form != null) && ((hitArray[i].transform == aAspect.Entity.Form.transform) || hitArray[i].transform.IsChildOf(aAspect.Entity.Form.transform)))
            {
                continue;
            }
        Label_0331:
            return false;
        }
    }
    return true;
}

Стоит обратить внимание на raycastAll и то что он всегда стреляет в одну точку.


по string ключу дорого. Лучше используйте хеш.
 int [animation]key= Animator.StringToHash("Speed");
...
 _animator.SetFloat( [animation]key, speed);
Характеристики объектов в игре

Предложение автору. Как я решил подобную проблему. Все Unit имееют стратегии. Не важно что это heath mana и тд. С бафами можно обыграть так.
Код
namespace Engine
{ 
   
    public abstract class UnitStrategyBase 
    {

        public virtual EventHandler Handler { get; set; }

        public virtual Unit CurrentUnit { get; set; }

        public virtual void OnAdd(Unit unit)
        {
            CurrentUnit = unit;
        }
        public virtual void OnRemove(Unit unit)
        {
            CurrentUnit = null;
        }

        public virtual void Send(IEvent @event)
        {
            if (Handler != null)
            {
                Handler.Send(@event);
            }
        }
    }
}



При добавлении стратегии, например баф. Сам баф сохраняет дельту, и обновляет нужные данные. После удаления, по этой самой дельте вернуть изначальное состояние. И так далее. Однажды пробовал обратную связь. Тоже работает, мол Armor например ищет бафы и сам возвращает результат. Но такой подход не очень, когда бафов становится огромное n количество.
С XML существует проблема на WinRT. Рекомендую использовать Xml.Linq XElement и тд. Но с ней существует проблема в Web player. Лечится это, через копирование System.Xml.Linq.dll (лучше вытянуть из папки unity) в Plugins и указанием билда только под веб.
Хорошая статья. Я тоже пришел к аналогичному приему. Но с некоторыми поправками. Использую MVC, где Unity3d view и иногда часть модельной логики (через интерфейсы). Unit — модельный класс, имеющий базовые поля и словарь стратегий, во вью аналогичное решение но с юнити компонентами. А на уровне общения только IAction (для контроллеров) и IEvent для (View или сети).
1

Information

Rating
Does not participate
Date of birth
Registered
Activity