Рандом без повторения в switch
|
|
StinkN | Дата: Среда, 28 Марта 2018, 18:56 | Сообщение # 1 |
был не раз
Сейчас нет на сайте
| Привет, пишу я скрипт рандома, с появлением обьекта. Когда к примеру я захожу в триггер, и у меня появляется обьект в рандомном месте. Когда захожу по новой в него, появляется другой другой обьект в другом месте. Но проблема в том что бывает после захода в триггер обьект появляется в том же месте где и предыдущий например. Сам код
Код var rnd = Random.Range(0,2); switch (rnd) { case 0: obj[0].SetActive (true); break; case 1: obj[1].SetActive (true); break; case 2: obj[2].SetActive (true); break;
Как бы сделать так, что бы case больше не повторялся?
|
|
| |
sfabrikan | Дата: Среда, 28 Марта 2018, 19:03 | Сообщение # 2 |
БЕЗУМЕЦ!!!
Сейчас нет на сайте
| Я не юнитист, но что-то мне подсказывает нужно задать у рандома семя типа Randomseed(), srand() около того
Это я
|
|
| |
StinkN | Дата: Среда, 28 Марта 2018, 19:08 | Сообщение # 3 |
был не раз
Сейчас нет на сайте
| Не понял куда вписать это. Пишу это вместo Random.Range, она закрашивается красным
|
|
| |
sfabrikan | Дата: Среда, 28 Марта 2018, 19:17 | Сообщение # 4 |
БЕЗУМЕЦ!!!
Сейчас нет на сайте
| StinkN, специально для вас залез в доки юнити и сразу нашел что нужно Random.seed = n; n число И не надо убирать рандом.рейдж. Просто рандом.сид где нибудь выше вставьте и все. Это нужно чтоб рандом был "рандомен"
Это я
Сообщение отредактировал sfabrikan - Среда, 28 Марта 2018, 19:21 |
|
| |
StinkN | Дата: Среда, 28 Марта 2018, 19:22 | Сообщение # 5 |
был не раз
Сейчас нет на сайте
| Код Random.seed = 2; var rnd = Random.Range(0,2); Написал так. Не пашет(
|
|
| |
sfabrikan | Дата: Среда, 28 Марта 2018, 19:25 | Сообщение # 6 |
БЕЗУМЕЦ!!!
Сейчас нет на сайте
| StinkN, жди других, я лиш ориентировался на общих признаках в программировании
Это я
|
|
| |
seaman | Дата: Среда, 28 Марта 2018, 19:29 | Сообщение # 7 |
старожил
Сейчас нет на сайте
| Random.Range(0,2); Никогда не даст значения 2, т.к. 0 и 2 - целые. Чтобы не было повторов - запоминай какой уже был и сравнивай random с ним, если тот же - снова random...
|
|
| |
StinkN | Дата: Среда, 28 Марта 2018, 19:36 | Сообщение # 8 |
был не раз
Сейчас нет на сайте
| seaman, Не понял.. Я не сильно так разбираюсь в программировании А подробнее можно пожалуйста, если не сложно.
|
|
| |
Vostrugin | Дата: Среда, 28 Марта 2018, 19:39 | Сообщение # 9 |
постоянный участник
Сейчас нет на сайте
| seaman, не самое лучшее решение. Почему не сделать пул с возможными значениями, выпавшее значение удаляешь из пула. Соответственно выбирать случайное значение из этого пула. Как только пул стал пустым - наполняем его заново.
|
|
| |
StinkN | Дата: Среда, 28 Марта 2018, 19:40 | Сообщение # 10 |
был не раз
Сейчас нет на сайте
| Vostrugin, Цитата StinkN ( ) Я не сильно так разбираюсь в программировании А подробнее можно пожалуйста, если не сложно.
|
|
| |
zmear | Дата: Среда, 28 Марта 2018, 20:23 | Сообщение # 11 |
почетный гость
Сейчас нет на сайте
| Код var rnd = Random.Range(0,2);//в с++ правильнее было бы написать rand()%3, или как минимум (2) целое чиcло в скобках, обратите внимание на это, а чтобы не было повторений можно использовать такой алгоритм: вводим переменную int check; switch (rnd) { case 0: if (!check==0){// и вот такое условие проверки можно сделать, оно не допустит повторения, но может быть такое, что будут появлять в двух местах, игнорируя третье некоторое время obj[0].SetActive (true); check=0; } break; case 1: obj[1].SetActive (true); check=1; break; case 2: obj[2].SetActive (true); check=2; break; чтобы работало до конца, нужно будет зациклить, пока check не примет другое значение, вместо того, которое у него было до этого, это можно сделать циклом while или вашим циклом введя доп. условиеДобавлено (28 Марта 2018, 20:22) --------------------------------------------- Ну и не забудьте услове в каждом блоке case добавить Добавлено (28 Марта 2018, 20:23) --------------------------------------------- Проблему можно решить и будет идеально отдельной функцией, но для этого, если ничего не поможет, напишите в лс мне
|
|
| |
drcrack | Дата: Среда, 28 Марта 2018, 20:56 | Сообщение # 12 |
старожил
Сейчас нет на сайте
| Тему не читал А рандом без повторений делается так:
Код List<AudioClip> clips = new List<AudioClip>(); int index;
public AudioClip GetNext() {
if (clips.Count == 0) return null;
if (clips.Count == 1) return clips[0];
index = (index + Random.Range(1, clips.Count)) % clips.Count;
return clips[index];
}
Сообщение отредактировал drcrack - Среда, 28 Марта 2018, 21:20 |
|
| |
StinkN | Дата: Четверг, 29 Марта 2018, 05:20 | Сообщение # 13 |
был не раз
Сейчас нет на сайте
| drcrack, а в моем случае как реализовать?
|
|
| |
drcrack | Дата: Четверг, 29 Марта 2018, 06:13 | Сообщение # 14 |
старожил
Сейчас нет на сайте
| Да так же как и у меня. Можешь лишние проверки убрать если уверен что обьекты всегда есть.
Код public GameObject[] obj; // судя по всему заполняется в инспекторе int objectIndex; // чтобы избежать повторений, надо хранить предыдущий индекс // ...... void ActivateRandomObject(){ objectIndex = (objectIndex + Random.Range(1, obj.Length)) % obj.Length; obj[objectIndex].SetActive(true); }
P.S.
Цитата Чтобы не было повторов - запоминай какой уже был и сравнивай random с ним, если тот же - снова random...
Цитата seaman, не самое лучшее решение. Почему не сделать пул с возможными значениями, выпавшее значение удаляешь из пула. Соответственно выбирать случайное значение из этого пула. Как только пул стал пустым - наполняем его заново.
Цитата нужно будет зациклить, пока check не примет другое значение, вместо того, которое у него было до этого, это можно сделать циклом while или вашим циклом введя доп. условие это был негласный конкурс на худшее решение проблемы тса?
Сообщение отредактировал drcrack - Четверг, 29 Марта 2018, 06:17 |
|
| |
Vostrugin | Дата: Четверг, 29 Марта 2018, 09:05 | Сообщение # 15 |
постоянный участник
Сейчас нет на сайте
| Цитата drcrack ( ) это был негласный конкурс на худшее решение проблемы тса? У тебя решение хорошее Но если я понял задачу тс-а правильно, то нужно исключить выпадание похожих значений вообще, а не подряд, поэтому я предложил использовать пул. Твоё же решение "лечит" только случаи с выпаданием подряд одинаковых чисел.
Сообщение отредактировал Vostrugin - Четверг, 29 Марта 2018, 09:06 |
|
| |
drcrack | Дата: Четверг, 29 Марта 2018, 09:12 | Сообщение # 16 |
старожил
Сейчас нет на сайте
| Если объекты должны появляться по одному разу за все время, то можно просто удалять их из obj (предварительно сделав его List<GameObject>, если он просто массив) Ну и как тут уже сказали, Random.Range(0,2) возвращает 0 или 1 и в коде тса последний объект не появится вообще никогда
Код public static class GCUPExtensions {
public static T PullRandom<T>(this List<T> list) {
if (list.Count == 0) return default(T);
var index = UnityEngine.Random.Range(0, list.Count); var result = list[index];
list.RemoveAt(index);
return result; }
} пользоваться так:
Код if(obj.Count > 0) obj.PullRandom().SetActive(true);
Сообщение отредактировал drcrack - Четверг, 29 Марта 2018, 09:25 |
|
| |