升级生成工具
This commit is contained in:
parent
bee7af1732
commit
c5877622c8
@ -78,8 +78,9 @@ namespace MindPowerSdk.Editor
|
|||||||
for (int i = 0; i < mapEntries.Count; i++)
|
for (int i = 0; i < mapEntries.Count; i++)
|
||||||
{
|
{
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
mapEntries[i].mapName = EditorGUILayout.TextField("Map 名称", mapEntries[i].mapName);
|
mapEntries[i].mapName = EditorGUILayout.TextField("Map 名称", mapEntries[i].mapName).Replace(".map", "");
|
||||||
mapEntries[i].resourceDataName = EditorGUILayout.TextField("资源名称", mapEntries[i].resourceDataName);
|
mapEntries[i].resourceDataName = EditorGUILayout.TextField("资源名称", mapEntries[i].resourceDataName)
|
||||||
|
.Replace(".obj", "");
|
||||||
mapEntries[i].isSmoothing = EditorGUILayout.Toggle("对地形平滑处理", mapEntries[i].isSmoothing);
|
mapEntries[i].isSmoothing = EditorGUILayout.Toggle("对地形平滑处理", mapEntries[i].isSmoothing);
|
||||||
if (GUILayout.Button("删除", GUILayout.Width(60)))
|
if (GUILayout.Button("删除", GUILayout.Width(60)))
|
||||||
{
|
{
|
||||||
@ -176,9 +177,8 @@ namespace MindPowerSdk.Editor
|
|||||||
foreach (var entry in mapEntries)
|
foreach (var entry in mapEntries)
|
||||||
{
|
{
|
||||||
// 拼接完整数据路径
|
// 拼接完整数据路径
|
||||||
string mapDataPath = Path.Combine(mapDataFolder, entry.mapName);
|
string mapDataPath = Path.Combine(mapDataFolder, entry.mapName + ".map");
|
||||||
string resourceDataPath = Path.Combine(resourceDataFolder, entry.resourceDataName);
|
string resourceDataPath = Path.Combine(resourceDataFolder, entry.resourceDataName + ".obj");
|
||||||
|
|
||||||
// 读取地图数据
|
// 读取地图数据
|
||||||
using FileStream fs = File.OpenRead(mapDataPath);
|
using FileStream fs = File.OpenRead(mapDataPath);
|
||||||
BinaryReader reader = new BinaryReader(fs);
|
BinaryReader reader = new BinaryReader(fs);
|
||||||
@ -190,9 +190,68 @@ namespace MindPowerSdk.Editor
|
|||||||
TerrainGenerator.GenTerrain(map, chunkSize, terrainMaterial, parent.transform, entry.mapName,
|
TerrainGenerator.GenTerrain(map, chunkSize, terrainMaterial, parent.transform, entry.mapName,
|
||||||
entry.isSmoothing);
|
entry.isSmoothing);
|
||||||
Debug.Log($"生成地图:{entry.mapName}\n数据路径:{mapDataPath}\n资源路径:{resourceDataPath}");
|
Debug.Log($"生成地图:{entry.mapName}\n数据路径:{mapDataPath}\n资源路径:{resourceDataPath}");
|
||||||
|
|
||||||
|
CreateMapObject(resourceDataPath, map, parent.transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CreateMapObject(string objPath, MPMap map, Transform parent)
|
||||||
|
{
|
||||||
|
CSceneObjSet sceneObjSet = new CSceneObjSet();
|
||||||
|
sceneObjSet.LoadBin("Assets/Resources/sceneobjinfo.bin");
|
||||||
|
|
||||||
|
SceneObjFile sceneObjFile = new SceneObjFile();
|
||||||
|
sceneObjFile.Load(objPath);
|
||||||
|
string objName = Path.GetFileNameWithoutExtension(objPath);
|
||||||
|
GameObject root = new GameObject($"{objName}_SceneAssetsRoot");
|
||||||
|
root.transform.SetParent(parent);
|
||||||
|
for (int y = 0; y < sceneObjFile.FileHeader.SectionCntY; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < sceneObjFile.FileHeader.SectionCntX; x++)
|
||||||
|
{
|
||||||
|
var list = sceneObjFile.objInfos[x, y];
|
||||||
|
if (list is null) continue;
|
||||||
|
|
||||||
|
foreach (var sceneObjInfo in list)
|
||||||
|
{
|
||||||
|
if (sceneObjInfo.GetTypeId() == 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int id = sceneObjInfo.GetID();
|
||||||
|
|
||||||
|
CSceneObjInfo modeInfo = sceneObjSet.Get(id);
|
||||||
|
|
||||||
|
Vector3 pos = new Vector3(sceneObjInfo.X / 100f, sceneObjInfo.HeightOff / 100f,
|
||||||
|
sceneObjInfo.Y / 100f * -1f);
|
||||||
|
float mapHeight = map.GetHeight(pos.x, (sceneObjInfo.Y / 100f));
|
||||||
|
pos.y += mapHeight;
|
||||||
|
|
||||||
|
//Quaternion rot = Quaternion.AngleAxis(sceneObjInfo.YawAngle, Vector3.up);
|
||||||
|
string modePath = "Assets/Resources/Model/Scene/" +
|
||||||
|
Path.GetFileNameWithoutExtension(modeInfo.szDataName) + ".lmo.obj";
|
||||||
|
Object mode = AssetDatabase.LoadAssetAtPath<Object>(modePath);
|
||||||
|
if (mode)
|
||||||
|
{
|
||||||
|
GameObject goModel = (GameObject)GameObject.Instantiate(mode);
|
||||||
|
goModel.transform.position = pos;
|
||||||
|
goModel.transform.localScale = new Vector3(1, 1, -1);
|
||||||
|
Vector3 e = goModel.transform.eulerAngles;
|
||||||
|
goModel.transform.rotation = Quaternion.Euler(e.x, sceneObjInfo.YawAngle, e.z);
|
||||||
|
goModel.name = $"[{id}]{mode.name}";
|
||||||
|
goModel.transform.SetParent(root.transform);
|
||||||
|
// Debug.Log(goModel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError($"mode not found: {modePath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 清除场景中已生成的地图(父物体名称为 GENERATED_MAPS_PARENT)
|
/// 清除场景中已生成的地图(父物体名称为 GENERATED_MAPS_PARENT)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -226,20 +285,69 @@ namespace MindPowerSdk.Editor
|
|||||||
// 遍历每个地图生成的子对象
|
// 遍历每个地图生成的子对象
|
||||||
foreach (Transform mapTransform in parent.transform)
|
foreach (Transform mapTransform in parent.transform)
|
||||||
{
|
{
|
||||||
string prefabPath = "Assets/Prefabs/" + mapTransform.name + ".prefab";
|
if (mapTransform.name.Contains("SceneAssetsRoot"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string folder = EditorUtility.OpenFolderPanel("选择预制体路径", "", "") + $"/{mapTransform.name}/";
|
||||||
|
string prefabPath = folder + mapTransform.name + ".prefab";
|
||||||
|
|
||||||
|
|
||||||
string directory = Path.GetDirectoryName(prefabPath);
|
string directory = Path.GetDirectoryName(prefabPath);
|
||||||
if (!Directory.Exists(directory))
|
if (!Directory.Exists(directory))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(directory);
|
Directory.CreateDirectory(directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string materialDir = Path.GetDirectoryName(prefabPath) + "/Material";
|
||||||
|
if (!Directory.Exists(materialDir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(materialDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
string texturesDir = Path.GetDirectoryName(prefabPath) + "/Textures";
|
||||||
|
if (!Directory.Exists(texturesDir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(texturesDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mapTransform.childCount; i++)
|
||||||
|
{
|
||||||
|
var child = mapTransform.GetChild(i);
|
||||||
|
var terrain = child.GetComponent<Terrain>();
|
||||||
|
var terrainCollider = child.GetComponent<TerrainCollider>();
|
||||||
|
|
||||||
|
|
||||||
|
if (terrain != null)
|
||||||
|
{
|
||||||
|
materialDir = materialDir.Replace(@"\", "/");
|
||||||
|
materialDir = materialDir.Replace(Application.dataPath, "Assets");
|
||||||
|
materialDir = $"{materialDir}/{mapTransform.name}.mat";
|
||||||
|
var terrainDataPath = directory.Replace(@"\", "/");
|
||||||
|
terrainDataPath = terrainDataPath.Replace(Application.dataPath, "Assets");
|
||||||
|
terrainDataPath = $"{terrainDataPath}/{mapTransform.name}.asset";
|
||||||
|
if (File.Exists(materialDir))
|
||||||
|
AssetDatabase.DeleteAsset(materialDir);
|
||||||
|
if (File.Exists(terrainDataPath))
|
||||||
|
AssetDatabase.DeleteAsset(terrainDataPath);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
AssetDatabase.CreateAsset(terrain.materialTemplate, materialDir);
|
||||||
|
AssetDatabase.CreateAsset(terrainCollider.terrainData, terrainDataPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PrefabUtility.SaveAsPrefabAssetAndConnect(mapTransform.gameObject, prefabPath,
|
PrefabUtility.SaveAsPrefabAssetAndConnect(mapTransform.gameObject, prefabPath,
|
||||||
InteractionMode.UserAction);
|
InteractionMode.UserAction);
|
||||||
|
|
||||||
Debug.Log($"保存预制体:{prefabPath}");
|
Debug.Log($"保存预制体:{prefabPath}");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Debug.LogWarning("该功能仅在 Unity Editor 下可用");
|
Debug.LogWarning("该功能仅在 Unity Editor 下可用");
|
||||||
#endif
|
#endif
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using MindPowerSdk;
|
using MindPowerSdk;
|
||||||
@ -14,9 +15,10 @@ public static class TerrainGenerator
|
|||||||
/// <param name="parent">生成的 Terrain 父节点</param>
|
/// <param name="parent">生成的 Terrain 父节点</param>
|
||||||
/// <param name="isSmoothing"></param>
|
/// <param name="isSmoothing"></param>
|
||||||
/// <param name="entryMapName"></param>
|
/// <param name="entryMapName"></param>
|
||||||
public static void GenTerrain(MPMap map, int chunkSize, Material terrainMaterial, Transform parent,
|
public static List<Texture> GenTerrain(MPMap map, int chunkSize, Material terrainMaterial, Transform parent,
|
||||||
string entryMapName, bool isSmoothing = true)
|
string entryMapName, bool isSmoothing = true)
|
||||||
{
|
{
|
||||||
|
List<Texture> textureList = new List<Texture>();
|
||||||
// 计算全局高度范围(归一化用)
|
// 计算全局高度范围(归一化用)
|
||||||
(float globalMin, float globalMax) = ComputeGlobalHeightRange(map);
|
(float globalMin, float globalMax) = ComputeGlobalHeightRange(map);
|
||||||
|
|
||||||
@ -55,7 +57,8 @@ public static class TerrainGenerator
|
|||||||
Debug.LogWarning($"{startX} {startY} {chunkSize}");
|
Debug.LogWarning($"{startX} {startY} {chunkSize}");
|
||||||
(Texture2D texNo, Texture2D maskNo) = map.GenTxtNoTexture((short)startX, (short)startY, chunkSize);
|
(Texture2D texNo, Texture2D maskNo) = map.GenTxtNoTexture((short)startX, (short)startY, chunkSize);
|
||||||
|
|
||||||
|
textureList.Add(texNo);
|
||||||
|
textureList.Add(maskNo);
|
||||||
// 设置每个 tile 在辅助 baked UV 贴图中希望的像素尺寸(建议不小于 4)
|
// 设置每个 tile 在辅助 baked UV 贴图中希望的像素尺寸(建议不小于 4)
|
||||||
int cellPixelSize = 7;
|
int cellPixelSize = 7;
|
||||||
|
|
||||||
@ -80,7 +83,7 @@ public static class TerrainGenerator
|
|||||||
GameObject terrainGO = Terrain.CreateTerrainGameObject(terrainData);
|
GameObject terrainGO = Terrain.CreateTerrainGameObject(terrainData);
|
||||||
terrainGO.name = $"terrain_{i}_{j}";
|
terrainGO.name = $"terrain_{i}_{j}";
|
||||||
terrainGO.transform.parent = terrainMap.transform;
|
terrainGO.transform.parent = terrainMap.transform;
|
||||||
terrainGO.transform.position = new Vector3(startX, globalMin, startY - chunkSize);
|
terrainGO.transform.position = new Vector3(startX, globalMin, startY - chunkSize + 1);
|
||||||
Debug.Log($"terrainGO: {terrainGO.name} | pos: {terrainGO.transform.position}");
|
Debug.Log($"terrainGO: {terrainGO.name} | pos: {terrainGO.transform.position}");
|
||||||
// 设置 Terrain 为自定义材质模式,并赋予生成的材质实例
|
// 设置 Terrain 为自定义材质模式,并赋予生成的材质实例
|
||||||
Terrain terrainComponent = terrainGO.GetComponent<Terrain>();
|
Terrain terrainComponent = terrainGO.GetComponent<Terrain>();
|
||||||
@ -88,6 +91,8 @@ public static class TerrainGenerator
|
|||||||
terrainComponent.materialTemplate = matInstance;
|
terrainComponent.materialTemplate = matInstance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return textureList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user