Создание поля зрения с помощью Raycasts With for loop (Использование Unity C #) - PullRequest
0 голосов
/ 09 января 2019

Код:

        void IdleState ()
    {
    RaycastHit hit;

    for (float i = -ViewWidth; i < ViewWidth; i++)
        { 
            float Iterater = i/20;
            if (Physics.Raycast(transform.position, transform.forward + new Vector3(Iterater,0,0), out hit, ViewRange))
             {
                Debug.DrawRay(transform.position,(transform.forward + new Vector3(Iterater,0,0)).normalized * ViewRange, Color.red);
                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Player"))
                 {
                    FoundPlayer(hit.transform);
                 }
             }
        }

}

Проблема: в Unity я пытаюсь создать поле зрения для искусственного интеллекта противника, рисуя несколько лучевых передач с циклами for. По какой-то причине Raycast делают это: GIF

Я пытался исправить это в течение нескольких дней Пожалуйста, помогите!

Также функция FoundPlayer (), если она вам нужна:

void FoundPlayer  (Transform DetectedObject)
    { 
        float step = TurnSpeed * Time.deltaTime;
        Vector3 Direc = DetectedObject.position - transform.position;
        Vector3 RotMath = Vector3.RotateTowards(transform.forward, Direc,step,0.0f);
        transform.rotation = Quaternion.LookRotation(RotMath);
        Vector3 CurrentRot = transform.eulerAngles;
        transform.rotation = Quaternion.Euler(0,CurrentRot.y,0);
    }

Функция FoundPlayer () просто поворачивает противника по направлению к игроку, когда один из лучевых передач ударил его.

1 Ответ

0 голосов
/ 09 января 2019

Относительно Raycast:

transform.Forward находится в координатах мирового пространства, к которым вы добавляете некоторую долю смещения оси X мирового пространства. То, что вы хотели, это добавить некоторую часть оси X «локального пространства». transform.Right - это преобразование в мировом пространстве локальной оси X. Попробуйте:

var rayDirection = (transform.Forward + (Vector3.Scale(transform.Right, new Vector3(Iterater, 0, 0))).normalized;

Относительно полей обзора:

Если все, что вы хотите сделать, это проверить, какие объекты находятся в поле зрения, начать находить все внутри сферы, а затем отфильтровать эти объекты в пределах соответствующих углов от transform.forward:

float ViewRange = 10;
float hHalfFov = 45; // Horizontal Half-Field of View (Degrees)
float vHalfFov = 45; // Vertical Half-Field of View (Degrees)

void IdleState() {

    // Find all colliders within ViewRange
    var hits = Physics.OverlapSphere(transform.position, ViewRange);

    foreach (var hit in hits) {
        if ( hit.gameObject == this.gameObject ) continue; // don't hit self

        // Check FOV
        var direction = (transform.position - hit.transform.position);
        var hDirn = Vector3.ProjectOnPlane(direction, transform.up).normalized; // Project onto transform-relative XY plane to check hFov
        var vDirn = Vector3.ProjectOnPlane(direction, transform.right).normalized; // Project onto transform-relative YZ plane to check vFov

        var hOffset = Vector3.Dot(hDirn, transform.forward) * Mathf.Rad2Deg; // Calculate horizontal angular offset in Degrees
        var vOffset = Vector3.Dot(vDirn, transform.forward) * Mathf.Rad2Deg; // Calculate vertical angular offset in Degrees

        if (hOffset > hHalfFov || vOffset > vHalfFov) continue; // Outside of FOV

        Debug.DrawLine(transform.position, hit.transform.position, Color.red);

        if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Player")) {
            FoundPlayer(hit.transform);
        }
    }
}
...