Форум программистов, компьютерный форум, киберфорум
Unity, Unity3D
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
Другие темы раздела
Unity, Unity3D Можно ли изменить разрешение для Android? Всем привет! Можно ли как-то изменить отображаемое разрешение на Android? Объясняю ситуацию : делаю игру, на моём телефоне разрешение 720 на 1800 и все работает нормально (процессор у меня... Кажется нет, но можешь попробовать Screen.SetResolution(widthValue, heightValue, true); Еще можно на камере поставить галку Allow Dynamic Resolution, но это не всегда работает. https://www.cyberforum.ru/ unity/ thread3091618.html Unity, Unity3D Inputfield не активен Добрый день. Подскажите, пожалуйста, такой момент. Имеется 3д поле, в котором реализовано перемещение объекта от первого лица. Нужно добавить поле для ввода, допустим, на другой объект. Но суть в... Tehnoos, такое может происходить из-за того, что поле ввода перекрывает другой объект, который забирает на себя нажатие. https://www.cyberforum.ru/ unity/ thread3091579.html
Как сделать счётчик очков дрифта? Unity, Unity3D
Помогите пожалуйста сделать счётчик очков дрифта для телефонной игры Vasya141, код реализации дрифта покажете?
Unity, Unity3D Краш при запуске проекта в редакторе https://www.cyberforum.ru/ unity/ thread3091724.html
Всем здравствуйте. Я не могу понять, почему у меня происходит краш, если я запускаю проект в редакторе. Прикладываю Editor.log(слишком большой, загрузил на яндекс диск... Данила213213123, в crash.dmp должная быть более подробная информация. Думаю, стоит его показать.
Unity, Unity3D Проблема с передачей velocity одного объекта другому https://www.cyberforum.ru/ unity/ thread3091546.html
Я делаю игру-раннер, в которой персонаж при столкновении с неактивными персонажами делает их активными, проблема в том, что если активный персонаж сталкивается с группой неактивных персонажей,... В момент передачи скорости неактивному, проверь не соприкасается ли он с другими неактивными, если да, то передавай им тоже. А краш очень странно что происходит, какая ошибка конкретно?
Unity, Unity3D Как сделать чтобы при заходе игрока в зону объекта и нажатии на клавишу объект исчез? https://www.cyberforum.ru/ unity/ thread3091705.html
Здравствуйте, нужно чтобы при заходе игрока в зону объекта и при нажатии игроком клавиши "Е" объект исчез или был уничтожен wasd3131, попробуйте что-то вроде этого. Надо тестировать. private bool inArea; private void Update() { if(Input.GetKey(KeyCode.E) && check) Destroy(gameObject); }
Unity, Unity3D Как сделать переключение между автомобилей? https://www.cyberforum.ru/ unity/ thread3091608.html
Я хочу добавить в Unity игру добавить несколько автомобилей как мне добавить несколько машин и сделать переключение между автомобилями? Чот ору :D
Unity, Unity3D Случайное появление UI объектов https://www.cyberforum.ru/ unity/ thread3091518.html
У меня есть игра , в которой я хочу реализовать случайное появление предметов(UI-images) , но не знаю как это реализовать :( dimarey212, расскажи подробнее, что нужно реализовать. Не совсем понять что именно должно быть "рандомным".
Unity, Unity3D Не работает воспроизведение анимации при вхождении в триггер
Надо чтобы при вхождении в триггер радом со шлгабаумом шлагбаум открывался а при выходн закрывался, но просто скрипт не работает и все, вот скрипт using UnityEngine; public class BarrierAnimation... RFUTBOTBAJCACG, чтобы понять, что у вас не работает надо проверить его с помощью дэбага. пример: public void OnTriggerEnter(Collider other) { print("OnTriggerEnter"); ...
Сдвиг объекта на некоторое время Unity, Unity3D
Помогите сделать такой скрипт. Если Игрок заходит в Триггер Объекта, то: этот Объект сразу сдвигается по оси вниз (напр. на 100 метров) и через некоторое (напр. 15 сек., желательна возможность это... irix, private float timeToReturn; private void OnTriggerEnter2D(Collider2D other) { if(other.gameObject.GetComponent<Скрипт игрока>()) { ...
Unity, Unity3D Анимации при переходе зацикливаются друг с другом https://www.cyberforum.ru/ unity/ thread3091326.html
Я делаю раннер, по нажатию мышки персонаж бежит, когда отпускаю останавливается, также по нажатию мышки включается анимация бега и выключается, но нажатии мышки персонаж бежит, останавливается и... Свойства перехода анимаций:
Unity, Unity3D Слежение камеры за персом
Пишу 2D платформер на юнити, хотел сделать слежение камеры за персом, в итоге юнити ругается на Hero в конце в FindObjectType. Когда меняю Hero на hero, перестаёт ругаться но камера не следит за... ANALys1s, ругается на Hero в конце в FindObjectType. Ваш скрипт называется "hero", следовательно и ругается, что нет "Hero". подскажите в чём проблема Попробуйте заменить код на это. Если всё...
2 / 1 / 0
Регистрация: 31.05.2021
Сообщений: 48
0

Оптимизация движения большого количества объектов - Unity, Unity3D - Ответ 16822022

24.03.2023, 00:09. Показов 3366. Ответов 52
Метки (Все метки)

Author24 — интернет-сервис помощи студентам
Я занимаюсь разработкой игры, в которую хочу добавить что-то по типу конвейеров, которые в моей игре являются трубами. На данный момент я занимаюсь кодом который реализует передвижение ресурсов по трубам. И здесь я столкнулся с проблемой, которую уже долгое время не могу решить и это проблема оптимизации и производительности этих самых объектов. Меня не сильно волнует рендеринг объектов так как в будущем я планирую всё это перенести в DrawMeshes. Но даже так я понятия не имею как оптимизировать поиск пути и движения этих объектов на данный момент максимум сколько я могу двигать одновременно объектов это 5000 ресурсов для 60+ фпс, который скачет от 60 до 100. Я хочу услышать что-то кроме "кешируй объекты, не используй Linq, не используй .Find" и тд. вещи потому что это даёт прирост спору нет. Но у меня уже руки опускаются потому что не знаю что делать, я считаю что выжал все фпс из своего кода настолько, насколько мог сам.
Буду очень благодарен за вашу помощь, спрашивайте, если нужна какая-то дополнительная информация, свой код я прикрепил ниже.

Вот мой код на данный момент:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
using UnityEngine.Profiling;
using Cysharp.Threading.Tasks;
 
public class ResourceManager : MonoBehaviour
{
    [SerializeField] private Pipes pipes;
    [SerializeField] private Buildings buildings;
    private TileBase[] directionTile;
    private TileBase[][] turnPipes = new TileBase[4][];
    private TileBase[] teePipes = new TileBase[4];
    private TileBase crossPipe;
    private Transform[] neighborPipes = new Transform[4];
    public Dictionary<int, Transform> _resourcesDict = new Dictionary<int, Transform>();
    public Dictionary<int, Resource> _resourcesComponentDict = new Dictionary<int, Resource>();
 
    public int resourceDictCount = 0;
    private Vector3Int[] offsets = new Vector3Int[] {
        new Vector3Int(0, 1, 0),
        new Vector3Int(1, 0, 0),
        new Vector3Int(0, -1, 0),
        new Vector3Int(-1, 0, 0)
    };
    private CancellationTokenSource cancellationTokenSource;
    private async void Awake()
    {
        directionTile = pipes.DirectionTile;
        turnPipes[0] = pipes.TurnPipesUp;
        turnPipes[1] = pipes.TurnPipesRight;
        turnPipes[2] = pipes.TurnPipesDown;
        turnPipes[3] = pipes.TurnPipesLeft;
        teePipes = pipes.TeePipes;
        crossPipe = pipes.CrossPipe;
        cancellationTokenSource = new CancellationTokenSource();
        await ResourceTask(cancellationTokenSource.Token);
    }
 
    private async UniTask ResourceTask(CancellationToken cancellationToken)
    {
        while (true)
        {
            int objectsPerFrame = Mathf.CeilToInt((resourceDictCount + 50) / 5);
            int objectsProcessed = 0;
            for (int key = 0; key < resourceDictCount; key++)
            {
                if (objectsProcessed % objectsPerFrame == 0) await UniTask.Yield();
                if (_resourcesDict.TryGetValue(key, out Transform transform) && _resourcesComponentDict.TryGetValue(key, out Resource resource))
                {
                    if (pipes._pipeGroupDict.TryGetValue(Vector3Int.FloorToInt(resource.pos), out Pipes.PipeObj pipeByPos))
                    {
                        Vector3Int cellPosition = Vector3Int.FloorToInt(resource.pos);
                        for (int i = 0; i < 4; i++)
                        {
                            if (pipes._pipeGroupDict.TryGetValue(cellPosition + offsets[i], out Pipes.PipeObj neiPipe)) neighborPipes[i] = neiPipe.transform;
                            else neighborPipes[i] = null;
                        }
                        if (resource.lastPipe != pipeByPos.transform)
                        {
                            resource.currentPipe = pipeByPos.Pipe;
                            resource.neighboringPipes = neighborPipes;
                        }
                        resource.lastPipe = pipeByPos.transform;
                        if (resource.currentPipe != null)
                        {
                            if (resource.startPipe == null)
                            {
                                resource.startPipe = resource.currentPipe;
                                resource.isStart = resource.currentPipe == resource.startPipe && Vector3.Distance(resource.pos, resource.currentPipe.transform.position) > 0.1f;
                            }
                            int neighbors = 0;
                            for (int i = 0; i < 4; i++)
                            {
                                if (resource.neighboringPipes[i] || ((i + 2) % 4 == resource.lastDirection)) neighbors++;
                                else if (buildings._lineGroupDict.ContainsKey(cellPosition + offsets[i])) neighbors++;
                            }
                            if (Vector3.Distance(resource.pos, resource.targetPosition) < 0.01f || resource.targetPosition == Vector3.zero)
                            {
                                if (Enumerable.ReferenceEquals(resource.neighboringPipes, neighborPipes) == false)
                                {
                                    resource.currentPipe = pipeByPos.Pipe;
                                    resource.neighboringPipes = neighborPipes;
                                }
                                if (resource.isStart)
                                {
                                    resource.isStart = resource.currentPipe == resource.startPipe && Vector3.Distance(resource.pos, resource.currentPipe.transform.position) > 0.01f;
                                    resource.targetPosition = resource.currentPipe.transform.position;
                                }
                                else if (neighbors == 2) TGP_DirectionAndTurn(resource);
                                else if (neighbors == 3) TGP_Tee(resource);
                                else if (neighbors == 4 && resource.currentPipe.currentTile == crossPipe) TGP_Cross(resource);
                            }
                            if (Vector3.Distance(resource.pos, resource.targetPosition) > 0.01f || neighbors != 1 && resource.neighboringPipes[resource.lastDirection]) MoveToCenter(resource.targetPosition, transform);
                        }
                    }
                    else resource.currentPipe = null;
                    objectsProcessed++;
                }
            }
            await UniTask.Yield();
        }
    }
    private void TGP_DirectionAndTurn(Resource r)
    {
        for (int i = 0; i < directionTile.Length; i++)
        {
            if (r.currentPipe.currentTile == directionTile[i] && r.neighboringPipes[i])
            {
                r.targetPosition = r.neighboringPipes[i].transform.position;
                r.lastDirection = i;
                break;
            }
            else if (i == 3 && r.currentPipe.currentTile != directionTile[i])
            {
                for (int j = 0; j < turnPipes[r.lastDirection].Length; j++)
                {
                    int directionIndex = r.lastDirection % 2 == 0 ? 3 : 2;
                    int index = directionIndex / (directionIndex * (j % 2) + (j % 2 == 0 ? 1 : 0));
                    if (r.currentPipe.currentTile == turnPipes[r.lastDirection][j] && r.neighboringPipes[directionIndex == 2 && index == 1 ? 0 : index])
                    {
                        r.targetPosition = r.neighboringPipes[directionIndex == 2 && index == 1 ? 0 : index].transform.position;
                        r.lastDirection = directionIndex == 2 && index == 1 ? 0 : index;
                    }
                }
            }
        }
    }
 
    private void TGP_Tee(Resource r)
    {
        int[] indices = new int[3];
        var pipesOutput = r.currentPipe.PipesOutput;
        for (int i = 0; i < 4; i++)
        {
            if (r.currentPipe.currentTile == teePipes[i])
            {
                int index = 0;
                int direction = (r.lastDirection + 2) % 4;
                for (int j = 0; j < 4; j++) if (j != direction && r.currentPipe.IsNeighbor[j] && index < 2) indices[index++] = j;
                if (pipesOutput[indices[0]][indices[0]] || r.neighboringPipes[indices[0]] == false)
                {
                    if (pipesOutput[indices[1]][indices[1]] || r.neighboringPipes[indices[1]] == false)
                    {
                        pipesOutput[indices[0]][indices[0]] = false;
                        pipesOutput[indices[1]][indices[1]] = false;
                    }
                }
                int indexCached = 0;
                for (int j = 0; j < 2; j++)
                {
                    indexCached = indices[j];
                    if (pipesOutput[indexCached][indexCached] == false && r.neighboringPipes[indexCached])
                    {
                        r.targetPosition = r.neighboringPipes[indexCached].transform.position;
                        r.lastDirection = indexCached;
                        pipesOutput[indexCached][indexCached] = true;
                        break;
                    }
                }
            }
        }
    }
 
    private void TGP_Cross(Resource r)
    {
        int number = 0;
        int[] indices = new int[3];
        int direction = (r.lastDirection + 2) % 4;
        for (int j = 0; j < 4; j++) if (j != direction) indices[number++] = j;
        var pipesOutput = r.currentPipe.PipesOutput;
        int count = 0;
        int index = 0;
        for (int i = 0; i < 3; i++)
        {
            index = indices[i];
            if (pipesOutput[r.lastDirection][index] || r.neighboringPipes[index] == false)
            {
                count++;
                if (count == 3) for (int j = 0; j < 4; j++) pipesOutput[r.lastDirection][j] = false;
            }
        }
        for (int i = 0; i < 3; i++)
        {
            index = indices[i];
            if (pipesOutput[r.lastDirection][index] == false && r.neighboringPipes[index])
            {
                r.targetPosition = r.neighboringPipes[index].transform.localPosition;
                pipesOutput[r.lastDirection][index] = true;
                r.lastDirection = index;
                break;
            }
        }
    }
 
    private void MoveToCenter(Vector3 targetPosition, Transform transform)
    {
        if (targetPosition != Vector3.zero)
        {
            transform.localPosition = Vector3.MoveTowards(transform.localPosition, targetPosition, 5 * Time.deltaTime);
        }
    }
}


Вернуться к обсуждению:
Оптимизация движения большого количества объектов Unity, Unity3D
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.03.2023, 00:09
Готовые ответы и решения:

Оптимизация обработки большого количества объектов
Доброго времени суток, господа. У меня есть графическая программа на основе SFML. В программе обновляются около 12-13 тысяч объектов в...

Оптимизация хранения большого количества объектов в Dictionary
Добрый день. Имеется некий класс Quest и список public static Dictionary&lt;Subject, Dictionary&lt;byte, List&lt;Quest&gt;&gt;&gt; newdata_quest =...

Оптимизация большого количества if else
В приере только 3 в игре будет 26. и как видите (p1=0 и p2=1) тоже самое что (p1=1 и p2=0) получаетс 2 фразы повторяются. Как это...

52
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.03.2023, 00:09
Помогаю со студенческими работами здесь

Оптимизация большого количества NPC на карте
Пытаюсь сделать Терарию на C#(без Unity и т.д).В этой игре есть довольно большая карта, на которой одновременно размещается множество...

Оптимизация большого количества пользовательских элементов управления
Задача такова: необходимо создать элемент управления с предложением в котором выделяется каждое слово (слово при наведении выделяется...

Отрисовка большого количества объектов
Привет, у меня проблема: при отрисовке 3000 вершин телефон уже начинает тормозить(. Вопрос: на что вообще способен средний телефон в наше...

Оптимизация вывода большого (более 7000) количества записей на странице
Здравствуйте. Прошу совета, как сделать более оптимальным решение. Имеется справочник КБК. Модель: public partial class...

Проверка столкновения большого количества объектов
...и всё же. Вот на любом сайте, когда описывают и как сделать столкновение объектов, то приводят вот такой вот цикл для проверки всех...

0
Новые блоги и статьи
Использование кэша Laravel - полный гайд
bytestream 18.02.2025
Кэширование - один из наиболее эффективных способов повышения производительности веб-приложений. В современном мире, где скорость загрузки страниц напрямую влияет на удержание пользователей и. . .
Создаем REST API в Laravel с аутентификацией через Passport
bytestream 18.02.2025
Разработка современных веб-приложений все чаще требует создания надежного и хорошо структурированного API. REST API стал стандартом де-факто для построения взаимодействия между клиентской и серверной. . .
Пайплайны в Laravel - полный гайд
bytestream 18.02.2025
Разработка современных веб-приложений часто требует обработки сложных процессов, состоящих из множества последовательных шагов. Например, при создании системы комментариев может потребоваться. . .
Как правильно использовать @required в Symfony
bytestream 18.02.2025
При разработке приложений на Symfony мы часто сталкиваемся с необходимостью внедрения зависимостей. Фреймворк предоставляет несколько способов управления этим процессом, и одним из таких инструментов. . .
Система безопасности в Laravel: возможности и примеры
Wired 18.02.2025
Каждый день появляются новые виды атак и уязвимостей, которые могут поставить под угрозу конфиденциальные данные пользователей и функционирование всей системы. В этом контексте выбор надежного. . .
Давайте сравним Django и Laravel
Wired 18.02.2025
Django и Laravel - два мощных инструмента, которые часто сравнивают между собой. Оба фреймворка предлагают разработчикам богатый набор возможностей для создания масштабируемых веб-приложений, но. . .
Laravel или React - что лучше?
Wired 18.02.2025
В разработке веб выбор правильного инструмента часто определяет успех всего проекта. Особенно интересным представляется сравнение Laravel и React - двух популярных технологий, которые часто. . .
Laravel 11: новые возможности, гайд по обновлению
Wired 18.02.2025
Laravel 11 - это новая масштабная версия одного из самых популярных PHP-фреймворков, выпущенная в марте 2024 года. Эта версия продолжает традицию внедрения передовых технологий и методологий. . .
Миграции в Laravel
Wired 18.02.2025
Разработка веб-приложений на Laravel неразрывно связана с управлением структурой базы данных. При работе над проектом часто возникает необходимость вносить изменения в схему базы данных - добавлять. . .
Аутентификация в Laravel
Wired 18.02.2025
В современном мире веб-разработки безопасность пользовательских данных становится критически важным аспектом любого приложения. Laravel, как один из самых популярных PHP-фреймворков, предоставляет. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru