Physics.OverlapSphere неправильно определяет коллайдеры - PullRequest
0 голосов
/ 01 ноября 2019

Я делаю миниигру ИИ в Unity для колледжа. Я пытаюсь сделать так, чтобы простые агенты двигались по проходной сетке с помощью рулевого управления. Сейчас я использую рулевое управление Flocking и использую метод, показанный в этой статье .

Проблема, с которой я столкнулся, заключается в том, что функция OverlapSphere не возвращает коллайдеры. правильно, как вы можете видеть на изображении:

Scene

Вот код, который я использую для управления. Значение 8 в вызове Overlap Sphere - это слой, где расположены коллайдеры, используемые для этого управления.

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

public class SteeringFlocking : SteeringAbstract
{
    Move move;
    public uint detection_radius = 5;

    // Start is called before the first frame update
    void Start()
    {
        move = GetComponent<Move>();
    }

    // Update is called once per frame
    void Update()
    {
        Collider[] agents_near = Physics.OverlapSphere(transform.position, detection_radius, 8);

        if (agents_near.Length > 0)
        {
            Vector3 final = Alignment(agents_near) + Cohesion(agents_near) + Separation(agents_near);
            move.AccelerateMovement(final.normalized * move.max_mov_acceleration, priority);
        }

    }

    private Vector3 Alignment(Collider[] agents_near)
    {
        Vector3 result = Vector3.zero;

        for (uint i = 0; i < agents_near.Length; ++i)
        {
            result += agents_near[i].gameObject.GetComponent<Move>().movement;
        }

        result.x /= agents_near.Length;
        result.y /= agents_near.Length;
        result.z /= agents_near.Length;
        result.Normalize();

        return result;
    }

    private Vector3 Cohesion(Collider[] agents_near)
    {
        Vector3 result = Vector3.zero;

        for (uint i = 0; i < agents_near.Length; ++i)
        {
            result += agents_near[i].gameObject.transform.position;
        }

        result.x /= agents_near.Length;
        result.y /= agents_near.Length;
        result.z /= agents_near.Length;
        result = new Vector3(result.x - move.transform.position.x, result.y - move.transform.position.y, result.z - move.transform.position.z);
        result.Normalize();

        return result;
    }

    private Vector3 Separation(Collider[] agents_near)
    {
        Vector3 result = Vector3.zero;

        for (uint i = 0; i < agents_near.Length; ++i)
        {
            result += agents_near[i].gameObject.transform.position - move.transform.position;
        }

        result.x /= agents_near.Length;
        result.y /= agents_near.Length;
        result.z /= agents_near.Length;
        result *= -1;
        result.Normalize();

        return result;
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, detection_radius);
    }
}

Ожидаемый результат - OverlapSphere, правильно возвращающий количество коллайдеров внутри него.

1 Ответ

1 голос
/ 01 ноября 2019

8 в вызове Overlap Sphere - это слой, где расположены коллайдеры, используемые для этого управления.

8 и битовая маска уровня # 8 - это не одно и то же.

8 - это просто 8. Битовая маска слоя # 8 равна 1<<8 или 256.

Кроме того, не похоже, что ваши персонажи находятся не на слое 8, а на слое 0, поэтому, конечно, ваш OverlapSphere вернетсянулевые коллайдеры (если дочерние элементы не находятся на другом слое, скриншот не прояснит это).

Вместо этого вы захотите:

Collider[] agents_near = Physics.OverlapSphere(transform.position, detection_radius, 1<<8);

Так же, как изменение вашего объекта нана самом деле будет на уровне 8 (хотя я бы выбрал другое, поскольку Unity имеет жестко запрограммированное имя слоя 8 как Post Processing, которое не имеет контекстного значения, которое вы хотите для своих целей).

ИЛИ

Collider[] agents_near = Physics.OverlapSphere(transform.position, detection_radius, 1<<0); //cast against layer 0.

См .: Слои .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...