unityunity节点遍历之BFS/DFS

Posted 程序员茶馆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unityunity节点遍历之BFS/DFS相关的知识,希望对你有一定的参考价值。

一.应用背景

在unity的Hierachy面板上,节点是以树形结构布局的,有些时候我们需要对节点进行遍历,通常有两种比较常用的遍历方式,一种是从指定节点出发(比如根节点),优先遍历直接相邻的子节点,即广度优先遍历(BFS);另一种是从指定节点出发,一路遍历到叶子节点后再遍历下一节点,即深度优先遍历(DFS)。遍历节点只是一种方式,关键是遍历节点期间我们需要做什么,以及当前节点是否需要继续往下遍历?为此,这里针对unity的Transform进行扩展,如下:

二.核心源码:

BFS核心思想:优先遍历直接相邻的子节点,然后再以同样的方式遍历子节点的子节点,直到叶子节点。

DFS核心思想:顺着子节点的一边,一直往下遍历,直到该边到达叶子节点,再以同样的方式遍历下一子节点。

using System.Collections.Generic;
using UnityEngine;
public static class TransformExtension

    public delegate bool TransformAction(Transform transfrom);
    public static void DFSGetChildren(this Transform transform, TransformAction action)
    
        var childCount = transform.childCount;
        for (var index = 0; index < childCount; index++)
        
            var child = transform.GetChild(index);
            if (action.Invoke(child))
                child.DFSGetChildren(action);
        
    
    public static void BFSGetChildren(this Transform transform, TransformAction action)
    
        var childCount = transform.childCount;
        var transformList = new List<Transform>();
        for (var index = 0; index < childCount; index++)
        
            var child = transform.GetChild(index);
            if (action.Invoke(child))
                transformList.Add(child);
        
        for (var index = 0; index < transformList.Count; index++)
        
            var child = transformList[index];
            child.BFSGetChildren(action);
        
    

三.测试结果:

针对上述扩展方法,这里以两种方式遍历指定节点,并且跳过未激活的子节点,测试源码如下:

using UnityEngine;
using UnityEditor;
public class Test

    [MenuItem("GameObject/SearchNode",priority = 0)]
    static void Search()
    
        var trans = Selection.activeTransform;
        Debug.Log("_____BFS_____");
        trans.BFSGetChildren(child =>
        
            var active = child.gameObject.activeSelf;
            if (active)
            
                Debug.Log(child.name);
            
            return active;
        );
        Debug.Log("_____DFS_____");
        trans.DFSGetChildren(child =>
        
            var active = child.gameObject.activeSelf;
            if (active)
            
                Debug.Log(child.name);
            
            return active;
        );
    

测试结果如下图:

 

以上是关于unityunity节点遍历之BFS/DFS的主要内容,如果未能解决你的问题,请参考以下文章

面试刷题:广度优先搜索BFS | 第91期

hdu 4771 求一点遍历全部给定点的最短路(bfs+dfs)

图的遍历算法:DFSBFS

图的遍历(bfs+dfs)模板

图的创建和遍历(BFS/DFS)

模板 图的遍历 bfs+dfs 图的最短路径 Floyed+Dijkstra