不求上进的小菜,写了5年多的逻辑界面功能,把人都写废了。反思顿悟后决定发奋图强,争取在接下来不要混到要饭的场景上。
尴尬的是要饭都没有给c#和unity机会。
本篇内容就如小菜先分享出来的gif一样,探讨的是动态场景地块的内容。
很多国内厂商的mmorpg游戏中,都打着无缝大世界的旗号,我们通常会在这些看似很大的场景中寻找npc做任务对话,或者是割怪升级。那些看起来无边际的大场景真的是一块大场景吗?
想知道答案就往下继续看吧。
动态地块加载原理
使用一定的策略将玩家周身或者玩家视野内的物体渲染出来。
这听起来没什么难度嘛!
涉及到的知识
Bounds
首先是Bounds,这个在很多的地方的别名是AABB包围盒。
它能帮助我们的构造一个六面体的包裹范围。有其大小和中心点供我们设置。
此外它的常用的两个方法。
Contains(Vector3 point) 判断包围盒是否包含某个点
Intersects(Bounds bounds) 是否与另一个Bounds相交
四叉树
这听起来很玄学,经典的四叉树(quad tree)和八叉树(octree)是一种常用的空间剖分方法,它将已知的空间分成四/八个子空间作为节点,每个节点又划分成四/八个子空间,依此递归,直到达到指定深度。在数据存储、数据分析和图像分析的领域使用的也很广泛。
为什么我们一定要用四叉树呢?这是由于四叉树能加快我们查找的速度。由于我们的查找频繁,我们希望我们的查找是高效的,普通的查找方式无非是我们去foreach遍历所有的对象。尽管思维敏捷的伙伴或想到二分查找来节省查找的开销,但这仍不是最高效的方式。
四叉树的优势就在于可以轻松的按照我们的熟悉的坐标系,划分成简单的四个象限。
这让我们的定位缩短了3/4,通过不断的四分我们能很快将数据存取。
搞懂了这些小菜的动态地块加载实际也就没什么难度了。
实现的步骤:
2.构建四叉树数据结构,将按照象限的划分规则,将地块数据存储在四叉树的结构中。
由于插入的数据成员本身也包含空间位置和大小信息,可能出现数据刚好处于节点的边界上的情况。
此时两个节点同时包含该数据,我们就需要把这种情况的物体存放在这两个节点的根上去。
3.构建好角色控制后,通过Bounds检测是否与物体相交,如果相交就将物体Load出来。同时处理好离开视野的那些物体。
接下来是小菜实现的核心类的划分:
INode.cs
BlockNode.cs
SceneMgrTree.cs
这三个类是对四叉树的构建。
将场景物体信息,存入到四叉树中的情况。不断的递归到其子节点去插入。值得注意的便是这跨象限的情况。
触发移动时的更新情形。
在树的数据结构操作中,常规的遍历执行的操作就是递归了,这点不管是二叉树,行为树,各种树……都是通用的。
我们为每个不达树的最大深度的节点都划分四个象限,并设定好每个象限的bounds大小。
由于小菜时间不足,有很多地方都不完善:
一篇关于莫尔顿码的简单入门介绍:
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
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句