Как я могу обнаружить ближайшие GameObject без физики / raycast?

Я пытаюсь обнаружить объект в пределах диапазона с игроком в качестве исходной точки. Как мне найти Transforms из заданной области вокруг игрока без использования коллайдеров или Physics.OverlaptSphere() Я не хочу использовать этот метод, потому что единственная информация, которая мне нужна, - это преобразование ближайших объектов из заданного LayerMask (точнее, положение и вращение) Если бы я использовал физику, мне пришлось бы запускать триггер для каждой точки, которую я считаю ненужной.

Есть ли другой метод поиска ближайших точек, отличный от того, который использует физику?


person Noobie    schedule 18.11.2017    source источник
comment
вы хозяин своей игровой вселенной. вы должны получить их все. вычислите расстояние от вашего игрока до желаемых объектов, и вы настроены - это метод грубой силы. вы можете прикрепить скрипт к желаемым обновлениям и позволить ему вычислить расстояние до игрока, если оно ниже порогового значения, вы уведомите какой-то объект бухгалтера, что вы находитесь в сфере влияния игрока - бухгалтер проверяет свой внутренний список при обновлении и удаляет вещи, которые вышли из этой области ... и т. д. Подумайте об этом и запрограммируйте.   -  person Patrick Artner    schedule 18.11.2017
comment
Разве использование Vector3.Distance для многих точек не является дорогостоящим?   -  person Noobie    schedule 18.11.2017
comment
Вы можете бросать лучи вокруг игрока и видеть, что они намекают на расстоянии xyz. Если вы выбрали подход и возникли проблемы, покажите нам код.   -  person Patrick Artner    schedule 18.11.2017
comment
Или даже не это ... Я думал об этом, но я просто хочу знать, является ли это решением, аналогичным Physics.Overlap (); но без использования физики   -  person Noobie    schedule 18.11.2017
comment
Почему? Вектор, расстояние - это очень простая математика, в этом и хороши компьютеры. Raycast - более сложная математика, поэтому я бы не стал прибегать к этому. Сфера влияния определяет перекрытие (я полагаю) ограничивающих объемов - это сложнее, чем вычисление расстояния между двумя трехмерными точками.   -  person Patrick Artner    schedule 18.11.2017
comment
У вас есть миллионы предметов? Судя по маске слоя, я понял, что объектов будет немного, так что все будет в порядке. Закодируйте его, попробуйте, если он слишком медленный, отправьте код и получите помощь в его оптимизации.   -  person Patrick Artner    schedule 18.11.2017
comment
Хмм хорошо! Это удовлетворительный ответ. Спасибо!   -  person Noobie    schedule 18.11.2017


Ответы (1)


Если вы хотите сделать это без физики или коллайдеров, получите доступ ко всем объектам. Прокрутите их, проверьте слой и, если они совпадают, используйте Vector3.Distance для сравнения расстояния до каждого объекта. Вернуть результат.

List<GameObject> findNearObjects(GameObject targetObj, LayerMask layerMask, float distanceToSearch)
{
    //Get all the Object
    GameObject[] sceneObjects = UnityEngine.Object.FindObjectsOfType<GameObject>();

    List<GameObject> result = new List<GameObject>();

    for (int i = 0; i < sceneObjects.Length; i++)
    {
        //Check if it is this Layer
        if (sceneObjects[i].layer == layerMask.value)
        {
            //Check distance
            if (Vector3.Distance(sceneObjects[i].transform.position, targetObj.transform.position) < distanceToSearch)
            {
                result.Add(sceneObjects[i]);
            }
        }
    }
    return result;
}

Это можно улучшить, используя Scene.GetRootGameObjects для получения всех GameObjects, но он не возвращает объекты, помеченные как DontDestroyOnLoad.

Расширен как функция расширения:

public static class ExtensionMethod
{
    public static List<GameObject> findNearObjects(this GameObject targetObj, LayerMask layerMask, float distanceToSearch)
    {
        GameObject[] sceneObjects = UnityEngine.Object.FindObjectsOfType<GameObject>();
        List<GameObject> result = new List<GameObject>();
        for (int i = 0; i < sceneObjects.Length; i++)
            if (sceneObjects[i].layer == layerMask.value)
                if (Vector3.Distance(sceneObjects[i].transform.position, targetObj.transform.position) < distanceToSearch)
                    result.Add(sceneObjects[i]);
        return result;
    }
}

Использование:

List<GameObject> sceneObjects = gameObject.findNearObjects(layerMask, 5f);
person Programmer    schedule 18.11.2017