升级生成工具
This commit is contained in:
parent
bee7af1732
commit
c5877622c8
@ -78,8 +78,9 @@ namespace MindPowerSdk.Editor
|
||||
for (int i = 0; i < mapEntries.Count; i++)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
mapEntries[i].mapName = EditorGUILayout.TextField("Map 名称", mapEntries[i].mapName);
|
||||
mapEntries[i].resourceDataName = EditorGUILayout.TextField("资源名称", mapEntries[i].resourceDataName);
|
||||
mapEntries[i].mapName = EditorGUILayout.TextField("Map 名称", mapEntries[i].mapName).Replace(".map", "");
|
||||
mapEntries[i].resourceDataName = EditorGUILayout.TextField("资源名称", mapEntries[i].resourceDataName)
|
||||
.Replace(".obj", "");
|
||||
mapEntries[i].isSmoothing = EditorGUILayout.Toggle("对地形平滑处理", mapEntries[i].isSmoothing);
|
||||
if (GUILayout.Button("删除", GUILayout.Width(60)))
|
||||
{
|
||||
@ -176,9 +177,8 @@ namespace MindPowerSdk.Editor
|
||||
foreach (var entry in mapEntries)
|
||||
{
|
||||
// 拼接完整数据路径
|
||||
string mapDataPath = Path.Combine(mapDataFolder, entry.mapName);
|
||||
string resourceDataPath = Path.Combine(resourceDataFolder, entry.resourceDataName);
|
||||
|
||||
string mapDataPath = Path.Combine(mapDataFolder, entry.mapName + ".map");
|
||||
string resourceDataPath = Path.Combine(resourceDataFolder, entry.resourceDataName + ".obj");
|
||||
// 读取地图数据
|
||||
using FileStream fs = File.OpenRead(mapDataPath);
|
||||
BinaryReader reader = new BinaryReader(fs);
|
||||
@ -190,9 +190,68 @@ namespace MindPowerSdk.Editor
|
||||
TerrainGenerator.GenTerrain(map, chunkSize, terrainMaterial, parent.transform, entry.mapName,
|
||||
entry.isSmoothing);
|
||||
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>
|
||||
/// 清除场景中已生成的地图(父物体名称为 GENERATED_MAPS_PARENT)
|
||||
/// </summary>
|
||||
@ -226,20 +285,69 @@ namespace MindPowerSdk.Editor
|
||||
// 遍历每个地图生成的子对象
|
||||
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);
|
||||
if (!Directory.Exists(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,
|
||||
InteractionMode.UserAction);
|
||||
|
||||
Debug.Log($"保存预制体:{prefabPath}");
|
||||
}
|
||||
#else
|
||||
Debug.LogWarning("该功能仅在 Unity Editor 下可用");
|
||||
#endif
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using MindPowerSdk;
|
||||
@ -14,9 +15,10 @@ public static class TerrainGenerator
|
||||
/// <param name="parent">生成的 Terrain 父节点</param>
|
||||
/// <param name="isSmoothing"></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)
|
||||
{
|
||||
List<Texture> textureList = new List<Texture>();
|
||||
// 计算全局高度范围(归一化用)
|
||||
(float globalMin, float globalMax) = ComputeGlobalHeightRange(map);
|
||||
|
||||
@ -55,7 +57,8 @@ public static class TerrainGenerator
|
||||
Debug.LogWarning($"{startX} {startY} {chunkSize}");
|
||||
(Texture2D texNo, Texture2D maskNo) = map.GenTxtNoTexture((short)startX, (short)startY, chunkSize);
|
||||
|
||||
|
||||
textureList.Add(texNo);
|
||||
textureList.Add(maskNo);
|
||||
// 设置每个 tile 在辅助 baked UV 贴图中希望的像素尺寸(建议不小于 4)
|
||||
int cellPixelSize = 7;
|
||||
|
||||
@ -80,7 +83,7 @@ public static class TerrainGenerator
|
||||
GameObject terrainGO = Terrain.CreateTerrainGameObject(terrainData);
|
||||
terrainGO.name = $"terrain_{i}_{j}";
|
||||
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}");
|
||||
// 设置 Terrain 为自定义材质模式,并赋予生成的材质实例
|
||||
Terrain terrainComponent = terrainGO.GetComponent<Terrain>();
|
||||
@ -88,6 +91,8 @@ public static class TerrainGenerator
|
||||
terrainComponent.materialTemplate = matInstance;
|
||||
}
|
||||
}
|
||||
|
||||
return textureList;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user