//菱形坐标转AOI index public static Vector2 DiamondToAOIIndex(DiamondVector2 pos) { return(AOICoordinates.WorldToAOI(DiamondToWorld(pos))); }
private void OnCameraMove(Vector3 posLB, Vector3 posLT, Vector3 posRT, Vector3 posRB) { //向外扩展的距离,这里和画tile一样,为了让实际范围比显示更大,这样拖动时不会露馅 float extraDis = DiamondCoordinates.w * 2; //算出4个点对应的aoi,然后遍历所有aoi插入 Vector2Int aoiLB = AOICoordinates.WorldToAOI(posLB + new Vector3(-extraDis, 0, -extraDis)); Vector2Int aoiLT = AOICoordinates.WorldToAOI(posLT + new Vector3(-extraDis, 0, extraDis)); Vector2Int aoiRT = AOICoordinates.WorldToAOI(posRT + new Vector3(extraDis, 0, extraDis)); //Vector2Int aoiRB = DiamondCoordinates.WorldToAOI(posRB += new Vector3(extraDis, 0, -extraDis)); newAOIList.Clear(); inActiveList.Clear(); newActiveList.Clear(); for (int x = aoiLT.x; x <= aoiRT.x; x++) { for (int y = aoiLT.y; y <= aoiLB.y; y++) { Vector2Int aoiPos = new Vector2Int(x, y); if (!AOICoordinates.IsValid(aoiPos)) { continue; } //Debug.Log("aoiPos==" + aoiPos); //如果从不活跃变为活跃,则加入新增列表 if (aoiStateBytes[AOICoordinates.AOIToIndex(aoiPos)] == 0) { newActiveList.Add(aoiPos); } newAOIList.Add(aoiPos); } } //将旧的设置为非活跃 foreach (var item in oldAOIList) { aoiStateBytes[AOICoordinates.AOIToIndex(item)] = 0; } //将新的设置为活跃 foreach (var item in newAOIList) { aoiStateBytes[AOICoordinates.AOIToIndex(item)] = 1; } //重新遍历上次数据,查找所有非活跃的,加入非活跃发送列表 foreach (var item in oldAOIList) { if (aoiStateBytes[AOICoordinates.AOIToIndex(item)] == 0) { inActiveList.Add(item); } } //LogHelper.Log(oldAOIList, "oldAOIList=="); //LogHelper.Log(newAOIList, "newAOIList=="); //新的变为旧的 List <Vector2Int> tmp = oldAOIList; oldAOIList = newAOIList; newAOIList = tmp; //如果有新的aoi进入视野或者有旧的移除,就向后台发送通信 if (newActiveList.Count > 0 || inActiveList.Count > 0) { //LogHelper.Log(newactiveList, "newactiveList:"); //LogHelper.Log(inactiveList, "inactiveList:"); EventDispatcher.Singleton.NotifyListener(EventKey.WorldAOIChange, newActiveList, inActiveList, UserModel.Singleton.userId); } }
//正常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); }); } }