• unity动态加载地图瓦片


    效果如下:

    以下为UI结构即具体设置:

    PanelTest设置:

    Center设置:

    Scroll View设置:

    Viewport设置:

    Content设置:

    ImageTempLate设置:

    原理简图:

    代码:

      1 using Common;
      2 using UnityEngine;
      3 using UnityEngine.UI;
      4 
      5 namespace Lugs
      6 {
      7     /// <summary>
      8     /// 图形切割配置
      9     /// </summary>
     10     public class GridData
     11     {
     12         /// <summary>
     13         /// 原始图片的文件
     14         /// </summary>
     15         public string SrcFileName = @"D:_lugsProjectsMapCutterSourceMap.jpg";
     16         /// <summary>
     17         /// 切割后的图片输出目录
     18         /// </summary>
     19         public string OutDirectory = @"D:_lugsProjectsMapCutterRes";
     20         /// <summary>
     21         /// 图片宽度
     22         /// </summary>
     23         public int ImageWidth = 3000;
     24         /// <summary>
     25         /// 图片高度
     26         /// </summary>
     27         public int ImageHeight = 1900;
     28         /// <summary>
     29         /// 格子宽度
     30         /// </summary>
     31         public int GridWidth = 256;
     32         /// <summary>
     33         /// 格子高度
     34         /// </summary>
     35         public int GridHeight = 256;
     36         /// <summary>
     37         /// 切片文件前缀
     38         /// </summary>
     39         public string titlePrefixName = "WorldMap_";
     40         /// <summary>
     41         /// 切片文件扩展名
     42         /// </summary>
     43         public string expandedName = @".jpg";
     44     }
     45 
     46     /// <summary>
     47     /// UI显示的格子结构
     48     /// </summary>
     49     public class GridItem
     50     {
     51         public bool isUsed;
     52         public int index;
     53         public RawImage image;
     54 
     55         GridData data;
     56         public GridItem(RawImage itemTemplate, GridData data)
     57         {
     58             image = GameObject.Instantiate<RawImage>(itemTemplate, itemTemplate.transform.parent);
     59             image.enabled = true;
     60             image.gameObject.SetActive(true);
     61             this.data = data;
     62         }
     63 
     64         public void Clear()
     65         {
     66             isUsed = false;
     67             index = -1;
     68             image.enabled = false;
     69         }
     70 
     71         public void SetInfo(int index, int xGridCount)
     72         {
     73             this.index = index;
     74             isUsed = true;
     75             image.enabled = true;
     76             int x = index % xGridCount;
     77             int y = index / xGridCount;
     78             GameObject obj = image.gameObject;
     79             obj.name = string.Format("[{0},{1}]", x, y);
     80             int width = data.GridWidth;
     81             int height = data.GridHeight;
     82             obj.transform.localPosition = new Vector3(x * width, -y * height);
     83             if ((x + 1) * width > data.ImageWidth)
     84             {
     85                 width = data.ImageWidth - x * width;
     86             }
     87 
     88             if ((y + 1) * height > data.ImageHeight)
     89             {
     90                 height = data.ImageHeight - y * height;
     91             }
     92             image.rectTransform.sizeDelta = new Vector2(width, height);
     93             string imageName = "worldmap_" + (index + 1).ToString("D2");
     94             //Debug.Log("imageName = " + imageName);
     95             ImageAssetItem item = new ImageAssetItem(UIManager.Str_WorldMapTxFolderName, imageName, false, true);
     96             item.LoadImage(() =>
     97             {
     98                 image.texture = item.TexObject;
     99             });
    100         }
    101     }
    102 }

    UI代码:

      1 using System.Collections;
      2 using System.Collections.Generic;
      3 using UnityEngine;
      4 using UnityEngine.UI;
      5 
      6 namespace Lugs
      7 {
      8     public sealed class PanelTest : MonoBehaviour
      9     {
     10         public RawImage RawImage_GridTemplate;
     11         public ScrollRect scrollRect;
     12         public Slider Slider_Scale;
     13         /// <summary>
     14         /// 视口的缩放系数,默认不缩放
     15         /// </summary>
     16         float mScreenRatio = 1.0f;
     17         public float ScreenRatio
     18         {
     19             get
     20             {
     21                 return mScreenRatio;
     22             }
     23             set
     24             {
     25                 mScreenRatio = value;
     26                 Vector2 pos = scrollRect.normalizedPosition;
     27                 pos.x = Mathf.Clamp01(pos.x);
     28                 pos.y = Mathf.Clamp01(pos.y);
     29                 scrollRect.normalizedPosition = pos;
     30             }
     31         }
     32         /// <summary>
     33         /// 可视区域的可滑动的区域大小
     34         /// </summary>
     35         Vector2 scrollRectMoveArea;
     36         /// <summary>
     37         /// 可视区域大小
     38         /// </summary>
     39         Vector2 screenSize;
     40         /// <summary>
     41         /// 扩展的可视区域大小
     42         /// </summary>
     43         Vector2 screenExtendSize;
     44         /// <summary>
     45         /// 可视区域左下角在可滑动区域内的位置
     46         /// </summary>
     47         Vector2 screenLBPosAtMoveArea;
     48         /// <summary>
     49         /// 可视区域右上角在可滑动区域内的位置
     50         /// </summary>
     51         Vector2 screenRTPosAtMoveArea;
     52         /// <summary>
     53         /// 扩展的可视区域左下角在可滑动区域内的位置
     54         /// </summary>
     55         Vector2 screenExtendLBPosAtMoveArea;
     56         /// <summary>
     57         /// 扩展的可视区域右上角在可滑动区域内的位置
     58         /// </summary>
     59         Vector2 screenExtendRTPosAtMoveArea;
     60         /// <summary>
     61         /// 实际可视区域的扩展比例
     62         /// </summary>
     63         float screenExtendRatio;
     64         /// <summary>
     65         /// 地图的尺寸
     66         /// </summary>
     67         Vector2 mapSize;
     68         /// <summary>
     69         /// 铅直方向上的格子数量
     70         /// </summary>
     71         int mYGridCount;
     72         /// <summary>
     73         /// 水平方向上的格子数量
     74         /// </summary>
     75         int mXGridCount;
     76         /// <summary>
     77         /// 格子出现的左下位置
     78         /// </summary>
     79         Vector2 gridLBPos;
     80         /// <summary>
     81         /// 格子出现的右上位置
     82         /// </summary>
     83         Vector2 gridRTPos;
     84         /// <summary>
     85         /// 使用中的UI格子
     86         /// </summary>
     87         List<GridItem> useGridList = new List<GridItem>();
     88         /// <summary>
     89         /// 未使用的UI格子
     90         /// </summary>
     91         List<GridItem> unUsedGridList = new List<GridItem>();
     92         /// <summary>
     93         /// 格子的配置数据
     94         /// </summary>
     95         GridData mGridData = new GridData();
     96         void Start()
     97         {
     98             Init();
     99             OnScrollValueChanged();
    100         }
    101 
    102         void Init()
    103         {
    104             RawImage_GridTemplate.gameObject.SetActive(false);
    105 
    106             mXGridCount = Mathf.CeilToInt(mGridData.ImageWidth * 1.0f / mGridData.GridWidth);
    107             mYGridCount = Mathf.CeilToInt(mGridData.ImageHeight * 1.0f / mGridData.GridHeight);
    108 
    109             mapSize = new Vector2(mGridData.ImageWidth, mGridData.ImageHeight);
    110             screenSize = UIManager.Instance.UIUGUIRootScene.sizeDelta;
    111             scrollRect.content.sizeDelta = mapSize;
    112             scrollRectMoveArea = mapSize - screenSize;
    113             screenExtendRatio = 0.1f;
    114             screenExtendSize = screenSize * screenExtendRatio;
    115             scrollRect.onValueChanged.RemoveAllListeners();
    116             scrollRect.onValueChanged.AddListener(OnScrollValueChanged);
    117         }
    118         void OnScrollValueChanged(Vector2 vec2)
    119         {
    120             OnScrollValueChanged();
    121         }
    122 
    123         void OnScrollValueChanged()
    124         {
    125             //ScrollRect当前在可是区域滑动的比例
    126             float xPox = scrollRect.horizontalNormalizedPosition;
    127             float yPos = scrollRect.verticalNormalizedPosition;
    128 
    129             //视口在可移动区域内的位置
    130             screenLBPosAtMoveArea.x = scrollRectMoveArea.x * xPox;
    131             screenLBPosAtMoveArea.y = scrollRectMoveArea.y * yPos;
    132             screenRTPosAtMoveArea = screenLBPosAtMoveArea + screenSize;
    133 
    134             //扩展视口在可移动区域内的位置
    135             screenExtendLBPosAtMoveArea = screenLBPosAtMoveArea - screenExtendSize;
    136             screenExtendRTPosAtMoveArea = screenRTPosAtMoveArea + screenExtendSize;
    137 
    138             //计算格子出现的位置:左下 右上
    139             gridLBPos.x = Mathf.FloorToInt(screenExtendLBPosAtMoveArea.x / mGridData.GridWidth);
    140             gridLBPos.y = Mathf.FloorToInt(screenExtendLBPosAtMoveArea.y / mGridData.GridHeight);
    141             gridRTPos.x = Mathf.CeilToInt(screenExtendRTPosAtMoveArea.x / mGridData.GridWidth);
    142             gridRTPos.y = Mathf.CeilToInt(screenExtendRTPosAtMoveArea.y / mGridData.GridHeight);
    143 
    144             //分别计算左下格子和右上格子的索引
    145             int iMin = (int)gridLBPos.x;
    146             int iMax = (int)gridRTPos.x;
    147             int jMin = (int)gridLBPos.y;
    148             int jMax = (int)gridRTPos.y;
    149 
    150             //刷新格子
    151             RefreshGrid(iMin, iMax, jMin, jMax);
    152         }
    153 
    154         void RefreshGrid(int iMin, int iMax, int jMin, int jMax)
    155         {
    156             //先全部重置所有格子为 未使用
    157             for (int i = 0; i < useGridList.Count; ++i)
    158             {
    159                 GridItem item = useGridList[i];
    160                 item.isUsed = false;
    161                 unUsedGridList.Add(item);
    162             }
    163 
    164             //整个扩展可视区域内需要的格子数量
    165             int needCount = 0;
    166             for (int i = iMin; i <= iMax; ++i)
    167             {
    168                 for (int j = jMin; j <= jMax; ++j)
    169                 {
    170                     if (i < 0 || i >= mXGridCount || j < 0 || j >= mYGridCount)
    171                     {
    172                         continue;
    173                     }
    174 
    175                     ++needCount;
    176                     //格子在可移动区域的索引
    177                     int index = (mYGridCount - j - 1) * mXGridCount + i;
    178                     for (int k = 0; k < useGridList.Count; ++k)
    179                     {
    180                         GridItem item = useGridList[k];
    181                         if (index == item.index)
    182                         {
    183                             unUsedGridList.Remove(item);
    184                             item.isUsed = true;
    185                             break;
    186                         }
    187                     }
    188                 }
    189             }
    190 
    191             //不够的话补够
    192             for (int i = useGridList.Count; i < needCount; ++i)
    193             {
    194                 GridItem item = GetItem();
    195                 useGridList.Add(item);
    196             }
    197 
    198             //刷新格子的信息
    199             bool isRightInfo = false;
    200             GridItem firstFreeItem = null;
    201             for (int i = iMin; i <= iMax; ++i)
    202             {
    203                 for (int j = jMin; j <= jMax; ++j)
    204                 {
    205                     if (i < 0 || i >= mXGridCount || j < 0 || j >= mYGridCount)
    206                     {
    207                         continue;
    208                     }
    209 
    210                     isRightInfo = false;
    211                     firstFreeItem = null;
    212                     int index = (mYGridCount - j - 1) * mXGridCount + i;
    213                     for (int k = 0; k < useGridList.Count; ++k)
    214                     {
    215                         GridItem item = useGridList[k];
    216 
    217                         if (null == firstFreeItem && !item.isUsed)
    218                         {
    219                             firstFreeItem = item;
    220                         }
    221 
    222                         if (item.isUsed && (index == item.index))
    223                         {
    224                             isRightInfo = true;
    225                             break;
    226                         }
    227                     }
    228 
    229                     if (!isRightInfo)
    230                     {
    231                         if (null != firstFreeItem)
    232                         {
    233                             firstFreeItem.SetInfo(index, mXGridCount);
    234                         }
    235                     }
    236                 }
    237             }
    238         }
    239 
    240         GridItem GetItem()
    241         {
    242             for (int i = unUsedGridList.Count - 1; i >= 0;)
    243             {
    244                 GridItem tmpItem = unUsedGridList[i];
    245                 tmpItem.Clear();
    246                 unUsedGridList.Remove(tmpItem);
    247                 return tmpItem;
    248             }
    249 
    250             GridItem item = new GridItem(RawImage_GridTemplate, mGridData);
    251             return item;
    252         }
    253 
    254         public void OnSliderValueChange()
    255         {
    256             float scale = Slider_Scale.value / Slider_Scale.maxValue;
    257             scrollRect.viewport.localScale = new Vector3(scale, scale, 1);
    258             Rect baseRect = (scrollRect.transform as RectTransform).rect;
    259             scrollRect.viewport.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, baseRect.width / scale);
    260             scrollRect.viewport.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, baseRect.height / scale);
    261             ScreenRatio = 1 / scale;
    262         }
    263     }
    264 }
  • 相关阅读:
    html 输入框 只能输入数字 只能输入字母数字 等组合
    element中table高度自适应问题
    设置千分位问题(改变数据结构形式--转成字符串)
    在element的table接受数据设置千分位问题(不改变数据类型)
    element在使用tab页时,echarts只在第一个页面加载(第二个tab页也在默认tab页显示)问题
    css1
    B/S(Web)实时通讯解决方案
    WebRTC介绍及简单应用
    webpack的编译流程
    01 写一个 mySetInterVal(fn, a, b),每次间隔 a,a+b,a+2b 的时间,然后写一个 myClear,停止上面的 mySetInterVal
  • 原文地址:https://www.cnblogs.com/luguoshuai/p/14081190.html
Copyright © 2020-2023  润新知