TransWikia.com

Как получить массив из GameObject'ов, который косаются другого объекта в Юнити

Stack Overflow на русском Asked on January 12, 2021

Я делаю игру про алхимию в Юнити, в которой игрок должен соединять несколько элементов, чтобы получить другой.
КОгда игрок соединяет два элемента, например огонь и воду, то вызывается функция OnMouseUp (в которой я устанавливаю переменной wasMouseReleased значение true), и функция ONCollisionStay (где я проверяю, была ли кнопка мыши отпущена* и соединяю элементы, если возможно). Но в некоторых случаях в соединении учавствуют 3 или даже 4 элемента, однако OnCollisionStay возвращает только 1 объект, с которым котактирует другой. Есть ли какая-то функция, которая возвращает список или массив всех объектов, с которыми контактирует другой объект, на котором висит скрипт?
Например: игрок соединяет металл и батарейку, но ничего не происходит, потому что такого соединения в игре нет, но потом я добавляю ИИ, после чего я получаю список из 3 этих элементов, они пропадают, а появляется робот.
Мой скрипт сейчас выглядит так:

public class Elements_Behaviour : MonoBehaviour
{
    bool wasReleased = false; // отпущена ли кнопка мыши
    private void OnMouseDown()
    {
        wasReleased = false;
    }
    private void OnMouseDrag()
    {
        Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 5);
        Vector3 objPos = Camera.main.ScreenToWorldPoint(mousePos);
        transform.position = objPos;
    }
    private void OnMouseUp()
    {
        wasReleased = true;
    }
    private void OnCollisionStay2D(Collision2D collision)
    {
        if (wasReleased)
        {
            tryToConnect();

            wasReleased = false;
        }
    }
}

  • Мне нужна переменная wasReleased для того, чтобы элементы не соединялись, если игрок не отпускает ктопку мыши, а просто перетаскивает один элемент над другим.

One Answer

Вам помогут методы Physics.OverlapSphere, Physics.OverlapBox, Physics.OverlapCapsule, в 2D скорее всего будет удобнее использовать Physics2D.OverlapCollider или Collider2D.OverlapCollider, хотя методы для сфер, боксов и прочего тоже присутствуют. Так же есть их аналоги с постфиксом NonAlloc, которые не аллоцируют новые массивы. Эти методы возвращают int, который показывает, сколько элементов было изменено в заранее созданном массиве.

Пример использования OverlapSphereNonAlloc

Допустим есть SphereCollider, который вы ставите в инспекторе

public SphereCollider collider;
private Collider[] results = new [10]; // создаем массив, в который будут класться коллайдеры

void CheckColliders()
{
    int resultsAmount = Physics.OverlapSphereNonAlloc(collider.transform.position + collider.center, collider.radius, results);
    // проходимся только по обновленным
    for (int i = 0; i < resultsAmount; i++)
    {
        var colliderInSphere = results[i];
        // делаем что-то дальше
    }
}

Все методы описаны в документации Unity.

https://docs.unity3d.com/ru/current/ScriptReference/Physics2D.html

https://docs.unity3d.com/ScriptReference/Physics.html

Найдите в списке нужный вам.

UPD: Увидел, что у вас 2D. Пример Collider2D.OverlapCollider

https://docs.unity3d.com/ru/current/ScriptReference/Collider2D.OverlapCollider.html

public Collider2D col;
private Collider2D[] results = new Collider2D[10];

void CheckCollider()
{
    ContactFilter2D filter = new ContactFilter2D();
    int resultAmount = col.OverlapCollider(filter.NoFilter(), results);
    
    for (int i = 0; i < resultAmount; i++)
    {
        var colliderInCol = results[i];
    }
}

В вашем случае можно вызывать в OnMouseUp()

Correct answer by luvjungle on January 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP