Среда, 12 Августа 2020, 01:36

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Модератор форума: beril  
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Защита от пересечения генерируемых объектов (Части уровня создаются друг в друге, а это надо исправить.)
Защита от пересечения генерируемых объектов
mrFrankensteinДата: Воскресенье, 10 Мая 2020, 22:49 | Сообщение # 1
был не раз
Сейчас нет на сайте
На сцене перед началом игры случайно генерируются части уровня, всячески поворачивая и закручиваясь. Иногда они закручиваются сами в себя, а иногда большой кусок ставится в маленькой пространство. вот как-то так получается http://s1.uploadpics.ru/images/-yyDLbFjpB.png
Надо как-то придумать проверку для того, чтобы знать когда можно ставить кусочки а когда нельзя, а я не могу придумать(
Помогите :)

Добавлено (12 Мая 2020, 18:24)
---------------------------------------------
Короче. Рас уж никто мне не может помочь, то буду делать сам и пусть вам, дорогие друзья, будет стыдно crazy
На данный момент придумал я такую штуку: перед установкой нужного объекта на своё место на это место ставится примитив (куб) который ещё и триггер. Триггер меняет размеры примерно имитируя размеры возможных комнат, а результаты пишутся в массив. Если такой-то размер задевает другие объекты, то комнату такого-то размера суда ставить нельзя. Осталось только придумать, как в нулевой промежуток времени (между строчками кода) проверить касается ли триггера что-нибудь или нет, т.к. OnTriggerStay-Enter работают не так, да и вдобавок енто в дугом скрипте делается, а я так не хочу.
Короче, пойду искать инфу. Вернусь завтра ^_^ ну, или когда там получится)


Сообщение отредактировал mrFrankenstein - Вторник, 12 Мая 2020, 18:27
Storm54Дата: Вторник, 12 Мая 2020, 19:16 | Сообщение # 2
постоянный участник
Сейчас нет на сайте
Можно проверять без костылей с триггерами, например через Physics.OverlapBox или подобный метод. А можно проверять без использования средств Unity, задав каждой комнате прямоугольник или параллелепипед (если требуется 3D) и проверять пересечение этих фигур. Проблема же не только в пересечении, а в целом в алгоритме генерации лабиринтов? Парой строк кода здесь не обойдешься.

Более 10 лет опыта разработки на разных языках высокого уровня.
Отличные знания .NET, Unity.
Отличные знания TCP, UDP.
Наличие выпущенных коммерческих проектов (Верхние рейтинги в Google Play и App Store).
Платные и бесплатные консультации по любым темам геймдева - Л.С.
mrFrankensteinДата: Среда, 13 Мая 2020, 18:32 | Сообщение # 3
был не раз
Сейчас нет на сайте
Да вот нет, мне кажется, что как раз обойдешься. И Physics.OverlapBox, возможно, как раз то, что я ищу. Заранее спасибо)

Сейчас код выглядит так

Код

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CaveCreator : MonoBehaviour
{
public GameObject[] caveSpavnPoint;    //хранилище найденых точек установки частей пещеры
public GameObject[] spawnObjects;    //устанавливаемые обьекты
public GameObject[] spawnedObj;    //установленные обьекты
public int caveLong;    // задаём длинну пещеры

private int I=0;    //счётчик длинны пещеры
private GameObject Instantiat;    //надо подумать как без этого
public Bounds b;    //попробуем с бондами избавится от пересечения

void Start()
{
spawnedObj= new GameObject[caveLong];    //устанавливаем длинну массива
}

void Update()
{
if(caveLong>I)    //если ещё надо ставить куски то...
{
caveSpavnPoint = GameObject.FindGameObjectsWithTag("CaveSpawnPoint");    //ищем все точки для спавна
if(caveSpavnPoint.Length>=2)    //если нашлось больше 2-х точек то...
{
GameObject spawn = new GameObject();    //создаём обьект для выбора рондомного кусочка
spawn=caveSpavnPoint[Random.Range(0,(caveSpavnPoint.Length-1))];    //выбераем кусочек
Instantiat=GameObject.Instantiate(spawnObjects[Random.Range(0,(spawnObjects.Length-1))],spawn.transform.position,spawn.transform.rotation) as GameObject;    //ставим кусочек
spawnedObj[I]=Instantiat;    //записываем установленный кусочек в массив
Destroy(spawn);    //удаляем точку спавна
b = new Bounds(spawnedObj[I].transform.Find("main").position, new Vector3(112, 112, 12));    //пытаюсь разобраться с бондами
}
else    //если точек спавна мень 2-х то...
{
Instantiat=GameObject.Instantiate(spawnObjects[0],caveSpavnPoint[0].transform.position,caveSpavnPoint[0].transform.rotation) as GameObject;    //не мудрствуя лукаво ставим кусочек
spawnedObj[I]=Instantiat;    //записываем установленный кусочек в массив
Destroy(caveSpavnPoint[0]);    //удаляем точку спавна
}
I++;    //рибавляем 1 к счётчику
}
}
}

Посмотрим, что из него получится)

Добавлено (14 Мая 2020, 23:44)
---------------------------------------------
И вот я снова тут. Это было сложно, но я что-то сделал crazy
По крайней мере оно работает и даже так, как я хотел)
А вот собственно и код. Если есть замечания и предложения- бичуйте меня по чём зря! Нечего тут рассусоливать! Если говно- то и говорите что говно, но с оговорками что и как можно исправить)

Код
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CaveCreator : MonoBehaviour
{
    public Vector3 startPointPos;  //запомнить стартовую позицию
    public Quaternion startPointRot;  //и направление
    public int misTry;  //счётчик неудачных установок

    public GameObject[] caveSpavnPoint;    //хранилище найденых точек установки частей пещеры
    public GameObject[] spawnObjects;    //устанавливаемые обьекты
    public GameObject[] spawnRums;    //обьект для выбора онончаний тонелей
    public GameObject[] spawnedObj;    //установленные обьекты
    public GameObject spawn;    //обьект для выбора рондомного кусочка
    public int caveLong;    // задаём длинну пещеры

    private int I=0;    //счётчик длинны пещеры
    private GameObject Instantiat;    //надо подумать как без этого
    
    bool Started;  //для гизмо для инспектора. Удалить по окончании!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    //чтобы не создавать новые переменные во время работы кода
    //создаём переменные, в кторые будут сохранятся переменные колайдёра
    //для проверки столкновений с другими коллайдёрами
    Vector3 positionOfCave;  //сохраняем позицию
    Vector3 sizeOfCave;   //и размер
    Quaternion rotOfCave;  //и направление

    void Start()
    {
        spawnedObj= new GameObject[(caveLong+10)];    //устанавливаем длинну массива
        Started = true;  //это штука для работы гизмо в инспекторе. Удалить!!!!!!!!!!!!!!!!!!!!!!!!!
        startPointPos=GameObject.FindWithTag("CaveSpawnPoint").transform.position;  //запоминаем стартовую позицию
        startPointRot=GameObject.FindWithTag("CaveSpawnPoint").transform.rotation;  //и направление обьекта, из которого будет начинаться пещера
    }

    void Update()
    {
     if(misTry>25)  //если ошибок больше 25
     {
      misTry=0;  //обнуляем счётчик ошибок
      GameObject star = new GameObject();  //создаём новый обьект в сцене. Да, от этого все эти непонятные "New Game Objeсt". Больше не использую такую нострукцию
      star.transform.position=startPointPos;  //задаём обьекту нужную позицию
      star.transform.rotation=startPointRot;  //и напавление
      star.tag = "CaveSpawnPoint";  //и нужный таг тоже

      for(int i=0; i<spawnedObj.Length-1; i++)  //циклом удаляем все уже созданные обьекты
      {
       Destroy(spawnedObj[i]);  
      }

      spawnedObj= new GameObject[caveLong+10];  //обуляем массив созданных обьектов чтоб наверняка
      I=0;  //ну и обнуляем счётчик длинны пещеры
     }
     else  //если ошибок не больше 25, то
     {
      caveSpavnPoint = GameObject.FindGameObjectsWithTag("CaveSpawnPoint");    //ищем все точки для спавна
      if(caveSpavnPoint.Length >0)    //если ещё надо ставить куски то...
      {
       spawn=caveSpavnPoint[Random.Range(0,(caveSpavnPoint.Length-1))];    //берём случайный кусочек

       if(caveSpavnPoint.Length +I <= caveLong)  //если не достаточно проходов и не нужно ставить комнаты
       {
        Instantiat=GameObject.Instantiate(spawnObjects[Random.Range(0,spawnObjects.Length)],spawn.transform.position,spawn.transform.rotation) as GameObject;    //ставим кусочек
       }
       else  //если достаточно проходов и нужно ставить комнаты
       {
        Instantiat=GameObject.Instantiate(spawnRums[Random.Range(0,spawnRums.Length)],spawn.transform.position,spawn.transform.rotation) as GameObject;    //ставим комнаты
       }
       spawnedObj[I]=Instantiat;  //записываем установленный кусочек в массив
       string nam=I.ToString();  //переводим цифры в буквы
       spawnedObj[I].name=nam ;  //переименовываем установленный кусочек в номер
      
          positionOfCave=spawnedObj[I].transform.Find("box").transform.position;  //из только что установленного кусочка выдераем обьект, который размерами как комната, только это простой квадрат
          sizeOfCave=spawnedObj[I].transform.Find("box").GetComponent<Collider>().bounds.size;  //выдераем из квадрата его размер в мировых кординатах
          rotOfCave=spawnedObj[I].transform.rotation;  //и направление

          spawnedObj[I].SetActive(false);  //основной же обьект скрываем на время проверки
          Collider[] colliders = Physics.OverlapBox(positionOfCave, sizeOfCave, rotOfCave);  //собственно, делаем проверку

          if(colliders.Length>=1)  //если проверка показала, что мы чего-то касаемся, то...
          {
           misTry++;  //+1 в ошибки
           Destroy(spawnedObj[I]);  //удаляем установленный обьект
          }
          else  //если проверка показала, что мы ничего не касаемся, то...
          {
           misTry=0;  //обнуляем счётчик ошибок
           spawnedObj[I].SetActive(true);  //включаем наш главный обьект
           Destroy(spawnedObj[I].transform.Find("box").gameObject);  //удаляем уже ненужный квадрат
           Destroy(spawn);    //удаляем точку спавна
           I++;    //прибавляем 1 к счётчику
          }
      }
  }
    }

    void OnDrawGizmos()  //эта штака нужна только для гизмо в инспекторе. Удалить!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    {
        Gizmos.color = Color.red;
        if (Started)
            Gizmos.DrawWireCube(positionOfCave, sizeOfCave);
    }
}


Сообщение отредактировал mrFrankenstein - Среда, 13 Мая 2020, 18:33
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Защита от пересечения генерируемых объектов (Части уровня создаются друг в друге, а это надо исправить.)
  • Страница 1 из 1
  • 1
Поиск:

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