代码之家  ›  专栏  ›  技术社区  ›  Rupert Stamp

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

  •  0
  • Rupert Stamp  · 技术社区  · 8 年前

    我在做一个游戏,地板由单独的活像素和死像素组成。如果在两点之间画了一条活像素线,你就通过了。如果线断了,你就不能通过。

    我想检测两点之间的所有对象是否属于同一标签。下面是一张图,试图说明这一点:

    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 回复  |  直到 8 年前
        1
  •  1
  •   Serlite Gandalf StormCrow    8 年前

    解决这个问题的一种不依赖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;
    }
    

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

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

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