MMO地图传送

2024-09-08 08:12
文章标签 地图 传送 mmo

本文主要是介绍MMO地图传送,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本篇由以下四个点讲解:

创建传送点

传送点配置

编辑器扩展:传送点数据生成

传送协议与实现

创建传送点

建碰撞器触发

//位置归零

建一个传送门cube放到要传送的位置(这个teleporter1是传出的区域

这是从另一张地图传入时的传送门

创建一个脚本TeleporterObject给每个传送cube都绑上脚本

通过脚本,让传送门在编辑器下面还能绘制出来

给每个传送点编号

把特效挂在传送点上

//把野外场景的传送也加上(并把传送门的id改了

碰撞检测

TelePorterObject:OnTriggerEnter

private void OnTriggerEnter(Collider other)
{PlayerInputController playerInputController=other.GetComponent<PlayerInputController>();//传入的对象是否有玩家控制器if(playerInputController!=null&&playerInputController.isActiveAndEnabled){//得到传送点的IDTeleporterDefine teleDefine = DataManager.Instance.Teleporters[this.ID];if(teleDefine==null){//从角儿控制器取得角色character,第几个传送点Debug.LogErrorFormat("TeleporterObject: Character [{0}] Enter Teleporter [{1}] ,But TeleporterDefine not existed", playerInputController.character.Info.Name, this.ID);return;}Debug.LogFormat("TeleporterObject: Character[{0}] Enter Telepoter [{1}:{2}] ",playerInputController.character.Info.Name, teleDefine.ID,teleDefine.Name); ;if(teleDefine.LinkTo>0){if(DataManager.Instance.Teleporters.ContainsKey(teleDefine.LinkTo))MapService.Instance.SendMapTeleporter(this.ID);else Debug.LogErrorFormat("Teleporter ID:{0} LinkID {1} error!",teleDefine.ID,teleDefine.LinkTo);   }}
}

在MapService中发送进入传送点的信息SendMapTeleporter

SendMapTeleporter
public void SendMapTeleport(int teleporterID)
{Debug.LogFormat("MapTeleporterRequest :teleporterID:{0}", teleporterID);NetMessage message = new NetMessage();message.Request = new NetMessageRequest();message.Request.mapTeleport = new MapTeleportRequest();message.Request.mapTeleport.teleporterId = teleporterID;NetClient.Instance.SendMessage(message);
}

向客户端发送有角色进入传送点的信息

message MapTeleportRequest
{int32 teleporterId = 1;
}

只需要传一个传送点id即可(也可以传地图的id,再传送点的id)

 服务端的协议处理MapService:OnMapTeleport

在MapService()中, 

订阅:

     MessageDistributer<NetConnection<NetSession>>.Instance.Subscribe<MapTeleportRequest>(this.OnMapTeleport);

void OnMapTeleport(NetConnection<NetSession> sender,MapTeleportRequest request)
{//得到客户端进行传送点传送的对象Character character=sender.Session.Character;Log.InfoFormat("OnMapTeleporter: characterID:{0}:{1} TeleporterId:{2}", character.Id, character.Data, request.teleporterId);//没有该传送点if(!DataManager.Instance.Teleporters.ContainsKey(request.teleporterId)){Log.WarningFormat("Source TeleporterID[{0}] not existed", request.teleporterId);return;}TeleporterDefine teleportDefine=DataManager.Instance.Teleporters[request.teleporterId]; if(teleportDefine.LinkTo==0||!DataManager.Instance.Teleporters.ContainsKey(teleportDefine.LinkTo)){Log.WarningFormat("Source TeleporterID [{0}] LinkTo ID [{1}] not existed", request.teleporterId, teleportDefine.LinkTo);}//从客户端传过来的传送点数据表teleportDefine.LinkTo:6 //取的key为6 传送目标点TeleporterDefine teleporterDefine1 = DataManager.Instance.Teleporters[teleportDefine.LinkTo];//角色所在的地图,角色离开处理MapManager.Instance[teleportDefine.MapID].CharacterLeave(character);//把新位置信息填充给角色character.Position=teleporterDefine1.Position;character.Direction=teleporterDefine1.Direction;//角色进入新地图MapManager.Instance[teleporterDefine1.MapID].CharacterEnter(sender,character);
}

关于传送点配置表TeleporterDefine:

点击这里查看是否有TeleporterDefine配置表生成

扩展编辑器

MapTool:遍历所有传送点,把里面的世界坐标转换成逻辑坐标存到配置表中

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
using UnityEditor;
using Common.Data;
public class MapTool : MonoBehaviour
{[MenuItem("Map Tools/Export Teleportters")]//扩展功能:staticpublic static void ExportTeleporters(){DataManager.Instance.Load();Scene current=EditorSceneManager.GetActiveScene();string currentScene=current.name;//把当前场景记录下来,并检查有无保存if(current.isDirty){EditorUtility.DisplayDialog("提示", "请先保存当前场景", "确定");return;}List<TeleporterObject> allTeleporters=new List<TeleporterObject>();foreach(var map in DataManager.Instance.Maps){//根据地图里配置名字生成原始路径string sceneFile = "Assets/Levels/" + map.Value.Resource + ".unity";if(!System.IO.File.Exists(sceneFile)){//判断每一个场景文件是否存在Debug.LogWarningFormat("Scene {0} not existed!", sceneFile);continue;}//打开单个场景EditorSceneManager.OpenScene(sceneFile,OpenSceneMode.Single);//检查所有的传送点TeleporterObject[] teleporters=GameObject.FindObjectsOfType<TeleporterObject>();    foreach(var teleporter in teleporters){Debug.Log("传送点ID" + teleporter.ID);if(!DataManager.Instance.Teleporters.ContainsKey(teleporter.ID)){//检查传送点的id在配置表中是否存在EditorUtility.DisplayDialog("错误", string.Format("地图:{0} 中配置的 Teleporter:[{1}]中不存在", map.Value.Resource, teleporter.ID), "确定");return;}TeleporterDefine def=DataManager.Instance.Teleporters[teleporter.ID];if (def.MapID != map.Value.ID){//地图配的mapID是否正确EditorUtility.DisplayDialog("错误", string.Format("地图:{0} 中的配置的Teleporter:[{1}] MapID:{2} 错误", map.Value.Resource,teleporter.ID,def.MapID), "确定");return;}def.Position=GameObjectTool.WorldToLogicN(teleporter.transform.position);def.Direction=GameObjectTool.WorldToLogicN(teleporter.transform.forward);}}//Save逻辑写在DataMangaer下,运行时是不会受影响的DataManager.Instance.SaveTeleporters();EditorSceneManager.OpenScene("Assets/Levels/" + currentScene + ".unity");EditorUtility.DisplayDialog("提示", "传送点导出完成", "确定");}}

把所有传送点的layer改成teleporter;因为角色是Default;Default之间是不可能碰撞的

演示:

传送成功;

 传送请求:1号传送点传送到野外的6号点

//从野外传回主城

5号传送点,传LinkTo2号传送点

//但是在野外的相机没有对着角色;在两个场景的切换时,角色会浮空

//Add:可以在场景切换时做一个Loading进度条掩盖

->Map01只有MainPlayerCamera带过来的相机发挥跟随角色的作用/创建角色时相机已经挂上了

关于到了新的场景中固定UI没有显示

把UIMainCity做成单例

(在加载新场景时UIMainCity会再创建实例

//可以看到现在加载到另一个场景,显示了UIMainCity和MainPlayerCamera以及UIWorldElementManager等;还有一些在每个场景中必要的GameObject:

//它们都是挂了单例脚本的物体

//关于刷新数据

例如小地图的mapImage

//小地图需要在次世界场景下加一个BoundingBox;根据当前角色的位置更新在小地图上的位置

需要将每次切换场景时把角色数据都拉一次进来

在UIMinmap.cs中,只有在启动时才加载了小地图

//在后面的文章会讲到

这篇关于MMO地图传送的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147584

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

全英文地图/天地图和谷歌瓦片地图杂交/设备分布和轨迹回放/无需翻墙离线使用

一、前言说明 随着风云局势的剧烈变化,对我们搞软件开发的人员来说,影响也是越发明显,比如之前对美对欧的软件居多,现在慢慢的变成了对大鹅和中东以及非洲的居多,这两年明显问有没有俄语或者阿拉伯语的输入法的增多,这要是放在2019年以前,一年也遇不到一个人问这种需求场景的。 地图应用这块也是,之前的应用主要在国内,现在慢慢的多了一些外国的应用场景,这就遇到一个大问题,我们平时主要开发用的都是国内的地

Imageview在百度地图中实现点击事件

1.首先第一步,需要声明的全局有关类的引用 private BMapManager mBMapMan; private MapView mMapView; private MapController mMapController; private RadioGroup radiogroup; private RadioButton normalview; private RadioBu

ArcGIS Pro SDK (十三)地图创作 3 特殊图层

ArcGIS Pro SDK (十三)地图创作 3 特殊图层 文章目录 ArcGIS Pro SDK (十三)地图创作 3 特殊图层1 高程表面图层1.1 创建具有地表图层的场景1.2 创建新的高程表面1.3 将自定义高程表面设置为 Z 感知图层1.4 将高程源添加到现有高程表面图层1.5 从地图中获取高程表面图层和高程源图层1.6 查找高程表面图层1.7 移除高程表面图层1.8 从曲面获

激光SLAM如何动态管理关键帧和地图

0. 简介 个人在想在长期执行的SLAM程序时,当场景发生替换时,激光SLAM如何有效的更新或者替换地图是非常关键的。在看了很多Life-Long的文章后,个人觉得可以按照以下思路去做。这里可以给大家分享一下 <br/> 1. 初始化保存关键帧 首先对应的应该是初始化设置,初始化设置当中会保存关键帧数据,这里的对应的关键帧点云数据会被存放在history_kf_lidar当中,这个数据是和

产品地图经典案例,为盲人设计一款闹钟

在产品设计的旅程中,复杂程度往往超乎你的想象。从理解产品设计的初衷,到制定具体目标,再到解决实际问题,这一过程涉及许多环节。以下是如何通过即时设计在线白板高效绘制产品地图,以便更好地进行产品设计的具体示例——为盲人设计一款闹钟。 即时设计在线白板是一个高效便捷的可视化工具,可以帮助团队更好地协作和整理思路。我们将通过实际案例来展示如何使用它绘制产品地图。https://js.design/?so

Uber开发的地图网格化的包h3

通常使用规则化的网格包括三角形,正方形和六边形。三角形或正方形的网格与其相邻的网格中心距离不同,而六边形则没有此种情况,因此,h3使用的是六边形网格. 地图的网格划分以南京为例子 api文档 https://github.com/uber/h3-py https://h3geo.org/docs/community/bindings 在这里插入图片描述h3包地图划分级别,第一列是边长 H3 P

echarts地图绘制并实现下钻功能

本文参考网址 使用echarts地图需要先准备好echarts地图渲染需要的json数据,数据可以从阿里云地址中下载自己需要的,下载之后直接引入即可使用,本文针对全国地图做一个简单的demo 阿里云界面如图 // 1、准备echarts地图容器<div class="map" ref="myChart" style="width:500px;height:500px;"></div>//

geodatatool(地图资源工具)3.8

geodatatool(地图资源工具)3.8(新)修复更新,修复更新包括: 1.优化在线地图多线程下载及用户体验。 注意:在线地图下载与背景地图显示用的是同样的源,所以在线地图是否能下载,可以先测试主地图背景地图是否能展示。如背景地图能展示,则该在线地图也能下载! 在线地图数据源可根据需要添加,且数据下载具有缓存功能,所有在线数据无论访问还是下载。都会在本地缓存。所以

Mapmost让你实现地图标注自由

最近在勤勤恳恳(moyuhaushui)搬砖之余,偶然间看到一个在线古籍图书馆,虽然对文言文阅读的心理障碍不亚于英文阅读理解,但网站中有很多历史图集还是引起了兴趣。比如这幅《水经注图》,顺藤摸瓜的瞧,才理解《水经注图》是以《水经注》为基础绘制的一部历史地理地图集,由清代杨守敬与熊会贞编绘。而我们课本中学过的《三峡》取自《水经注》,由北魏地理学家郦道元所撰,《水经注》名为对《水经》的注解,但实际上是