1下载地图
(1)下载全能电子地图(已无法下载google地图,可以用这个下载器)
网上有很多可以下到的地方,这里不再放链接
(2)选择区域和级别进行下载
选择区域
选择地图级别
选择保存位置
下载地图
(3)查看地图比例尺
在下载器的右下角,我们可以看到当前地图的级别以及该级别对应的每像素的距离
2在Unity中导入地图
将下载的地图目录导入到Unity的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源代码