private void OnLoadOver(GameObject obj, DiamondVector2 pos, string fullPath) { //防止拖动过快导致还没加载完就被移除了,所以如果包含,证明已经被卸载了,则直接归入缓存中 if (earlyRemoveDic.ContainsKey(pos)) { //Debug.Log("earlyRemoveSet==" + fullPath); cacheManager.Put(fullPath, obj); tile2CacheDic.Remove(pos); earlyRemoveDic[pos]--; if (earlyRemoveDic[pos] == 0) { earlyRemoveDic.Remove(pos); } return; } //如果这个位置加载过,并且不是同一个物体,则把之前的删除 if (tile2CacheDic.ContainsKey(pos)) { OnObjectRemove(pos, tile2CacheDic[pos].fullPath); } //Debug.Log("OnLoadOver==" + fullPath); obj.transform.localEulerAngles = new Vector3(0, 180, 0); obj.transform.localScale = Vector3.one; obj.transform.localPosition = DiamondCoordinates.DiamondToWorld(pos); obj.SetActive(true); CacheObjectInfo info = new CacheObjectInfo(); info.obj = obj; info.fullPath = fullPath; tile2CacheDic.Add(pos, info); //Debug.Log("OnLoadOver==" + obj.transform.localPosition); }
private void OnUpdate() { if (UITools.IsRaycastUI()) { return; } if (InputManager.GetMouseButtonDown()) { lastTouchPos = InputManager.GetMousePosition(); } if (InputManager.GetMouseButtonUp()) { if (Vector2.Distance(InputManager.GetMousePosition(), lastTouchPos) <= maxDelta) { Ray ray = camera.ScreenPointToRay(InputManager.GetMousePosition()); //发个射线 float enter = 100.0f; Plane plane = WorldCreator.Singleton.plane; if (plane.Raycast(ray, out enter)) { DiamondVector2 dPos = DiamondCoordinates.WorldToDiamond(ray.GetPoint(enter)); EventDispatcher.Singleton.NotifyListener(EventKey.WorldClickTile, dPos); //暂时没别的需求,直接打开窗口 if (DiamondCoordinates.IsValid(dPos)) { UIManager.Singleton.OpenWindow <UIWorldPopup>(dPos); } } } } }
public override void OnInit() { camera = WorldCreator.Singleton.camera; cameraTf = camera.transform; ScriptBridge.Singleton.AddUpdate(OnUpdate, this); ScriptBridge.Singleton.AddLateUpdate(OnLateUpdate, this); //默认lookat中心点 DiamondVector2 lookAtDPos = new DiamondVector2(DiamondCoordinates.maxX / 2, DiamondCoordinates.maxY / 2); Vector3 worldPos = DiamondCoordinates.DiamondToWorld(lookAtDPos); LookAt(worldPos); }
/// <summary> /// 根据摄像机四个角对应的世界坐标+偏移,遍历所有包括的菱形格子 /// </summary> /// <param name="posLB">摄像机左下角</param> /// <param name="posLT">摄像机左上角</param> /// <param name="posRT">摄像机右上角</param> /// <param name="extraDis">偏移,因为如果卡死视野范围,周围过度会不平滑,而且会有露馅</param> /// <param name="action">事件回调</param> public static void ForeachByWorldPos(Vector3 posLB, Vector3 posLT, Vector3 posRT, float extraDis, Action <DiamondVector2> action) { //从左上角遍历到右下角,由于菱形地图奇数位会有错位的情况,所以这里加了一个Offset去处理偏移 float offset = 0; float halfWeight = DiamondCoordinates.w / 2; float halfHeight = DiamondCoordinates.h / 2; for (float y = posLT.z + extraDis; y >= posLB.z - extraDis; y -= halfHeight) { for (float x = posLT.x - extraDis; x <= posRT.x + extraDis; x += DiamondCoordinates.w) { DiamondVector2 dPos = DiamondCoordinates.WorldToDiamond(new Vector3(x + offset, 0, y)); //无效的点不作处理 if (!DiamondCoordinates.IsValid(dPos)) { continue; } //Debug.Log("worldpos==" + new Vector3(x + offset, 0, y)); action(dPos); } offset = offset == 0 ? halfWeight : 0; } }
private void OnCameraMove(Vector3 posLB, Vector3 posLT, Vector3 posRT, Vector3 posRB) { //思路:将上一帧数据全部设置为卸载,再将本次设置为活跃,回头再遍历一次此列表,判断状态为卸载的即为差集 foreach (var dPos in oldTileList) { WorldDataManager.Singleton.SetTileState(dPos.GetIndex(), WorldTileState.None); } //LogHelper.Output(newTileList, "newTileList1=="); newTileList.Clear(); DiamondCoordinates.ForeachByWorldPos(posLB, posLT, posRT, DiamondCoordinates.w * 2, (dPos) => { //将本次关注全部设置为活跃 //Debug.Log(new Vector3(x + offset, 0, y).ToString() + " " + dPos.ToString()); int index = dPos.GetIndex(); WorldDataManager.Singleton.SetTileState(index, WorldTileState.Active); //Debug.Log("dPos==" + dPos); newTileList.Add(dPos); }); //重新遍历上次数据,查找所有状态为卸载的 //LogHelper.Log(newTileList); foreach (var dPos in oldTileList) { int index = dPos.GetIndex(); if (WorldDataManager.Singleton.GetTileState(index) == WorldTileState.None) { //Debug.LogError(item); GameObject cacheObj = pos2TileObjDic[dPos]; cacheObj.SetActive(false); cacheTileList.Add(cacheObj); pos2TileObjDic.Remove(dPos); //将对应格子上的东西放到缓存列表里 int objectId = WorldDataManager.Singleton.GetObjectId(index); if (objectId > 0) { //Debug.Log("WorldObjectRemove==" + index + "=" + objectIdBytes[index]); EventDispatcher.Singleton.NotifyListener(EventKey.WorldObjectRemove, dPos, WorldDataManager.Singleton.GetObjectResPath(index)); //这里不设置数据层,表现只管表现 } } } //LogHelper.Log(newTileList, "newTileList=="); //LogHelper.Output(loadList, "loadList=="); foreach (var dPos in newTileList) { if (!pos2TileObjDic.ContainsKey(dPos)) { GameObject obj = GetTile(); obj.SetActive(true); obj.transform.localPosition = DiamondCoordinates.DiamondToWorld(dPos); pos2TileObjDic.Add(dPos, obj); int index = dPos.GetIndex(); //如果数据中这个格子有物体,就刷出来 int objectId = WorldDataManager.Singleton.GetObjectId(index); if (objectId > 0) { //用当前最新的数据进行填充 EventDispatcher.Singleton.NotifyListener(EventKey.WorldObjectAdd, dPos, WorldDataManager.Singleton.GetObjectResPath(index)); } } } //LogHelper.Output(newTileList, "newTileList3=="); //新的变为旧的 List <DiamondVector2> tmp = oldTileList; oldTileList = newTileList; newTileList = tmp; }
//正常userid服务端通过session拿,这里因为是模拟所以就客户端发了 private void OnAOIChange(List <Vector2Int> newActiveList, List <Vector2Int> inActiveList, long userId) { //旧的移除 foreach (var item in inActiveList) { if (aoi2UserDic.ContainsKey(item)) { aoi2UserDic[item].Remove(userId); } } //当客户端第一次注册新的aoi时,将新的所有信息返还给客户端 if (newActiveList.Count > 0) { List <WorldDataDto> result = new List <WorldDataDto>(); float halfAOICellWidth = AOICoordinates.aoiCellWidth / 2; //新的添加 foreach (var item in newActiveList) { if (!aoi2UserDic.ContainsKey(item)) { aoi2UserDic.Add(item, new HashSet <long>()); } aoi2UserDic[item].Add(userId); //根据块中心找到4个角 Vector3 worldPos = AOICoordinates.AOIToWorldPos(item); Vector3 posLB = worldPos + new Vector3(-halfAOICellWidth, 0, -halfAOICellWidth); Vector3 posLT = worldPos + new Vector3(-halfAOICellWidth, 0, halfAOICellWidth); Vector3 posRT = worldPos + new Vector3(halfAOICellWidth, 0, halfAOICellWidth); Vector3 posRB = worldPos + new Vector3(halfAOICellWidth, 0, -halfAOICellWidth); //CreateGameObject2(worldPos); //CreateGameObject(posLB); //CreateGameObject(posLT); //CreateGameObject(posRT); //CreateGameObject(posRB); //遍历当前aoi的所有点,发给客户端,实际遍历时比正常aoi大一点,防止边界问题 DiamondCoordinates.ForeachByWorldPos(posLB, posLT, posRT, DiamondCoordinates.w, //DiamondCoordinates.ForeachByWorldPos(posLB, posLT, posRT, 0, (dPos) => { //Debug.Log("ForeachByWorldPos dPos==" + dPos); int index = dPos.GetIndex(); WorldDataDto dto = new WorldDataDto(); dto.index = index; //Demo只做怪物 dto.type = WorldObjectType.Monster; dto.id = objectIdBytes[index]; //50%概率随便随机一个怪,模拟大地图物体会刷新 //dto.id = UnityEngine.Random.Range(0, 2) == 0 ? (byte)0 : (byte)UnityEngine.Random.Range(1, 23); //dto.id = UnityEngine.Random.Range(0, 2) == 0 ? (byte)0 : (byte)UnityEngine.Random.Range(1, 5); //dto.id = dPos.x % 2 == 0 ? (byte)0 : (byte)2; //dto.id = 2; result.Add(dto); }); } //模拟服务器延迟 TimeManager.Singleton.CreateTimerOfDuration((long)(Random.Range(0.2f, 0.5f) * 1000), (arg) => { EventDispatcher.Singleton.NotifyListener(EventKey.WorldServerDataSend, result); }); } }