检测Unity中两点之间的所有对象是否具有相同标签

Detect if all objects between two points are of same tag in Unity

我正在制作一个地板由单独的活像素和死像素组成的游戏。如果在两点之间绘制了一条实时像素线,则您通过了。断线就不能通过

我想检测两点之间的所有物体是否都属于同一个标签。这是一张图来尝试说明这一点:

目前,我有以下代码使用 RayCasts 检查下一个 "pixel" 是活的还是死的:

function Update () {

    var pixfwd = transform.TransformDirection (Vector3.up  * Reach);
    var pixbwd = transform.TransformDirection (Vector3.down  * Reach);
    var pixleft = transform.TransformDirection (Vector3.left * Reach);
    var pixright = transform.TransformDirection (Vector3.right * Reach);

    Debug.DrawRay(transform.position, pixfwd * Reach, Color.red, 0.1f);
    Debug.DrawRay(transform.position, pixbwd * Reach, Color.green, 0.1f);
    Debug.DrawRay(transform.position, pixleft * Reach, Color.yellow, 0.1f);
    Debug.DrawRay(transform.position, pixright * Reach, Color.blue, 0.1f);

    Physics.Raycast (transform.position, pixfwd, pixhit);
    Physics.Raycast (transform.position, pixbwd, pixhit2);
    Physics.Raycast (transform.position, pixleft, pixhit3);
    Physics.Raycast (transform.position, pixright, pixhit4);


    if ( checkVision(pixhit)  || checkVision(pixhit2)  || checkVision(pixhit3)  || checkVision(pixhit4) ) { 
        nextisLive = true;
    }
    else
    {   
        nextisLive=false;
    }

}

function checkVision(pixhit:RaycastHit):boolean
{
    if ( pixhit != null && pixhit.collider != null && pixhit.collider.tag == "Live" )
    {
        return true;
    }
    return false;

    if ( pixhit2 != null && pixhit2.collider != null && pixhit2.collider.tag == "Live" )
    {
        return true;
    }
    return false;

    if ( pixhit3 != null && pixhit3.collider != null && pixhit3.collider.tag == "Live" )
    {
        return true;
    }
    return false;

    if ( pixhit4 != null && pixhit4.collider != null && pixhit4.collider.tag == "Live" )
    {
        return true;
    }
    return false;
}

不依赖于 Unity 物理系统的解决此问题的方法是将 "pixel" 对象存储在二维数组中,并遍历该数组以评估活动像素是否形成连续的从一侧到另一侧的路径。

注意:这假设当您 create/initialize 您的游戏时,您正确地将像素对象存储在数组中,反映了它们在游戏中的排列。 (即代表它们形成的网格的行和列。)

以下是您的路径验证算法的大致思路:

var pixels : GameObject[,];

function Start()
{
    // Populate pixels array in here, or when you create the grid if the pixels are
    // created dynamically.
    //
    // Array should be initialized to new GameObject[GRID_WIDTH, GRID_HEIGHT];
    //
    // For this approach, it can be helpful if you group your pixel GameObjects under
    // empty GameObjects that match the structure of the array, as this will make it
    // easier to populate.
    // (Only really applies if you the pixels are not created dynamically.)
}

// Accepts two parameters, which provide the top and bottom of the generator at each
// point.
// 
// (For example, a generator spanning between pixels 0 and 2 in width would be
// represented by new int[]{0, 2})
function CheckForClearPath(startPoint : int[], endPoint : int[])
{
    // For tracking live pixels in last and current column
    var prevColumn : boolean[] = new boolean[pixels[0].length];
    var currColumn : boolean[] = new boolean[pixels[0].length];
    InitializeArray(prevColumn);

    // Iterating through each column of grid
    var x : int = 0;
    for (x = 0; x < pixels.length; x++)
    {
        // Special cases for first and last column
        var isFirstColumn : boolean = (x == 0);
        var isLastColumn : boolean = (x == pixels.length - 1);

        // Iterating through each row of grid column, first to identify live pixels
        // adjacent to previous column's live pixels
        var y : int = 0;
        for (y = 0; y < pixels[x].length; y++)
        {
            if (prevColumn[x]) {
                currColumn[y] = (pixels[x][y].tag == "Live");
            }
            else {
                currColumn[y] = false;
            }
        }

        // Next, iterating through each row of grid column, to identify live pixels
        // adjacent to current column's live pixels
        // 
        // This is done by checking whether current pixel is live, then checking whether
        // next pixel has live tag
        for (y = 0; y < pixels[x].length - 1; y++)
        {
            if (currColumn[y]){
                currColumn[y + 1] = (pixels[x][y].tag == "Live");
            }
        }

        // Check if any pixels are recorded as alive in column - if not, it means that no
        // live pixels were adjacent to last columns live pixels, and path is broken.
        if (AreAllPixelsDead(currColumn)) {
            return false;
        }

        // If first column, check if pixels next to start point are live.
        if (isFirstColumn) {
            if (!DoesPathMeetPoint(startPoint, currColumn)) {
                return false;
            }
        }

        // If last column, check if pixels next to end point are live.
        if (isLastColumn) {
            if (!DoesPathMeetPoint(endPoint, currColumn)) {
                return false;
            }
        }

        // Saving current column results in last column results
        for (x = 0; x < pixels.length; x++)
        {
            prevColumn[x] = currColumn[x];
        }
    }

    // If all goes well, path is valid
    return true;
}

function InitializeArray(arrayRef : boolean[]) {
    for (var i : int = 0; i < arrayRef.length; i++)
    {
        arrayRef[i] = true;
    }
}

function AreAllPixelsDead(arrayRef : boolean[]) {
    for (var i : int = 0; i < arrayRef.length; i++)
    {
        if (arrayRef[i]) {
            return false;
        }
    }
    return true;
}

function DoesPathMeetPoint(point : int[], columnPixels : boolean[]) {
    for (var i : int = 0; i < columnPixels.length; i++)
    {
        if (columnPixels[i] && i >= point[0] && i <= point[1]) {
            return true;
        }
    }
    return false;
}

基本上,该算法会遍历网格的每一列,并确定是否存在与前一列的活动像素相邻的活动像素,以及与这些相邻的活动像素。成功通过此测试意味着网格中的活动像素至少形成一条从一端到另一端的连续路径。 (然后有几个特殊检查以确保路径连接到起点和终点。)

希望对您有所帮助!如果您有任何问题,请告诉我。

免责声明:代码未经测试,但算法逻辑在那里。