下載Google瓦片地圖並在Unity中作爲場景底圖

1下載地圖

(1)下載全能電子地圖

	網上有很多可以下到的地方,這裏不再放鏈接

(2)選擇區域和級別進行下載

	選擇區域
	選擇地圖級別
	選擇保存位置
	下載地圖

全能電子地圖下載器

(3)查看地圖比例尺

	在下載器的右下角,我們可以看到當前地圖的級別以及該級別對應的每像素的距離

查看地圖級別和比例尺信息

2在Unity中導入地圖

	將下載的地圖目錄導入到Unity的Resources文件夾中

將圖片導入Resources文件夾

3設置參數

	打開“Tools/Google瓦片地圖生成器”
	在彈出的窗口中設置參數
	【需要注意瓦片地圖地址和材質保存地址都必須在當前工程目錄下才行,如果需要放置到其他路徑,可以進行進一步開發】

設置地圖生成器參數

4生成底圖

	點擊“生成地圖瓦片”按鈕,可能需要等待較長時間才能完成。

5全部源碼

(1)EditorWindow界面

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class GenerateGoogleMapWindow : EditorWindow
{
    string googleMapPosition;
    string GoogleMapPosition
    {
        set
        {
            if (googleMapPosition != value)
            {
                googleMapPosition = value;
                GenerateGoogleMapController.GetAllTextures(value);
                //解決每次路徑選擇完畢後在點擊其他輸入框時才顯示出選擇路徑的問題
                GoogleMapPosition = GoogleMapPosition;
                ClickButtonState = false;
            }
        }
        get
        {
            return googleMapPosition;
        }
    }
    string GenerateMaterialPosition = "";

    float lengthPerPixel;
    float LengthPerPixel
    {
        set
        {
            if (lengthPerPixel != value)
            {
                lengthPerPixel = value;
                LengthPerPixel = LengthPerPixel;
                ClickButtonState = false;
                GenerateGoogleMapController.LengthPerPixel = value;
            }
        }
        get
        {
            return lengthPerPixel;
        }
    }

    string LengthPerPixelString = "";

    string MapObjectName = "GeneratedMaps";


    string ClickGenerateButtonTipInfo = "";


    bool ClickButtonState = false;

    void OnInspectorUpdate() //更新
    {
        Repaint();  //重新繪製
    }


    GenerateGoogleMapWindow()
    {
        this.titleContent = new GUIContent("Google瓦片地圖生成器");
    }


    [MenuItem("Tools/Google瓦片地圖生成器")]
    private static void GenerateGoogleMap()
    {
        EditorWindow.GetWindow(typeof(GenerateGoogleMapWindow));
    }


 

    private void OnGUI()
    {
        GUILayout.BeginVertical();

        GUILayout.Space(10);

        GUIStyle titleStyle = new GUIStyle();
        titleStyle.fontSize = 20;
        titleStyle.alignment = TextAnchor.MiddleCenter;
        GUILayout.Label("Google瓦片地圖生成器", titleStyle);

        GUILayout.Space(10);


        #region 選擇瓦片地圖地址
        GUILayout.BeginHorizontal();
        GUILayout.Label("瓦片地圖地址:", GUILayout.Width(75));
        GoogleMapPosition = EditorGUILayout.TextField("", GoogleMapPosition);
        if (GUILayout.Button("...",GUILayout.Width(30)))
        {
            GoogleMapPosition = EditorUtility.OpenFolderPanel("選擇瓦片地圖地址", UnityEngine.Application.dataPath, "");
        }
        GUILayout.EndHorizontal();




        GUIStyle TipInfoStyle = new GUIStyle();
        TipInfoStyle.alignment = TextAnchor.MiddleCenter;
        if (GenerateGoogleMapController.AllMapTextures != null && GenerateGoogleMapController.AllMapTextures.Count != 0 && GenerateGoogleMapController.AllMapTextures[0] != null && GenerateGoogleMapController.AllMapTextures[0].Count != 0)
        {
            TipInfoStyle.normal.textColor = Color.blue;
            GUILayout.Space(5);
            GUILayout.Label("共檢索到" + GenerateGoogleMapController.AllMapTextures.Count + "x" + GenerateGoogleMapController.AllMapTextures[0].Count + " = " + GenerateGoogleMapController.AllMapTextures.Count * GenerateGoogleMapController.AllMapTextures[0].Count + "張瓦片" + "    瓦片分辨率爲:" + GenerateGoogleMapController.AllMapTextures[0][0].Map.width + "x" + GenerateGoogleMapController.AllMapTextures[0][0].Map.height, TipInfoStyle);
            GenerateGoogleMapController.MapSize = new Vector2(GenerateGoogleMapController.AllMapTextures[0][0].Map.width, GenerateGoogleMapController.AllMapTextures[0][0].Map.height);
            GUILayout.Space(5);
            TipInfoStyle.normal.textColor = Color.red;
        }
        else
        {
            TipInfoStyle.normal.textColor = Color.red;
            GUILayout.Space(5);
            GUILayout.Label("未檢索到瓦片!",TipInfoStyle);
            GUILayout.Space(5);
        }


        #endregion

        GUILayout.BeginHorizontal();

        GUIStyle TextFieldStyle = new GUIStyle(EditorStyles.label);

        bool inputError = false;
        GUILayout.Label("每像素代表的實際距離:", GUILayout.Width(120));

        LengthPerPixelString = EditorGUILayout.TextField("", LengthPerPixelString, GUILayout.Width(50));

        try
        {
            LengthPerPixel = float.Parse(LengthPerPixelString);
            inputError = false;
        }
        catch (System.Exception)
        {
            inputError = true;
        }
        GUILayout.Label("米", GUILayout.Width(15));

        GUILayout.EndHorizontal();

        GUILayout.Space(5);
        if (inputError == true)
        {
            GUILayout.Label("請重新輸入數字!", TipInfoStyle,GUILayout.Width(185));
            GUILayout.Space(5);
        }


        #region 選擇材質保存位置
        GUILayout.BeginHorizontal();

        GUILayout.Label("材質保存地址:",GUILayout.Width(75));
        GenerateMaterialPosition = EditorGUILayout.TextField("", GenerateMaterialPosition);

        if (GUILayout.Button("...",GUILayout.Width(30)))
        {
            GenerateMaterialPosition = EditorUtility.OpenFolderPanel("選擇材質保存地址", UnityEngine.Application.dataPath, "");
            GenerateGoogleMapController.MaterialSavePath = GenerateMaterialPosition;
        }



        GUILayout.EndHorizontal();
        #endregion



        
        if (GUILayout.Button("生成地圖瓦片"))
        {
            ClickGenerateButtonTipInfo = "";
            if (string.IsNullOrEmpty(GoogleMapPosition))
            {
                ClickGenerateButtonTipInfo += "請選擇瓦片地圖地址\n";
            }
            if (LengthPerPixel == 0)
            {
                ClickGenerateButtonTipInfo += "請輸入瓦片每像素代表的距離\n";
            }
            if (string.IsNullOrEmpty(GenerateMaterialPosition))
            {
                ClickGenerateButtonTipInfo += "請選擇材質保存地址\n";
            }
            ClickButtonState = true;
            GenerateGoogleMapController.StartGenerateGoogleMap();
        }
        if (!string.IsNullOrEmpty(ClickGenerateButtonTipInfo))
        {
            GUILayout.Label(ClickGenerateButtonTipInfo, TipInfoStyle);
        }
        if (string.IsNullOrEmpty(ClickGenerateButtonTipInfo) && ClickButtonState)
        {
            if (GenerateGoogleMapController.AllMapTextures == null || GenerateGoogleMapController.AllMapTextures.Count == 0 || GenerateGoogleMapController.AllMapTextures[0].Count == 0)
            {
                return;
            }


            GUILayout.Space(5);
            Rect ProcessRect = GUILayoutUtility.GetRect(50, 20);

            float process = GenerateGoogleMapController.CurrentGenerateCountNum / (GenerateGoogleMapController.AllMapTextures.Count * GenerateGoogleMapController.AllMapTextures[0].Count);


            if (process != 1f)
            {
                EditorGUI.ProgressBar(ProcessRect, process, "生成進度");
            }
            else
            {
                EditorGUI.ProgressBar(ProcessRect, process, "完成");
            }
        }

        GUILayout.EndVertical();

        GUILayout.FlexibleSpace();

    }
}

(2)地圖生成

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

/// <summary>
/// Google地圖生成器
/// 在Editor中執行
/// </summary>
//[ExecuteInEditMode]
public class GenerateGoogleMapController : MonoBehaviour
{
    /// <summary>
    /// 地圖大小(像素)
    /// </summary>
    public static Vector2 MapSize;

    /// <summary>
    /// 設置每個像素代表的距離
    /// </summary>
    public static float LengthPerPixel;


    /// <summary>
    /// 材質保存位置
    /// </summary>
    public static string MaterialSavePath;

    /// <summary>
    /// 獲取到的所有貼圖,每一行
    /// </summary>
    public static List<List<MapProperty>> AllMapTextures = new List<List<MapProperty>>();


    /// <summary>
    /// 當前生成的瓦片數量
    /// </summary>
    public static int CurrentGenerateCountNum = 0;


   



    /// <summary>
    /// 生成地圖瓦片
    /// </summary>
    public static void StartGenerateGoogleMap()
    {
        CurrentGenerateCountNum = 0;
        GameObject container = GameObject.Find("GenerateMapContainer");
        if (container != null)
        {
            //刪除Scene已有的地圖瓦片
            DestroyChildren(container.transform);
        }
        else
        {
            container = new GameObject("GenerateMapContainer");
        }

        //有多少列——每行有多少個
        int ColumnCount = AllMapTextures.Count;

        //按列生成
        for (int column = 0; column < ColumnCount; column++)
        {

            //有多少行
            int RowCount = AllMapTextures[column].Count;

            //生成每一列的父物體
            GameObject parentObj = new GameObject(AllMapTextures[column][0].MapName.Split('_')[0]);
            parentObj.transform.SetParent(container.transform);

            //生成每一列中的子物體
            for (int Row = 0; Row < RowCount; Row++)
            {
                GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Plane);
                obj.transform.SetParent(parentObj.transform);
                //設置瓦片大小
                obj.transform.localScale = new Vector3(MapSize.x * LengthPerPixel / 10.0f, 1, MapSize.y * LengthPerPixel / 10.0f);
                //設置瓦片位置
                obj.transform.localPosition = -new Vector3(
                    (column + 0.5f - ColumnCount / 2.0f) * obj.transform.localScale.x,
                    0,
                    (RowCount / 2.0f - Row - 0.5f) * obj.transform.localScale.z) * 10f;
                //生成瓦片材質
                Material material = CreateMaterail(AllMapTextures[column][Row].MapName, AllMapTextures[column][Row].Map,
                    MaterialSavePath.Remove(0, MaterialSavePath.IndexOf("Assets")) + "\\" + AllMapTextures[column][Row].MapName + ".mat");
                //爲瓦片物體賦值材質
                obj.GetComponent<Renderer>().material = material;
                //改變瓦片名稱
                obj.name = material.name;

                CurrentGenerateCountNum++;
                //Debug.Log(column + ":" + Row);
            }
        }

    }

    /// <summary>
    /// 獲取指定路徑下的所有貼圖(地圖瓦片)
    /// </summary>
    /// <param name="mapPath"></param>
    public static void GetAllTextures(string mapPath)
    {
        if (string.IsNullOrEmpty(mapPath))
        {
            Debug.LogError("請輸入路徑!");
            return;
        }
        AllMapTextures = new List<List<MapProperty>>();

        DirectoryInfo directoryInfo = null;

        //獲取路徑下的所有文件夾
        try
        {
            directoryInfo = new DirectoryInfo(mapPath);
        }
        catch (Exception)
        {
            directoryInfo = null;
        }

        if (directoryInfo == null)
        {
            Debug.LogError("目錄不存在!");
            return;
        }

        DirectoryInfo[] dirs = null;

        try
        {
            dirs = directoryInfo.GetDirectories();
        }
        catch (Exception)
        {
            Debug.LogError("目錄不存在!");
            return;
        }

        if (dirs == null || dirs.Length == 0)
        {
            Debug.LogError("該目錄下不存在存放瓦片的子文件夾!");
            return;
        }


        //遍歷所有目錄
        foreach (var dir in dirs)
        {
            //獲取所有後綴爲jpg的文件(僅遍歷當前目錄,子目錄不遍歷)
            FileInfo[] fileInfos = dir.GetFiles("*.jpg", SearchOption.TopDirectoryOnly);


            List<MapProperty> textures = new List<MapProperty>();

            //獲取當前路徑下的所有Texture並指定AllTextures的屬性
            foreach (var file in fileInfos)
            {
                //Texture texture = AssetDatabase.LoadAssetAtPath<Texture>(file.FullName);

                //刪除當前文件路徑的前部(Assets之前的路徑),從而獲取相對路徑
                string path = file.FullName.Remove(0, file.FullName.IndexOf("Assets"));
                //獲取當前路徑下指定的Texture
                Texture texture = (Texture)AssetDatabase.LoadAssetAtPath(path, typeof(Texture));
                //獲取針對Texture生成的Material的名稱
                string textureSaveName = dir.Name + "_" + file.Name.Replace(".jpg", "");

                //初始化TextureProperty屬性
                MapProperty textureProperty = new MapProperty();
                textureProperty.Map = texture;
                textureProperty.MapName = textureSaveName;

                textures.Add(textureProperty);
            }
            if (textures != null && textures.Count != 0)
                AllMapTextures.Add(textures);
        }

    }

    /// <summary>
    /// 刪除子物體
    /// </summary>
    /// <param name="container">父物體</param>
    private static void DestroyChildren(Transform container)
    {
        Transform[] trs = container.GetComponentsInChildren<Transform>();
        for (int i = trs.Length - 1; i >= 0; i--)
        {
            if (trs[i] != container)
            {
                DestroyImmediate(trs[i].gameObject);
            }
        }
    }


    /// <summary>
    /// 創建材質(Standard材質)
    /// </summary>
    /// <param name="matName">材質名稱</param>
    /// <param name="texture">材質貼圖</param>
    /// <param name="savePath">材質保存位置</param>
    /// <returns></returns>
    private static Material CreateMaterail(string matName, Texture texture, string savePath)
    {
        Material material = new Material(Shader.Find("Standard"));
        material.mainTexture = texture;
        material.SetFloat("_Glossiness", 0f);
        //創建材質
        AssetDatabase.CreateAsset(material, savePath);
        //更新Asset目錄(沒必要每個新生成的材質都刷新Asset目錄)
        //AssetDatabase.Refresh();
        return material;
    }


}

/// <summary>
/// 地圖瓦片屬性
/// </summary>
public class MapProperty
{
    /// <summary>
    /// 貼圖的保存名稱
    /// </summary>
    public string MapName;

    /// <summary>
    /// 貼圖
    /// </summary>
    public Texture Map;
}

6源代碼

GitHub地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章