Форум программистов, компьютерный форум, киберфорум
Unity, Unity3D
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 23.03.2017
Сообщений: 6

Генерация карты в Unity

18.02.2018, 13:11. Показов 3891. Ответов 7

Студворк — интернет-сервис помощи студентам
Есть вот такой код
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
for (int i = 0; i <15 ; i++)
            {
        link1:
            coin_flip = Random.Range(0, 100); // Задается вектор направления построения следующей точки.
            if (coin_flip > 0 && coin_flip < 25) // Проверяем куда пойдет построение. В данном случаее по оси Х в положительном направлении.
                {
                next_pos_x = start_pos_x; // Стартовые позиции заданы случайно. 
                next_pos_x++; 
                next_pos_y = start_pos_y;
                if (
                   next_pos_x > 6 || next_pos_y > 6 || next_pos_x < 0 || next_pos_y < 0|| // Проверяем на выход из массива размер которого 7х7
                   brick[next_pos_x, next_pos_y + 1].activeInHierarchy == true || // Проверка на существование соседних клеток. Тут и выдает ошибку.
                   brick[next_pos_x, next_pos_y - 1].activeInHierarchy == true ||
                   brick[next_pos_x, next_pos_y].activeInHierarchy == true // Проверка на существование той клетки которую хотим построить.
                   )
                    {
                    start_pos_x = new_start_x;
                    start_pos_y = new_start_y;
                    goto link1;
                    }
                else
                    {                    
                    brick[next_pos_x, next_pos_y].SetActive(true); // Если все прошло успешно то включаем следующую клетку.
                    start_pos_x = next_pos_x; // Делаем новую точку как стартовую.
                    }
Проблем несколько:
1) Как избавиться от ошибок что выдает сам Unity? (Скрин во вложении)
2) Как сделать так что бы строилось столько клеток сколько указанно?
3) И может вообще это можно сделать как то по другому?

Заранее спасибо за помощь =)
Миниатюры
Генерация карты в Unity  
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.02.2018, 13:11
Ответы с готовыми решениями:

Генерация фона в 2D игре Unity 2D
Ребят, у кого есть идеи для генерирования фона в 2д игре. Есть самолет он находтся на фоне, когда я лечу в любуюсторону нужно чтобы...

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

Генерация и переход на случайную сцену при нажатии на объект в Unity 3D на C#
Генерация и переход на случайную сцену при нажатии на объект в Unity 3D на C# Всем привет. У меня есть скрипт, который накладывается...

7
 Аватар для ImAlexSmith
325 / 114 / 7
Регистрация: 01.05.2011
Сообщений: 283
Записей в блоге: 3
18.02.2018, 14:11
О боже, мои глаза...
Простите за такую реакцию, но использовать goto ?????

C#
1
2
3
4
5
var count = 15; // или сколько надо клеток 
 
for (int i = 0; i <count; i++)
{
}
Ошибки говорят, что индекс за границами массива. Т.е. например у вас brick размерностью 15, а вы пытаетесь взять объект с индексом >=15. Так нельзя.

Приведите весь код и более подробное описание задачи, что хотите получить - может чем помогу)
0
0 / 0 / 0
Регистрация: 23.03.2017
Сообщений: 6
18.02.2018, 18:30  [ТС]
Вот весь код
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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class rend_gen_v2 : MonoBehaviour {
 
 
    public GameObject obj;
    public GameObject[,] brick;
    public string objName = "Block_";
    private int id;
    public int x_range, y_range;
    public int start_pos_x, start_pos_y;
    public int new_start_x, new_start_y;
    public int brick_count = 0;
    public int next_pos_x, next_pos_y;
    private int coin_flip;
 
    void Start()
        {
        Create();
        StartPosition();
        }
 
    void Create()
        {
        id = 0;
        float pos_x = -4.5f;
        brick = new GameObject[x_range, y_range];
        for (int y = 0; y < y_range; y++)
            {
            float pos_y = -4.5f;
            for (int x = 0; x < x_range; x++)
                {
                brick[x, y] = Instantiate(obj, new Vector2(pos_y, pos_x), Quaternion.identity) as GameObject;
                brick[x, y].transform.parent = transform;
                brick[x, y].SetActive(false);
                brick[x, y].name = objName + id;
                id++;
                pos_y += 1.5f;
                }
            pos_x += 1.5f;
            }
 
        }
 
    void Update()
        {
        if (Input.GetButtonDown("Jump"))
            {
            Clear();
            Start();
            NextPosition();
            }        
        }
 
    void Clear()
        {
        for (int y = 0; y < 7; y++)
            {
            for (int x = 0; x < 7; x++)
                {
                Destroy(brick[x, y]);
                }
            }
        }
 
 
    void StartPosition()
        {
        start_pos_x = Random.Range(1, 5);
        start_pos_y = Random.Range(1, 5);
        brick[start_pos_x, start_pos_y].SetActive(true);
        new_start_x = start_pos_x;
        new_start_y = start_pos_y;
        }
 
   
 
    void NextPosition ()
        {
        brick_count = 0;
        for (int i = 0; i <15 ; i++)
            {
        link1:
            coin_flip = Random.Range(0, 100); 
            if (coin_flip > 0 && coin_flip < 25) 
                {
                next_pos_x = start_pos_x; 
                next_pos_x++; 
                next_pos_y = start_pos_y;
                if (
                   next_pos_x > 6 || next_pos_y > 6 || next_pos_x < 0 || next_pos_y < 0|| 
                   brick[next_pos_x, next_pos_y + 1].activeInHierarchy == true || 
                   brick[next_pos_x, next_pos_y - 1].activeInHierarchy == true ||
                   brick[next_pos_x, next_pos_y].activeInHierarchy == true 
                   )
                    {
                    start_pos_x = new_start_x;
                    start_pos_y = new_start_y;
                    goto link1;
                    }
                else
                    {                    
                    brick[next_pos_x, next_pos_y].SetActive(true); // 
                    start_pos_x = next_pos_x; 
                    }
                }
            else if (coin_flip > 25 && coin_flip < 50)
                {
                next_pos_y = start_pos_y;
                next_pos_y++;
                next_pos_x = start_pos_x;
                if (
                    next_pos_x > 6 || next_pos_y > 6 || next_pos_x < 0 || next_pos_y < 0 ||
                    brick[next_pos_x + 1, next_pos_y].activeInHierarchy == true ||
                    brick[next_pos_x - 1, next_pos_y].activeInHierarchy == true ||
                    brick[next_pos_x, next_pos_y].activeInHierarchy == true
                    )
                    {
                    start_pos_x = new_start_x;
                    start_pos_y = new_start_y;
                    goto link1;
                    }
                else
                    {                    
                    brick[next_pos_x, next_pos_y].SetActive(true);
                    start_pos_y = next_pos_y;
                    }
                }
 
            else if (coin_flip > 50 && coin_flip < 75)
                {
                next_pos_x = start_pos_x;
                next_pos_x--;
                next_pos_y = start_pos_y;
                if (
                    next_pos_x > 6 || next_pos_y > 6 || next_pos_x < 0 || next_pos_y < 0 ||
                   brick[next_pos_x, next_pos_y + 1].activeInHierarchy == true || 
                   brick[next_pos_x, next_pos_y - 1].activeInHierarchy == true ||
                   brick[next_pos_x, next_pos_y].activeInHierarchy == true
                    )
                    {
                    start_pos_x = new_start_x;
                    start_pos_y = new_start_y;
                    goto link1;
                    }
                else
                    {
                    brick[next_pos_x, next_pos_y].SetActive(true);
                    start_pos_x = next_pos_x;
                    }
                }
            
            else if (coin_flip > 75 && coin_flip < 100)
                {
                next_pos_y = start_pos_y;
                next_pos_y--;
                next_pos_x = start_pos_x;
                if (
                    next_pos_x > 6 || next_pos_y > 6 || next_pos_x < 0 || next_pos_y < 0 ||
                    brick[next_pos_x + 1, next_pos_y].activeInHierarchy == true ||
                    brick[next_pos_x - 1, next_pos_y].activeInHierarchy == true ||
                    brick[next_pos_x, next_pos_y].activeInHierarchy == true
                   )
                    {
                    start_pos_x = new_start_x;
                    start_pos_y = new_start_y;
                    goto link1;
                    }
                else
                    {
                    brick[next_pos_x, next_pos_y].SetActive(true);
                    start_pos_y = next_pos_y;
                    }
                }
            }
        }
    }
Необходимо что бы происходило построение из массива (скрин1) полностью рандомных "лабиринтов" как на остальных скринах
Миниатюры
Генерация карты в Unity   Генерация карты в Unity   Генерация карты в Unity  

Генерация карты в Unity  
0
 Аватар для ImAlexSmith
325 / 114 / 7
Регистрация: 01.05.2011
Сообщений: 283
Записей в блоге: 3
19.02.2018, 16:54
Лучший ответ Сообщение было отмечено susa как решение

Решение

Я вам там еще код поправил, чтобы нормально выглядел Кстати, если нужно, чтобы было именно столько клеток, сколько в переменной MazeBricksCount - надо доработать метод NextPosition. Поиграйтесь)
Кликните здесь для просмотра всего текста
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
 // =====
    private const float BrickSize = 1.5f;
 
 
    // =====
    public GameObject Prefab;
    public string ObjNamePrefix = "Block_";
 
    public int RangeX = 10, RangeY = 6;
    public int StartPosX = 3, StartPosY = 4;
    public GameObject[] Bricks;
    public int MazeBricksCount = 10;
 
    private Stack<int> _maze;
 
 
    // =====
    void Start()
    {
        Create();
        StartPosition();
        NextPosition();
    }
 
    void Update()
    {
        if (Input.GetButtonDown("Jump"))
        {
            Clear();
            Create();
            StartPositionRandom();
            NextPosition();
        }
 
        if (Input.GetButtonDown("Fire2"))
        {
            Clear();
            Create();
            StartPosition();
            NextPosition();
        }
    }
 
    int ArrayIndex(int x, int y)
    {
        return y * RangeX + x;
    }
 
    void Clear()
    {
        if (Bricks != null)
        {
            for (int i = 0; i < Bricks.Length; i++)
            {
                if (Bricks[i] != null)
                    Destroy(Bricks[i]);
            }
        }
 
        Bricks = null;
        _maze = null;
    }
 
    void Create()
    {
        _maze = new Stack<int>();
        Bricks = new GameObject[ArrayIndex(RangeX, RangeY)];
 
        for (int y = 0; y < RangeY; y++)
        {
            for (int x = 0; x < RangeX; x++)
            {
                var ai = ArrayIndex(x, y);
                Bricks[ai] = Instantiate(Prefab, new Vector2(x * BrickSize, y * BrickSize), Quaternion.identity, transform);
                Bricks[ai].SetActive(false);
                Bricks[ai].name = string.Format("{0}_[{1},{2}]({3})", ObjNamePrefix, x, y, ai);
            }
        }
 
        SetupCameraAfterCreate(Camera.main);
    }
 
    void StartPositionRandom()
    {
        StartPosX = Random.Range(0, RangeX);
        StartPosY = Random.Range(0, RangeY);
        StartPosition();
    }
 
    void StartPosition()
    {
        ActivateBrick(StartPosX, StartPosY);
    }
 
    void NextPosition()
    {
        for (int i = 0; i < MazeBricksCount; i++)
        {
            if (_maze.Count <= 0)
                break;
 
            while (true)
            {
                var nextPosX = _maze.Peek() % RangeX;
                var nextPosY = _maze.Peek() / RangeX;
                var coinFlip = Random.Range(0, 100);
 
                if (coinFlip >= 0 && coinFlip < 25)
                {
                    nextPosX++;
 
                    if (CheckBrick(nextPosX, nextPosY, true))
                    {
                        ActivateBrick(nextPosX, nextPosY);
                        break;
                    }
                }
                else if (coinFlip >= 25 && coinFlip < 50)
                {
                    nextPosY++;
 
                    if (CheckBrick(nextPosX, nextPosY, false))
                    {
                        ActivateBrick(nextPosX, nextPosY);
                        break;
                    }
                }
                else if (coinFlip >= 50 && coinFlip < 75)
                {
                    nextPosX--;
 
                    if (CheckBrick(nextPosX, nextPosY, true))
                    {
                        ActivateBrick(nextPosX, nextPosY);
                        break;
                    }
                }
                else if (coinFlip >= 75 && coinFlip < 100)
                {
                    nextPosY--;
 
                    if (CheckBrick(nextPosX, nextPosY, false))
                    {
                        ActivateBrick(nextPosX, nextPosY);
                        break;
                    }
                }
 
                _maze.Pop();
                if (_maze.Count <= 0)
                    break;
            }
        }
    }
 
    private bool CheckBrick(int x, int y, bool horizontal)
    {
        if (x >= RangeX || y >= RangeY || x < 0 || y < 0 || Bricks[ArrayIndex(x, y)].activeInHierarchy)
            return false;
 
        if (horizontal)
        {
            if (y < RangeY - 1 && Bricks[ArrayIndex(x, y + 1)].activeInHierarchy)
                return false;
 
            if (y > 0 && Bricks[ArrayIndex(x, y - 1)].activeInHierarchy)
                return false;
        }
        else
        {
            if (x < RangeX - 1 && Bricks[ArrayIndex(x + 1, y)].activeInHierarchy)
                return false;
 
            if (x > 0 && Bricks[ArrayIndex(x - 1, y)].activeInHierarchy)
                return false;
        }
 
        return true;
    }
 
    private void ActivateBrick(int x, int y)
    {
        var ai = ArrayIndex(x, y);
        Bricks[ai].SetActive(true);
        _maze.Push(ai);
    }
 
    private void SetupCameraAfterCreate(Camera cam)
    {
        cam.transform.position = new Vector3((RangeX - 1) * BrickSize / 2f, (RangeY - 1) / 2f * BrickSize, cam.transform.position.z);
 
#if UNITY_EDITOR
        var ratio = 1F;
        if (Application.isEditor && !Application.isPlaying)
        {
            var gameViewSize = GetMainGameViewSize();
            ratio = gameViewSize.x / gameViewSize.y;
        }
        else
            ratio = (float) Screen.width / Screen.height;
#else
            var ratio = (float)Screen.width / Screen.height;
#endif
 
        if ((float) RangeX / RangeY > ratio)
        {
            cam.orthographicSize = RangeX * BrickSize / (2F * ratio);
        }
        else
        {
            cam.orthographicSize = RangeY * BrickSize / 2F;
        }
    }
 
#if UNITY_EDITOR
    private static Vector2 GetMainGameViewSize()
    {
        System.Type T = System.Type.GetType("UnityEditor.GameView,UnityEditor");
        System.Reflection.MethodInfo GetSizeOfMainGameView = T.GetMethod("GetSizeOfMainGameView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
        System.Object Res = GetSizeOfMainGameView.Invoke(null, null);
        return (Vector2) Res;
    }
#endif
1
0 / 0 / 0
Регистрация: 23.03.2017
Сообщений: 6
20.02.2018, 09:01  [ТС]
ImAlexSmith, Спасибо конечно. Но я вообще нихрена не понимаю что тут происходит)
0
 Аватар для ImAlexSmith
325 / 114 / 7
Регистрация: 01.05.2011
Сообщений: 283
Записей в блоге: 3
20.02.2018, 09:17
Ну так хорошая возможность разобраться, разве нет?)
Что именно непонятно?
0
0 / 0 / 0
Регистрация: 23.03.2017
Сообщений: 6
20.02.2018, 09:23  [ТС]
ImAlexSmith, Примерно всё) Есть возможность связаться? Там скайп какой нибудь или что нибудь вроде того?
0
 Аватар для ImAlexSmith
325 / 114 / 7
Регистрация: 01.05.2011
Сообщений: 283
Записей в блоге: 3
20.02.2018, 15:08
susa, возможность есть, желания - нет)

Попробуйте разобраться и задавайте конкретные вопросы, отвечу.
Если вам интересно, что не работало в вашем коде, то в подобных местах
C#
1
2
brick[next_pos_x, next_pos_y + 1].activeInHierarchy == true || 
brick[next_pos_x, next_pos_y - 1].activeInHierarchy == true ||
надо было добавить проверку на выход за границы массива (+1, -1).
Если интересно научится писать более грамотный код - то лучше разобраться в моем примере
Потому что от goto и паскаль_стайл в c# глаза вытекают)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.02.2018, 15:08
Помогаю со студенческими работами здесь

Генерация игровой карты через изображение
Имеется пиксельное изображение карты, в котором каждая провинция имеет свой уникальный цвет. Хочу, чтобы из подобных изображений можно было...

Генерация 2D карты
Привет всем. Пусть у нас есть квадрат или прямоугольник nxm пикселей. Нам надо делить карту на заданное k количество площадей. Т.к....

Генерация карты
Здравствуйте, сейчас делаю игру, так сказать изучаю XNA. В игре персонаж перемещается по блокам. Карта игры находиться в текстовом файле, в...

Генерация карты
Надо добавить в сгенерированую мной карту, символ &quot;X&quot; в ячейку, количество которого мы вводим в конструкторе вот так...

Генерация карты
Доброе время суток. Подскажите пожалуйста алгоритмы с помощью которых можно сделать подобного рода карты: Может быть есть готовые...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru