Четверг, 14 Ноября 2024, 06:05

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Рандом без повторения в 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, Не понял.. Я не сильно так разбираюсь в программировании cranky А подробнее можно пожалуйста, если не сложно.
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
старожил
Сейчас нет на сайте
Тему не читал :D А рандом без повторений делается так:
Код
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, а в моем случае как реализовать? crazy
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 или вашим циклом введя доп. условие

это был негласный конкурс на худшее решение проблемы тса? :D


Сообщение отредактировал 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
  • Страница 1 из 1
  • 1
Поиск:

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