Как передать другому скрипту информацию о столкновении определенного объекта из списка?

Рейтинг: 0Ответов: 1Опубликовано: 25.05.2023

Я добавляю объекты в список по кнопке, попутно прикрепляя к ним BoxCollider и Rigidbody. Все это происходит в первом скрипте:

//1 скрипт SBridge
public GameObject bridgeParticle; //добавил префаб
public List<GameObject> copyBridgeParticle = new List<GameObject>(); //создал список копий префаба
public void CreateObject() //подключил метод создания копий объектов к кнопке
{
  copyBridgeParticle.Add(Instantiate(bridgeParticle, newStartPosBridgeParticle, Quaternion.identity)); //добавил в список копию объекта
  copyBridgeParticle[i].AddComponent<BoxCollider>();
  copyBridgeParticle[i].AddComponent<Rigidbody>();
  copyBridgeParticle[i].AddComponent<SParticle>(); //добавил в качестве компонента 2 скрипт для проверки столкновений
}

//2 скрипт SParticle
private bool collided; //создал поле, отслеживающее столкновение
public bool GetCollideInfo { get => collided; } //обернул в свойство, чтобы использовать в 1 скрипте
private void OnCollisionEnter(Collision collision)
{
    collided = true;
}

Вопрос: как мне проверять значение GetCollideInfo из 1 скрипта во 2-ом по каждому объекту? Можно было бы создать публичную переменную типа SBridge и закинуть объект со скриптом, но объекты создаются при нажаии на кнопку (то есть изначально не на что закидывать в инспекторе). Пробовал прикрепить с помощью GetComponent<>, но также безуспешно. Всю механику удалось реализовать с помощью static, но это не практично + все части зависят друг от друга.

Расскажу чего хочу добиться: создается мост из частей (все части становятся дочерними, чтобы при перемещении моста объекты передвигались с ним). Далее, при столкновении с другим объектом на сцене, происходит отвязка от родителя, создается физика каждой части моста и они разлетаются. При этом я хочу отслеживать какие именно части столкнулись.

Буду рад любым предложениям, ибо перерыл уже весь интернет, перепробовал все возможные вариации (на мой взгляд)

Ответы

▲ 0

Для таких ситуаций я в другом языке использую систему сигналов

Смысл в том, что ты из любого места можешь передать необходимые данные в любое место и принять его там. Считай как вайфай в коде)))

при моей реализации сигналов это выглядит так в свифте:

// Обьявление самого сигнала
struct Signal {
    struct CollisionStart {
         let go1: GameObject
         let go2: GameObject
    }

    struct CollisionStop {
         let go1: GameObject
         let go2: GameObject
    }
}
//в нужном месте посылаем сигнал
StaticSignalSystem.send(Signal.CollisionStart(go1: collision.gameObject1, go2: collision.gameObject2) )
//в нужном месте подписываемся на сигнал
StaticSignalSystem.subscribe(to: Signal.CollisionStart.self)
     .onUpdate(context: self){ me, args in
           me.currentCollision = args 
           //здесь записываю в обьект где нахожусь Collision(GameObject,GameObject)
     }

на практике синтаксис будет зависеть не только от языка, но и от реализации системы сигналов поэтому твой код будет выглядеть совершенно иначе сохраняя принцип:

  • создать тип сигнала
  • где-то послать сигнал
  • где-то принять сигнал

Собственно сами реализации систем сигналов ты можешь найти в интернете и без особых проблем применить у себя в проэкте даже на юнити)

//////////

Второй вариант менее заморочлив - создать статическую переменную которая будет по-факту хранить весь список коллизий необходимого типа.

И как только будет начинатся коллизия - добавлять туда ее.

А как только будет заканчиватся коллизия - убирать из этого статического списка.

Но подозреваю что коллизий может быть несколько одновременно и как следствие к одному списку может быть доступ из нескольких мест и это может создать проблемы.... Но нужно пробовать на практике.

А к статическим переменным мы всегда и отовсюду имеем доступ.