Пятница, 29 Марта 2024, 13:13

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Множество объектов (Оптимизация)
Множество объектов
defGMDefeloperДата: Пятница, 19 Января 2018, 00:08 | Сообщение # 1
частый гость
Сейчас нет на сайте
Создаю игру на подобии spore.
Кто играл в spore знает что там очень много звезд(100к ,если spore.wiki не врет :3).Конечно единовременно рендерится не все(но наблюдения показывает что все равно рендерится достаточно много).
На каждом обьекте есть скрипт:


На таких масштабах каждая запятая важна.Сейчас спокойно на одной сцене существует 10к звезд.Я меняю альфа канал текстуры по мере отдаления камеры от точки куда она направлена:

Код
Material mK = stars[i].img_.material;
                    Color tc = mK.GetColor("_TintColor");
                    float k = 0.5f*(0.9f - (d / maxDist_[i]*d / maxDist_[i]));
                    mK.SetColor("_TintColor",new Vector4(tc.r,tc.g,tc.b,k));  


Вот пару картинок:




Ну.и собсвенно в чем проблема .Не смотря на все усилия fps низкий при том что рендерится лишь 10 часть от желаемого .И на 3 изображение при движении камеры звезды те что относительно далеко буд-то двигаются,что выглядит не очень реалистично и красиво,хотя и с точки зрения математики все правильно).
1.Как можно повысить производительность?
2.Как убрать " движение"?


Сообщение отредактировал defGMDefeloper - Пятница, 19 Января 2018, 00:19
GMasstaДата: Пятница, 19 Января 2018, 07:09 | Сообщение # 2
частый гость
Сейчас нет на сайте
Для начала убери в постоянно обновляемых методах создание новых элементов типа:
new Vector3(v.x, v.y, 0)


Make games, not war
Посмотри мои игры для мобилок, влепи лукаса!
Тут я делаю игры на Unity
OtinagiДата: Пятница, 19 Января 2018, 08:28 | Сообщение # 3
постоянный участник
Сейчас нет на сайте
Обычно подобные затухания через шейдер делаются.

«Смерти меньше всего боятся те люди, чья жизнь имеет наибольшую ценность.»
Иммануил Кант
defGMDefeloperДата: Пятница, 19 Января 2018, 13:43 | Сообщение # 4
частый гость
Сейчас нет на сайте
Цитата GMassta ()
Для начала убери в постоянно обновляемых методах создание новых элементов типа:
new Vector3(v.x, v.y, 0)

Это необходимый минимум. если на Jave,я его не использую,не могу быть уверен,пишется так

transform.position.x+= значение,то это лишь упрощение.На самом деле он также создает новый тип,Vector3 ,просто он это делает за вас.

Vector3 v = Camera.main.WorldToScreenPoint(star_.position);
t_.position = new Vector3(v.x, v.y, 0);
А то что я создал вектор v,если не ошибаюсь для компилятора это не особо важно,ведь я не создал новый тип.
А что на счет Camera.main.WorldToScreenPoint(star_.position); - без этого ниче работать не будет.Метод создает проекцию координат из трехмерного пространства на двухмерное(экранное),т.к все "звезды" - это картинки,спрайты.

P.S пришлось создать,ибо по какой-то причине если z у UI Image больше или равно 1000 он просто пропадает.Объяснит кто почему так происходит?я ничиго не нашел

А на счет шейдеров плиз попродробней,я не особов них смыслю.Даже не знаю с чего начать поиск.

Читал я как можно оптимизировать код,но эт не подходит все.Как по мне в коде все по минимуму,поправте если ошибаюсь.Тут нужно чет глобальное ,мб кто раньше делал что подобное и нашел более оптимальное решение,а может вообще использовал не UI. И ещё раз на счет того,что красным,если кто знает плз поясните.


Сообщение отредактировал defGMDefeloper - Пятница, 19 Января 2018, 14:10
zhuravelsvДата: Пятница, 19 Января 2018, 14:23 | Сообщение # 5
почетный гость
Сейчас нет на сайте
Если я правильно понимаю то что написано в справке, то изменение материала создаёт его копию на каждом обьекте, соответственно это тоже влияет на производительность, лучше написать простой шейдер который это будет делать автоматически


Цитата defGMDefeloper ()
На каждом обьекте есть скрипт:

Это 10к обьектов на которых такой скрипт?


Разработка программного обеспечения для ОС Windows и Android, клиент-серверные, облачные приложения, работа с БД и многое другое - https://www.weblancer.net/users/zhuravelsv/
InsaneSystemsДата: Пятница, 19 Января 2018, 14:26 | Сообщение # 6
участник
Сейчас нет на сайте
defGMDefeloper, насчёт шейдеров совет, конечно хороший, но человек без знаний в них никогда не сможет подобное самостоятельно сделать, а примеры из интернета вряд ли подойдут под конкретную задачу.

Насчёт программного решения, объясняю ваши основные проблемы в данный момент.
Проблема:
Вы используете на каждом объекте MonoBehaviour. При этом поведение абсолютно одинаковое и в данном случае это нерационально.
Решение:
Используйте один общий скрипт, хранящий массив или список звёзд. Это как минимум упростит логику взаимодействий и даже, возможно, ускорит быстродействие игры. Плюс открывается новая возможность - можно использовать многопоточное прохождение цикла в данной задаче, поскольку последовательность тут не важна. По этому поводу погугли c# parallel for, лично я в юнити это не использовал пока что. Но это позволит более выгодно использовать ресурсы процессора и увеличит производительность игры.
Проблема:
У вас для каждой звезды вызываются методы Camera.main.WorldToScreenPoint и Vector3.Distance, а ещё и SetColor для материала, как я понял. Почитайте про быстродействие каждого из этих методов и умножьте задержку выполнения на количество звёзд (10к в данном случае) и получите время, которое это занимает при обработке процессором. А теперь вспоминаем, что Update выполняется каждый кадр, и такая задержка соответственно будет каждый кадр.
Решение:
Необходимо либо сократить количество вызовов данных методов (например, как-нибудь обобщить для нескольких звёзд), либо вызывать их реже, чем каждый кадр. Допустим, 10 раз в секунду. Или разбить выполнение одной задачи (for по всем звёздам) на несколько кадров, что сократит задержки выполнения и увеличит производительность. При должной реализации можно добиться приемлемого результата.

Но, честно говоря, к решению такой задачи стоит, наверное, подойти иначе. Как именно - зависит только от ваших умений и креативности. 10к UI-элементов на экране это уже само по себе нехорошо очень.

P.S.: для того, чтобы избавиться от Camera.WorldToScreenPoint, можно использовать Canvas с Render Mode типа World Space.


Сообщение отредактировал InsaneSystems - Пятница, 19 Января 2018, 14:34
defGMDefeloperДата: Пятница, 19 Января 2018, 15:09 | Сообщение # 7
частый гость
Сейчас нет на сайте
Код
IEnumerator _StarDraw(float maxDist_MKG, float maxDist_AFB2, float maxDist_OB1)
    {
        while (true)
        {
            float[] maxDist_ = {maxDist_OB1,maxDist_OB1,maxDist_AFB2,maxDist_AFB2,maxDist_AFB2,maxDist_MKG,maxDist_MKG,maxDist_MKG};
            float d = Vector3.Distance(lookAt, camP.position);
            for (int i = 0; i < stars.Length; i++)
            {
     
                if (d > maxDist_[i])
                {
                    if (StarLayers[i])
                        StarLayers[i] = false;
                   
                }
                else
                {   
                    if (!StarLayers[i])
                        StarLayers[i] = true;
                    if(i==0) continue;
                    Material mK = stars[i].img_.material;
                    Color tc = mK.GetColor("_TintColor");
                    float k = 0.5f*(0.9f - (d / maxDist_[i]*d / maxDist_[i]));
                    mK.SetColor("_TintColor",new Vector4(tc.r,tc.g,tc.b,k));         
                }
            }
            yield return new WaitForFixedUpdate();
        }
    }


Не,конечно нет) Это вызывается в корутине ,и только для целых массивов звезд,разбитых по размеру.А проверка на дистанцию проходит только если Layer==true.Но за идею спасибо.Чутка переделать.Сделать все в 1 скрипте.
stars.Length - массив из 8 звезд(типов) это клас хранящий префаб,для создания и Image(UI).
Если менять материал префаба,меняет материал на всех обьектах.

Добавлено (19 Января 2018, 15:09)
---------------------------------------------
А World Space не подходит.Звезды то 2д картинки,но камера двигается в трехмерном пространстве.
Canvas.LookAt(camera) плохо.ибо повернуть холст с 10к дочерних обьектов..
звезда[1-10к].LookAt(camera) ничем не лучше варианта с преобразованием координат,только там я знаю точные координаты ,а в World Space координаты масштабируются в месте с холстом и короч не очень удобно

Сообщение отредактировал defGMDefeloper - Пятница, 19 Января 2018, 15:06
InsaneSystemsДата: Пятница, 19 Января 2018, 15:22 | Сообщение # 8
участник
Сейчас нет на сайте
Цитата
Не,конечно нет) Это вызывается в корутине ,и только для целых массивов звезд,разбитых по размеру.А проверка на дистанцию проходит только если Layer==true.Но за идею спасибо.Чутка переделать.Сделать все в 1 скрипте.

Насчёт материалов хорошо, что так. Остальное тоже рекомендую вынести в отдельный скрипт.

Цитата
А World Space не подходит.Звезды то 2д картинки,но камера двигается в трехмерном пространстве.

Ну и что с того? :) В данном случае просто задаёте ту же позицию, что и у трёхмерных звёзд, уже минус Camera.WorldToScreenPoint.
Цитата
Canvas.LookAt(camera) плохо.ибо повернуть холст с 10к дочерних обьектов..

Ничем не хуже, чем поворачивать каждый из этих объектов отдельно.
Цитата
а в World Space координаты масштабируются в месте с холстом и короч не очень удобно

Честно говоря, трудно решать подобные задачи, не пробуя разные варианты и не сравнивая производительность. ;)


Сообщение отредактировал InsaneSystems - Пятница, 19 Января 2018, 15:23
defGMDefeloperДата: Пятница, 19 Января 2018, 19:03 | Сообщение # 9
частый гость
Сейчас нет на сайте
Перетащил все в 1 скрипт.Фпс больше не стал(.Видимо надо делать внутри корутина алгоритмы чтобы отсеивать все ненужные звезды и посмотреть ещё что такое паралельные циклы

например ,чем ближе камера к точке обзора(цели)
тем меньше радиус на котором звезды "активны"
по сути чем она ниже опускается тем меньше смысла отрисовывать звезды которые заслоняют друг друга.И выглядит не очень и нагрузка лишняя.Короче мороки много =(

Добавлено (19 Января 2018, 19:03)
---------------------------------------------
И кстати.Как сделать проверку что элемент UI в области экрана?
Пробовал Rect.Contains - не вышло(.хотя мб вообще не стоит делать такую проверку(идеи чет закончились(

Сообщение отредактировал defGMDefeloper - Пятница, 19 Января 2018, 17:53
seamanДата: Пятница, 19 Января 2018, 19:28 | Сообщение # 10
старожил
Сейчас нет на сайте
Для начала прочитать 10 000 вызовов Update
(LateUpdate - это то же самое!)
defGMDefeloperДата: Пятница, 19 Января 2018, 19:56 | Сообщение # 11
частый гость
Сейчас нет на сайте
LateUpdate я вообще не использую.
Цитата defGMDefeloper ()
Перетащил все в 1 скрипт.

Все "звезды" находятся в 1 скрипте
GMasstaДата: Пятница, 19 Января 2018, 21:10 | Сообщение # 12
частый гость
Сейчас нет на сайте
Цитата
А то что я создал вектор v,если не ошибаюсь для компилятора это не особо важно,ведь я не создал новый тип.


Ошибаешься, это очень серьезная ошибка, читай как работают сборщики мусора.
при больших расчетах в апдейт методах даже гет не рекомендуется, но без этого уже тяжко.

Решить задачу можно создав 2 массива, в одном опорные звезды, отображаются на большом расстоянии, во второй создаются новые звезды, которые находятся рядом с опорной звездой, когда приближаешь камеру к одной из них.


Make games, not war
Посмотри мои игры для мобилок, влепи лукаса!
Тут я делаю игры на Unity
drcrackДата: Суббота, 20 Января 2018, 08:13 | Сообщение # 13
старожил
Сейчас нет на сайте
Цитата
Ошибаешься, это очень серьезная ошибка, читай как работают сборщики мусора.

И как же они работают со struct которая лежит в стеке? :D
InsaneSystemsДата: Суббота, 20 Января 2018, 12:27 | Сообщение # 14
участник
Сейчас нет на сайте
defGMDefeloper, совет. Используй профайлер (Ctrl + 7), отслеживай, что именно больше всего производительности требует, и уже от этого думай, как устранить.
GMasstaДата: Суббота, 20 Января 2018, 13:07 | Сообщение # 15
частый гость
Сейчас нет на сайте
Цитата
И как же они работают со struct которая лежит в стеке? :D


Даже и не посмотрел что он struct (.


Make games, not war
Посмотри мои игры для мобилок, влепи лукаса!
Тут я делаю игры на Unity
defGMDefeloperДата: Четверг, 25 Января 2018, 15:34 | Сообщение # 16
частый гость
Сейчас нет на сайте
Смотрите решил идти поэтапно.На выбор,ну то чтоя сумел придумать,было 3 варианта как рисовать звезды

1.Canvas + Camera.WorldToScreen
2.Canvas World Space+ look at
и самый безумный 3.Plane с текстурой звезды и look at.
Угадайте какой показал самую большую производительность? :)


Сообщение отредактировал defGMDefeloper - Четверг, 25 Января 2018, 20:00
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Множество объектов (Оптимизация)
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг