专栏首页吹弹牛皮之unity程序设计吹弹牛皮之Unity 动态地块加载

吹弹牛皮之Unity 动态地块加载

不求上进的小菜,写了5年多的逻辑界面功能,把人都写废了。反思顿悟后决定发奋图强,争取在接下来不要混到要饭的场景上。

尴尬的是要饭都没有给c#和unity机会。

本篇内容就如小菜先分享出来的gif一样,探讨的是动态场景地块的内容。

很多国内厂商的mmorpg游戏中,都打着无缝大世界的旗号,我们通常会在这些看似很大的场景中寻找npc做任务对话,或者是割怪升级。那些看起来无边际的大场景真的是一块大场景吗?

想知道答案就往下继续看吧。

动态地块加载原理

使用一定的策略将玩家周身或者玩家视野内的物体渲染出来。

这听起来没什么难度嘛!

涉及到的知识

  1. Bounds unity的包围盒子
  2. 四叉树的数据存取结构

Bounds

首先是Bounds,这个在很多的地方的别名是AABB包围盒。

它能帮助我们的构造一个六面体的包裹范围。有其大小和中心点供我们设置。

此外它的常用的两个方法。

Contains(Vector3 point) 判断包围盒是否包含某个点

Intersects(Bounds bounds) 是否与另一个Bounds相交

四叉树

这听起来很玄学,经典的四叉树(quad tree)和八叉树(octree)是一种常用的空间剖分方法,它将已知的空间分成四/八个子空间作为节点,每个节点又划分成四/八个子空间,依此递归,直到达到指定深度。在数据存储、数据分析和图像分析的领域使用的也很广泛。

为什么我们一定要用四叉树呢?这是由于四叉树能加快我们查找的速度。由于我们的查找频繁,我们希望我们的查找是高效的,普通的查找方式无非是我们去foreach遍历所有的对象。尽管思维敏捷的伙伴或想到二分查找来节省查找的开销,但这仍不是最高效的方式。

四叉树的优势就在于可以轻松的按照我们的熟悉的坐标系,划分成简单的四个象限。

这让我们的定位缩短了3/4,通过不断的四分我们能很快将数据存取。

搞懂了这些小菜的动态地块加载实际也就没什么难度了。

实现的步骤:

  1. 将场景中的所有的地块数据(资源路径,位置,旋转,缩放等)存储起来。场景中不再摆放物块。

2.构建四叉树数据结构,将按照象限的划分规则,将地块数据存储在四叉树的结构中。

由于插入的数据成员本身也包含空间位置和大小信息,可能出现数据刚好处于节点的边界上的情况。

此时两个节点同时包含该数据,我们就需要把这种情况的物体存放在这两个节点的根上去。

3.构建好角色控制后,通过Bounds检测是否与物体相交,如果相交就将物体Load出来。同时处理好离开视野的那些物体。

接下来是小菜实现的核心类的划分:

INode.cs

BlockNode.cs

SceneMgrTree.cs

这三个类是对四叉树的构建。

将场景物体信息,存入到四叉树中的情况。不断的递归到其子节点去插入。值得注意的便是这跨象限的情况。

触发移动时的更新情形。

在树的数据结构操作中,常规的遍历执行的操作就是递归了,这点不管是二叉树,行为树,各种树……都是通用的。

我们为每个不达树的最大深度的节点都划分四个象限,并设定好每个象限的bounds大小。

由于小菜时间不足,有很多地方都不完善:

  1. 使用Morton莫尔顿掩码结合位运算改进四叉树的存取。
  2. 小菜使用的检测仅仅是包围玩家周身的六面体,还可以使用角色的视角范围去判断。
  3. 资源的加载设计上,小菜并没有走心,可以合理的规划异步的加载和删除让资源的加载不会出现突变的峰值。同时也可以设定资源的权重值,让出现频繁的资源更晚的被删除。

一篇关于莫尔顿码的简单入门介绍:

https://www.cnblogs.com/to-sunshine/p/6430485.html

最后是小菜的demo地址:内容有点需要慢慢看。

链接:https://pan.baidu.com/s/1iK0PU8nCB2EPj1e1cO0yqQ

提取码:jqbm

本文分享自微信公众号 - 吹弹牛皮之unity程序设计(gh_4f97f8f53f59),作者:墨竹青书

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 吹弹牛皮之Unity AI决策-行为树

    行为树。小菜最早接触到这个内容的身影是在一款捕鱼游戏的机器人模拟上,模拟玩家登录游戏,进入大厅,发射子弹,退出游戏等过程中的行为。由于最近工作的需要,小...

    用户7698595
  • 吹弹牛皮之Unity 简易版FSM(Lua和Java)设计

    ///////////////////////////////////////////////////////////////////////////////《...

    用户7698595
  • 吹弹牛皮之Unity 引擎基础 - 四元数(一)

    复数对(a,b)定义了数a + bi。其中a称为实部,b称为虚部,i称为虚数,满足i² = -1。对于任意实数都能表示为复数(k, v)= k + vi。

    用户7698595
  • 以太坊多节点私有链部署

    https://g2ex.github.io/2017/09/12/ethereum-guidance/

    飞狗
  • 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    Tencent JCoder
  • LaserTagger: 文本生成任务的序列标注解决方案

    今天要和大家分享的是2019年Google Research的一篇关于文本生成的论文[1],已开源[2]。

    朴素人工智能
  • SQLServer 数据库镜像+复制切换方案

    目标: 主机做了Mirror和Replication,当主机出现问题时,Replication和Mirror实现自动的故障转移(Mirror 和Re...

    逸鹏
  • CVPR 2020 | 基于知识蒸馏的分块监督NAS

    以机器自动设计网络结构为目标的神经网络搜索(NAS,Neural Architecture Search)有望为机器学习带来一场新的革命。

    CV君
  • 测试mktime和localtime_r性能及优化方法

    一见
  • 测试mktime和localtime_r性能及优化方法

    一见

扫码关注云+社区

领取腾讯云代金券