撰写了文章 更新于 2017-03-24 18:07:51
Devlog 5
[题图:还是坎贝拉太空冒险,对了更新中文了哦!不一起来炸火箭么?]
2d tile 与 UniRx
今天的主题非常技术~
Unity的新2d预览版已经发到Release 3了,我这个游戏正式使用预览版在制作中的,其中最重要的一个特性就是tilemap - 瓦片地图,而瓦片地图中的最为重要的一个便利功能就是智能瓦片,啥是智能瓦片?就是每当你绘制地图时,系统会自动根据周围的瓦片情况来挑选合适的,比如官方有这么一个效果图:
现代地图编辑器和2D引擎都会有这个功能,比如Tiled Map和Gamemaker Studio。而unity的实现方式较为特殊:定制脚本!通过实现TileBase的子类,玩家自己来写智能瓦片的逻辑。
这个方式比起Tiled或者GMS那种编辑器里内置的方案,显然要难上手的多,但是却能给开发者带来完全的掌控力,不仅仅是简单的道路连接或者地形衔接,比如像“创建地板时自动在周围包一圈墙”或者“每种下一棵树,周围四格中随机一格放一个草堆”等等便利的逻辑都可以实现,没有任何限制,全看开发者的需求和脑洞。而这是另外两者无法轻易实现的。
在我的University中,目前用这个方式实现了玩家选框的功能:
编辑器中
运行时
嗯,不论是编辑器中还是运行时,智能瓦片都可以很好的工作。
拼块图
UniRx
Reactive(响应式编程)是个目前非常流行的编程范式,可以说正在席卷各种开发领域,在游戏方面,目前Unity也有了UniRx这个插件来实现Reactive,插件评价也非常好,虽然在国内的应用还非常少。
趁着自己做这个项目,我也尝试转换自己的思路,用Reactive的方式去写这个项目,不过作为小白,一上来就遇到了一些思想上的问题:
private void Start()
{
//更新鼠标当前cell
Observable.EveryUpdate()
.Subscribe(l =>
{
//行为:更新光标位置
CurrentCell = Utils.GetMouseCell(GroundTilemap);
});
//按下建设按钮就进入规划状态
BuildButton.OnClickAsObservable().Subscribe(_ =>
{
CurrentOperateState = OperateState.Planning;
});
//规划状态下的各种处理
Observable.EveryUpdate()
.Where(l => CurrentOperateState == OperateState.Planning)
.Subscribe(_ =>
{
if (Input.GetMouseButtonUp(1))
{
//右键点击回到待机状态
ClearGroundPreviewCells();
CurrentOperateState = OperateState.Idle;
}else if (!Input.GetMouseButton(0))
{
//单一块预览(鼠标没按下时)
var mouseCell = Utils.GetMouseCell(GroundTilemap);
UpdateGroundPreviewCells(mouseCell, mouseCell);
}else if (Input.GetMouseButtonDown(0))
{
//左键点下时记录起始tile
_cellPlanningStart = CurrentCell;
}else if (Input.GetMouseButton(0))
{
//按住时获取结束tile
_cellPlanningEnd = CurrentCell;
//基于起始位置更新绘制区方块
UpdateGroundPreviewCells(_cellPlanningStart, _cellPlanningEnd);
}
//地表预览层更新要绘制的cell
GroundPreviewLayer.ClearAllTiles();
foreach (var cell in _groundPreviewCells)
{
GroundPreviewLayer.SetTile(cell, GroundPreviewTile);
}
});
}
额,在牛关插代码似乎还是无法着色吧……总之,确实能够按照思路把玩家的各种操作转化为流,然后进行条件筛选,然后注册上各种对应行为。但是遇到两个问题:
1. 多个条件下都要处理,也就是说当流出现分支时要怎么做,这我目前还没研究明白,于是变成了大段的if-else,这样似乎就埋没了Reactive的优势,变得跟Update没什么区别了。
2.对同一个流的多个处理之后,如果其中有的处理希望结束后不要再进别的处理段,要怎么做呢,因为这种“时序问题”,导致好多处不得不引入状态标识或者if-else的,看上去勉勉强强的。
总之下周有空闲时间得好好看看响应式编程的书了。
Yoge 1年前
太昊 [作者] 1年前
Vistaing 1年前
Vistaing 1年前
发布
林云 1年前
啊啊啊啊我想玩University!
发布