Unity3D多人联机——Unet初步了解

Unity3D多人联机——Unet初步了解,第1张

首先在场景中新建一个空物体,添加组件Network Manager 和Network ManagerHUD组件

PlayerPrefab=>客户端加入时自动生成的Prefab

AutoCreatePlayer=>自动生成Prefab。

PlayerSpawnMethod=>Prefab的生成方法,两个选项。使用这个方法首先要有指定的位置。(NetworkStartPosition)

Random=>随机生成

创建角色预制体,添加组件Network Identity

.

给角色添加移动脚本PlayerController

将角色的预制体添加到NetWork Manager/Spawn Info中

构建项目并运行,打开构建的游戏,

点击左上角的LAN Host

再打开Unity,运行程序,点击LAN Client加入游戏

画面中有两个角色(重合),移动角色会发现角色在同时移动

要添加一个判断条件,判断当前角色是否为本地角色

首先,加入UnityEngine.Networking命名空间

其次,将MonoBehaviour改为NetworkBehaviour

最后添加判断条件

再次构建发布并运行,两个角色就可以分开移动了,但是还有个问题:画面不同步

在角色预制体中添加Network Transform

Network Send Rate 每秒的网络更新数

Transform Sync Mode 可以更改同步的组件类型

再次构建运行,可以看到 画面同步了。

一个拼接地块生成随机地图的尝试过程,个人感觉效果不是非常理想,还有许多优化空间,总之先记录一下。

虽说是3D场景,但生成的地图块都在同一个平面上,严格来说依然是2D的思路。对于类似3D地牢的生成,官方已经有一篇文章介绍: 在Unity中程序化生成的地牢环境 。

整体思路:

缺点:

在一个场景中搭建好各类地块:

由于计划要烘焙光照贴图,地块的开口朝向就必须都是固定的,旋转地块、移除墙壁都会导致穿帮。当然也可以设置一些动态的墙壁,需要时通过移除它们来形成开口。

上图搭建好的地块中,右侧两列为主要地块,拥有2~4个方向的开口;中间四个小地块分为横向与竖向,用来连接主要地块;左上角四个为单开口,在地块生成完毕后,用它们来封闭上空余的开口。

地块大致搭完后将它们都做成预制体,进行烘焙。这里使用插件 Unity Lightmap Prefab Baker ,它将整个场景按当前的光照设置进行烘焙,烘焙出的光照贴图移动到指定文件夹,然后通过挂在预制体下的脚本记录关联的光照贴图,当预制体加载到新场景时将它们关联起来。

插件安装好后,每个地块预制体挂上PrefabBaker脚本:

Window ->Prefab Baker 打开面板,调整相应设置后点击烘焙:

默认的光照贴图放在Assets/Resources/Lightmaps目录下,开发阶段可以暂时放在这里。如果2019版本报"Failed to created asset"错误,可尝试修改Plugins/PrefabBaker/Scripts/EditorUtils.cs,在200行:

烘焙完成后:

为了让地块之间的开口能顺利对接上,地块的每个开口处需要放置一个空对象作为连接点,令两个地块的连接点重合即完成拼接。地块还需要有类型,这里分为了Room(房间,单开口), Corridor(走廊,东西或南北开口), Corner(拐角), TShaped(丁字), Hall(大厅,四面开口)。

连接点,Z轴朝向开口方向:

地块预制体:

拼接时需要能获取到地块的连接点情况,加入相关方法:

在一个新场景中生成地图,编写 LevelGenerator.cs 脚本:

先对地块预制体进行分类:

分好类之后开始生成,编写生成地图的方法GenerateLevel,由于需要多次将满足条件的对象放入列表来随机抽取,事先准备好一些列表避免反复创建:

先生成一个初始地块,这里选择走廊作为初始的地块,也可用其他的地块类型:

GetRandom方法:

需要注意新场景中的光照(主要是平行光)需要和烘焙场景保持一致。

当前的算法是逐个拼接生成地块,最后用单开口地块对所有空余的开口进行封闭。为了控制地块数量,当前的地块数量为已生成个数加上即将生成个数。

编写循环生成:

GenerateMatchingCell方法用于寻找与当前地块连接口匹配的地块预制体,找到之后将它们拼接:

要寻找匹配的地块,首先要找到跟当前连接点匹配的连接点类型:

然后在地块预制体中寻找包含这种连接点类型的地块:

效果:

最后GenerateLevel方法中将有空余连接点的地块封口:

效果:

生成较多地块时,会发生冲突:

由于是逐个地块生成,冲突检测只能在要生成下一个地块时进行判断,如果当前连接点前方一段距离内已经存在地块,则该连接点不能用于继续生成,需要封闭;另外,如果连接点前方不存在地块,还需要判断前方的前方、左方、右方是否存在地块,若存在则只能生成开口朝向别处的地块。

每个地块添加碰撞体:

LevelGenerator.cs 加入冲突检测相关配置:

GenerateLevel方法中:

CheckConflict方法:

如果没有直接冲突,按照上面的逻辑判断前方的前方、左方、右方是否存在地块,若存在则记录到不期望的连接类型列表,随后由GenerateMatchingCell传入到GetMatchingCell中:

效果:

Demo项目地址:

Procedural-Map-Demo


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/bake/11663404.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存