说明:

简单总结一下深度优先算法和广度优先算法在Unity中最直观和最多见的使用。这里我所举的例子是应用到Unity中3D 人物的全部骨骼关键的遍历,推广开就是能够对全部物体的层级关系进行简单的遍历。。。算法

数据结构中的树的遍历在Unity中最直观的表现就是对某物体的全部子物体的遍历关系。数据结构

以下所示就是对Unity全部子物体层级的转换出的数据结构(树)3d

深度优先遍历:

深度优先遍历是按照树(图)的深度遍历的一种遍历算法。主要是基于深度优先,既是从某一节点V做为起始节点开始进行遍历,当V的的某一边里全部都遍历事后,回溯到起始节点V,而后继续对另外一条边进行遍历,直至全部节点被遍历完成为止。
如上图所示的树,深度优先的遍历方式为:
  1. A做为Root结点,第一个被访问,而后依次访问B、E、K,当这条路走完后,接着访问L,而后访问F,这样就表明第一条边被访问完成;
  2. 而后回溯到A,依次访问C、G
  3. 最后在回溯到A,依次访问D、H、M、I、J
在Unity中深度遍历全部子物体以下所示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 深度优先
/// </summary>
public class DepthFirst : MonoBehaviour
{
//用于存储所遍历到的物体
List<Transform> DepthFirstList = new List<Transform>(); void Start()
{
DepthFirst_0(transform);
//打印序列
foreach (var item in DepthFirstList)
{
Debug.Log(item);
}
} void DepthFirst_0(Transform tran)
{
foreach (Transform item in tran)
{
DepthFirstList.Add(item);
//判断是否存在子物体
if (item.childCount != 0)
{
DepthFirst_0(item);
}
}
}
}
打印结果以下所示:
 

广度优先遍历

广度优先遍历是按照树(图)的广度遍历的一种遍历算法(又称为层次遍历)。主要是基于广度优先,既是某一节点V做为起始节点开始进行遍历,沿着树(图)的层次进行依次遍历,当第N层被遍历完成后,进行第N+1层遍历,当全部节点都比访问后,遍历完成。
如上图所示的树,广度优先的遍历方式为:
  1. A做为Root结点,做为第一层被访问,当第一层访问完成,切到第二层
  2. 而后依次访问第二层:B、C、D,第二层访问完成
  3. 而后依次访问第三层:E、F、G、H、I、J,第三层访问完成
  4. 而后依次访问第四层:K、L、M
  5. 没有第4+1层,遍历完成

在Unity中广度遍历全部子物体以下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 获取全部关键
/// </summary>
public class BreathFirst : MonoBehaviour
{
List<Transform> BreadthFirstList = new List<Transform>();//层次遍历所获得的List /// <summary>
/// 首先把物体的第一层子物体放入一个List,便于以后使用
/// </summary>
void Start()
{
List<Transform> joinsList = new List<Transform>();
foreach (Transform itemJoins in transform)
{
joinsList.Add(itemJoins);
}
BreadthFirst_1(joinsList); foreach (var item in BreadthFirstList)
{
Debug.Log(item);
}
} /// <summary>
/// 递归遍历每一层
/// </summary>
/// <param name="joins"></param>
void BreadthFirst_1(List<Transform> joins)
{
List<Transform> joinsChildListss = new List<Transform>();
foreach (Transform item in joins)
{
BreadthFirstList.Add(item);//将每一层依次放入列表中
if (item.childCount != 0)//判断每一次的序列项是否存在子物体,存在就将全部子物体放入一个新的List
{
foreach (Transform itemss in item)
{
joinsChildListss.Add(itemss);
}
}
}
if (joinsChildListss != null && joinsChildListss.Count != 0)//判断是不是最后一层
BreadthFirst_1(joinsChildListss);
}
}

打印结果以下所示:



深度优先算法结合广度优先算法获取物体全部节点关系

深度优先算法是对物体的深度上进行的遍历,广度优先算法是对物体广度上的遍历,若是当咱们想要获得物体的层级关系(如:文件件的全部层级关系,3D 人物的骨骼关键关系等)时,咱们能够将深度优先结合广度优先便可获得整个层级关系——经过深度优先遍历获取获得每一个节点的深度信息,经过广度优先遍历获取到每一个节点的广度信息。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 获取全部关键
/// </summary>
public class ListOfJoints : MonoBehaviour
{
public Transform HumModel;
int numCount = 0;
List<Transform> BreadthFirstList = new List<Transform>();
Dictionary<Transform, int> BreathFirstDic = new Dictionary<Transform, int>();
List<Transform> DepthFirstList = new List<Transform>();
IEnumerator Start()
{
yield return new WaitForEndOfFrame();
DepthFirst_0(HumModel);
BreadthFirst_0(HumModel);
yield return new WaitForEndOfFrame();
foreach (var item in DepthFirstList)
{
if (BreathFirstDic.ContainsKey(item))
{
string str = "";
for (int i = 0; i < BreathFirstDic[item]; i++)
{
str += " ";
}
Debug.Log(str + item);
}
}
}
void BreadthFirst_0(Transform tran)
{
List<Transform> joinsList = new List<Transform>();
foreach (Transform itemJoins in HumModel)
{
joinsList.Add(itemJoins);
}
BreadthFirst_1(joinsList);
}
void BreadthFirst_1(List<Transform> joins)
{
numCount++;//层数
List<Transform> joinsChildListss = new List<Transform>();
foreach (Transform item in joins)//打印子物体
{
BreadthFirstList.Add(item);
BreathFirstDic.Add(item, numCount);
if (item.childCount != 0)
{
foreach (Transform itemss in item)
{
joinsChildListss.Add(itemss);
}
}
}
if (joinsChildListss != null && joinsChildListss.Count != 0)
BreadthFirst_1(joinsChildListss);
}
void DepthFirst_0(Transform tran)
{
foreach (Transform item in tran)
{
DepthFirstList.Add(item);
if (item.childCount != 0)
{
DepthFirst_0(item);
}
}
} }

深度优先及广度优先在Unity中的应用的更多相关文章

  1. Unity中通过深度优先算法和广度优先算法打印游戏物体名

    前言:又是一个月没写博客了,每次下班都懒得写,觉得浪费时间.... 深度优先搜索和广度优先搜索的定义,网络上已经说的很清楚了,我也是看了网上的才懂的,所以就不在这里赘述了.今天讲解的实例,主要是通过自 ...

  2. python、java实现二叉树,细说二叉树添加节点、深度优先(先序、中序、后续)遍历 、广度优先 遍历算法

    数据结构可以说是编程的内功心法,掌握好数据结构真的非常重要.目前基本上流行的数据结构都是c和c++版本的,我最近在学习python,尝试着用python实现了二叉树的基本操作.写下一篇博文,总结一下, ...

  3. 存储结构与邻接矩阵,深度优先和广度优先遍历及Java实现

    如果看完本篇博客任有不明白的地方,可以去看一下<大话数据结构>的7.4以及7.5,讲得比较易懂,不过是用C实现 下面内容来自segmentfault 存储结构 要存储一个图,我们知道图既有 ...

  4. Python爬虫从入门到放弃(十)之 关于深度优先和广度优先

    网站的树结构 深度优先算法和实现 广度优先算法和实现 网站的树结构 通过伯乐在线网站为例子: 并且我们通过访问伯乐在线也是可以发现,我们从任何一个子页面其实都是可以返回到首页,所以当我们爬取页面的数据 ...

  5. ES系列九、ES优化聚合查询之深度优先和广度优先

    1.优化聚合查询示例 假设我们现在有一些关于电影的数据集,每条数据里面会有一个数组类型的字段存储表演该电影的所有演员的名字. { "actors" : [ "Fred J ...

  6. python 实现图的深度优先和广度优先搜索

    在介绍 python 实现图的深度优先和广度优先搜索前,我们先来了解下什么是"图". 1 一些定义 顶点 顶点(也称为"节点")是图的基本部分.它可以有一个名称 ...

  7. 图的深度优先遍历&广度优先遍历

    1.什么是图的搜索? 指从一个指定顶点可以到达哪些顶点   2.无向完全图和有向完全图 将具有n(n-1)/2条边的无向图称为无向完全图(完全图就是任意两个顶点都存在边). 将具有n(n-1)条边的有 ...

  8. 58.海量bucket优化机制:从深度优先到广度优先

    当buckets数量特别多的时候,深度优先和广度优先的原理,图解 假如我们有如下数据数据:每个演员的每个电影的评论. 现在我们的需求是找到前10名的演员所演的电影的评论.这是一个两层聚合题.     ...

  9. Python之 爬虫(十二)关于深度优先和广度优先

    网站的树结构 深度优先算法和实现 广度优先算法和实现 网站的树结构 通过伯乐在线网站为例子: 并且我们通过访问伯乐在线也是可以发现,我们从任何一个子页面其实都是可以返回到首页,所以当我们爬取页面的数据 ...

  10. python数据结构之图深度优先和广度优先实例详解

    本文实例讲述了python数据结构之图深度优先和广度优先用法.分享给大家供大家参考.具体如下: 首先有一个概念:回溯 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到 ...

随机推荐

  1. nginx平台初探-5

    nginx的请求处理阶段 (90%)   接收请求流程 (99%)   http请求格式简介 (99%) 首先介绍一下rfc2616中定义的http请求基本格式:   Request = Reques ...

  2. C# 开发工具Visual Studio 介绍

    Visual Studio Community (社区版) 这个版本的 Visual Studio 是免费的,具备以前 Professional 版的功能.使用时间有许可限制.它对开源项目和培训.学术 ...

  3. 解决“yarn : 无法加载文件 C:\Users\quber\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本”问题

    1.问题描述 我们在使用yarn命令的时候,可能会出现如下图所示的错误: 2.解决办法 出现此错误的原因是本地计算机上运行你编写的未签名脚本和来自其他用户的签名脚本,可以使用如下命令将计算机上的执行策 ...

  4. [白话解析] 通俗解析集成学习之GBDT

    [白话解析] 通俗解析集成学习之GBDT 目录 [白话解析] 通俗解析集成学习之GBDT 0x00 摘要 0x01 定义 & 简述 1. GBDT(Gradient Boosting Deci ...

  5. JWT权限验证,兼容多方式验证

    前言 许久没写博文了,整合下这段时间所学吧,前进路上总要停下来回顾下学习成果. 本篇记录下项目的权限验证,WebApi项目中用权限验证来保证接口安全总是需要的,然而权限验证的方式多种多样,博主在项目中 ...

  6. Git 远程仓库地址修改了怎么办?

    项目迁移了一波仓库地址,从自建的git-lab到gitee,所以远程仓库地址发生了变更. 命令: git remote -v # 查看本地配置的远程仓库地址,针对下图中的origin,有的人起名字可能 ...

  7. Java进阶 - [1-1] 六大设计原则

    不要因为某本书而去读,而是因为这本书让你读起来时常有共鸣而去读. 一.单一职责原则 [术语]:SRP,Single Reposibility Principle [定义]:一个类或者模块只负责完成一个 ...

  8. Angular CLI 源码分析

    准备: 安装 Node.js https://nodejs.org/: 安装 VS Code https://code.visualstudio.com/: 创建文件夹 angular-cli-sou ...

  9. 为什么 退出登录 或 修改密码 无法使 token 失效

    前文说过 token 由 3 个部分组成:分别是 token metadata,payload,signature, 其中 signature 部分是对 payload 的加密,而 payload 当 ...

  10. 分布式锁—4.Redisson的联锁和红锁

    大纲 1.Redisson联锁MultiLock概述 2.Redisson联锁MultiLock的加锁与释放锁 3.Redisson红锁RedLock的算法原理 4.Redisson红锁RedLock ...