- 准备工作
- 前言
- ECS专题目录
- ECS更新计划
- 作者的话
如果大佬对ECS版的海克斯无限地图感兴趣,不妨参与进来,欢迎Star/Folk源码 0下载Unity编辑器(2019.1.12f1 or 更新的版本),if(已经下载了)continue; 1克隆:git clone https://github.com/cloudhu/HexMapMadeInUnity2019ECS.git --recurse
或下载Zip压缩包 2如果下载的是压缩包,需要先将压缩包解压。然后将HexMapMadeInUnity2019ECS添加到Unity Hub项目中; 3用Unity Hub打开的开源项目:HexMapMadeInUnity2019ECS,等待Unity进行编译工作; 4打开项目后,启动场景在Scenes目录下,打开AdvancedHexMap场景(优化重构的版本)。
在CSDN偶然发现了Andrew翻译的ECS官方文档,很有参考价值,这里推荐一下!如果之前有看到的话,可以少走不少弯路! 这一篇的河流比较复杂,花了两天时间来做,主要是水平有限,很多东西不理解。最终还是选择先实现出来,效果还可以,原作者的知识点这里就不说了,可以看原文,这里只说下河流的随机算法。
在生成单元的时候,根据单元的海拔来获取源头,毕竟河流的源头一般都是高处,水往低处流嘛。所以我暂时设定一个常量来控制源头的产生,顺便设置河床海拔和水面海拔偏移量的常数,都写在HexMetrics脚本里:
#region River河流
///
/// 河流源头的海拔值
///
public const int RiverSourceElevation = 5;
///
/// 河床海拔偏移量
///
public const float StreamBedElevationOffset = -1.75f;
///
/// 水面海拔偏移量
///
public const float RiverSurfaceElevationOffset = -0.5f;
#endregion
接下来在单元生成系统CellSpawnSystem中计算河流的随机算法,先申请两个容器来保存参数:
//河流的源头
NativeList riverSources = new NativeList(totalCellCount/15,Allocator.Temp);
//流入的河流索引
NativeArray riverIn = new NativeArray(totalCellCount, Allocator.Temp);
//若干代码
//释放内存
riverSources.Dispose();
riverIn.Dispose();
这里使用原生的容器,方便申请内存和释放,河流源头产生的几率大概是2/7,还有一些源头是需要闭源的。首先把第0个单元设置为源头,这样方便去观察生成的效果,0是比较好的参照:
//使第0个单元成为河流的源头
Colors[0] = Color.green;
Elevations[0] = HexMetrics.RiverSourceElevation;
riverSources.Add(0);
之后的每个单元都随机生成,我们只需要观察一个源头即可:
//后面将从服务器获取这些数据,现在暂时随机生成
for (int i = 1; i = HexMetrics.RiverSourceElevation) riverSources.Add(i);
}
这里的i是从1开始的,因为0已经被占位了,如果随机海拔满足河源产生的海拔,就将其索引添加进列表。这样我们手里就有原始数据了,这些数据将成为地图生成的关键,从这里开始,后面的地图都带有一定的必然性。 这里涉及到河流相关的数据,我们保存在Data组件里面:
///
/// 河流数据
///
public struct River : IComponentData
{
///
/// 是否有河流进入
///
public bool HasIncomingRiver;
///
/// 是否有河流出
///
public bool HasOutgoingRiver;
///
/// 流入方向
///
public int IncomingRiver;
///
/// 流出方向
///
public int OutgoingRiver;
}
在计算的时候先初始化这些字段,再通过算法来赋值,下面是出版的算法:
- 大河向东流,所以我们尽量使河流的走向是由西向东,未来地图的东面会做成湖或海;
- 水往低处走,所以流经的单元必然比河源的海拔低;
- 一个单元最多通过一条河流,这是为了使简化算法;
- 优先流向与自身海拔相近的单元,这是为了源远流长,避免过早流入低海拔的单元;
- 如果没有出口,就此闭源,这是为了减少河源,避免河流过短;
基于这些算法,我们来写代码:
//初始化河流数据
bool hasRiver = false;
bool hasOutgoingRiver = false;
bool hasIncomingRiver = false;
int incomingRiver = int.MinValue;
int outgoingRiver = int.MinValue;
//如果当前单元是河源
if (riverSources.Contains(i))
{
hasRiver = true;//河源单元必然有河流
//上一个单元海拔,用来做比较
int lastElevation = int.MinValue;
//从六个方向寻找河床
for (int j = 0; j
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?