简体   繁体   English

Physics.OverlapSphere 未正确检测对撞机

[英]Physics.OverlapSphere not detecting colliders correctly

I'm doing an AI "minigame" in Unity for a College Assigment.我正在 Unity 中为大学作业做一个人工智能“迷你游戏”。 I'm trying to make simple agents moving inside a walkable mesh using steerings.我正在尝试使用转向使简单的代理在可行走的网格内移动。 Right now I'm with the Flocking steering and I'm using the method showed in this article .现在我正在使用植绒转向,我正在使用本文中显示的方法。

The problem I'm having is that the OverlapSphere function doesn't return the colliders correctly as you can see in the image:我遇到的问题是 OverlapSphere function 没有正确返回对撞机,如图所示:

场景

Here's the code I'm using for the steering.这是我用于转向的代码。 The 8 in the Overlap Sphere call is the layer where the colliders used for this steering are located. Overlap Sphere 调用中的 8 是用于此转向的碰撞器所在的层。

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);
    }
}

The expected result is the OverlapSphere returning correctly the number of colliders inside it.预期的结果是 OverlapSphere 正确返回了其中的碰撞器数量。

The 8 in the Overlap Sphere call is the layer where the colliders used for this steering are located. Overlap Sphere 调用中的 8 是用于此转向的碰撞器所在的层。

8 and a bitmask of Layer #8 are not the same thing.8层和第 8 层的位掩码不是一回事。

8 is just 8 . 8只是8 A bitmask of layer #8 is equal to 1<<8 or 256. #8 层的位掩码等于1<<8或 256。

Additionally, it does not appear that your characters are not on layer 8, but on layer 0, so of course your OverlapSphere is going to return zero colliders (unless the children are on a different layer, the screenshot did not make that clear).此外,您的角色似乎不是不在第 8 层,而是在第 0 层,所以您的 OverlapSphere 当然会返回零对撞机(除非孩子们在不同的层上,屏幕截图并没有说明清楚)。

You'll want this instead:你会想要这个:

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

As well as changing your object to actually be on Layer 8 (though I would pick a different one, as Unity has hard-coded layer 8's name as Post Processing which does not have the contextual value you want for your purposes).除了将 object 更改为实际位于第 8 层之外(尽管我会选择不同的,因为 Unity 将第 8 层的名称硬编码为Post Processing ,它没有您想要的上下文值)。

OR或者

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

See: Layers .请参阅:图层

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM