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

时间:2016-03-15 19:57:28

标签: unity3d unityscript raycasting

我正在制作一个游戏,其中地板由单个实时像素和死像素组成。如果在两点之间绘制一条实时像素线,则传递。如果该行被破坏,则无法通过。

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

enter image description here

目前,我有以下代码,使用RayCasts检查下一个“像素”是活还是死:

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

1 个答案:

答案 0 :(得分:1)

不依赖于Unity物理系统的这个问题的解决方法是将“像素”对象存储在2D数组中,并迭代数组以评估实时像素是否从一侧形成连续路径到另一个。

注意:这假设您在创建/初始化游戏时,将像素对象正确存储在数组中,反映其在游戏中的排列方式。 (即代表他们形成的网格的行和列。)

以下是您的路径验证算法的外观:

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

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

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

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