362 lines
10 KiB
C#
362 lines
10 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using Framework;
|
|
using Gameplay;
|
|
using LC.Newtonsoft.Json;
|
|
using PhxhSDK.Phxh;
|
|
using UnityEngine;
|
|
using Sirenix.OdinInspector;
|
|
using TGS;
|
|
using UnityEngine.Serialization;
|
|
using Debug = DebugUtil;
|
|
using JsonSerializer = Newtonsoft.Json.JsonSerializer;
|
|
using Object = UnityEngine.Object;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
#endif
|
|
|
|
[ExecuteAlways]
|
|
public class MapSceneEditor : MonoBehaviour
|
|
{
|
|
//#if UNITY_EDITOR
|
|
private const string MAP_DATA_NAME = "MapData";
|
|
|
|
private const float UPP = 100;
|
|
|
|
private TerrainGridSystem _tgs;
|
|
|
|
public TerrainGridSystem TGS => _tgs;
|
|
|
|
public bool HasSetGround => _groundMaterial != null && _groundMaterial.mainTexture != null;
|
|
|
|
public bool HasMap => _mapDataJson != null;
|
|
|
|
public MapData MapData
|
|
{
|
|
get => _mapData;
|
|
set
|
|
{
|
|
if (_mapData != value)
|
|
{
|
|
_mapData = value;
|
|
if (value == null)
|
|
{
|
|
Map = null;
|
|
}
|
|
else
|
|
{
|
|
Map = MapUtils.LoadMap(_tgs, _mapData);
|
|
MapUtils.BindCameraController(_camera, Map);
|
|
var cameraController = _camera.gameObject.GetComponent<CameraController>();
|
|
cameraController.InitializeCameraPosition(initialCameraPosition);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public Map Map { get; private set; }
|
|
|
|
public int Width => _tgs.columnCount;
|
|
|
|
public int Height => _tgs.rowCount;
|
|
|
|
[HideInInspector]
|
|
[SerializeField]
|
|
private Camera _camera;
|
|
|
|
[TableColumnWidth(57, Resizable = false)]
|
|
[PreviewField(Alignment = ObjectFieldAlignment.Center)]
|
|
[AssetList(Path = (Constants.MAP_TEXTURE_PATH_WITHOUT_ASSET))]
|
|
[OnValueChanged("OnMapMaterialChanged")]
|
|
[LabelText("地面图")]
|
|
[SerializeField]
|
|
private Material _groundMaterial;
|
|
|
|
private void OnMapMaterialChanged()
|
|
{
|
|
if (HasSetGround)
|
|
{
|
|
_tgs.GetComponent<MeshRenderer>().sharedMaterial = _groundMaterial;
|
|
ResetMapScale();
|
|
}
|
|
}
|
|
|
|
[LabelText("地图尺寸")]
|
|
[LabelWidth(100)]
|
|
//[ReadOnly]
|
|
[SerializeField]
|
|
[OnValueChanged("OnMapScaleChanged")]
|
|
[ShowIf("HasSetGround")]
|
|
private Vector2 _mapScale;
|
|
|
|
private void OnMapScaleChanged()
|
|
{
|
|
//防止网格上的显示在修改缩放后出现问题
|
|
_tgs.regularHexagons = false;
|
|
var currScale = _tgs.transform.localScale;
|
|
var xRatio = _mapScale.x / currScale.x;
|
|
var yRatio = _mapScale.y / currScale.y;
|
|
var ration = Mathf.Approximately(xRatio, 1) ? yRatio : xRatio;
|
|
_mapScale = currScale * ration;
|
|
_tgs.transform.localScale = new Vector3(_mapScale.x, _mapScale.y, 1);
|
|
_tgs.regularHexagons = true;
|
|
}
|
|
|
|
[Button("重置地图大小")]
|
|
[ShowIf("HasSetGround")]
|
|
private void ResetMapScale()
|
|
{
|
|
if (HasSetGround)
|
|
{
|
|
//防止网格上的显示在修改缩放后出现问题
|
|
_tgs.regularHexagons = false;
|
|
_mapScale = (new Vector2(_groundMaterial.mainTexture.width,
|
|
_groundMaterial.mainTexture.height) / UPP);
|
|
_tgs.transform.localScale = new Vector3(_mapScale.x, _mapScale.y, 1);
|
|
_tgs.regularHexagons = true;
|
|
}
|
|
}
|
|
|
|
[LabelText("网格宽高")]
|
|
[OnValueChanged("OnGridWidthHeightChanged")]
|
|
[HideIf("HasMap")]
|
|
[SerializeField]
|
|
private Vector2Int _gridWidthHeight;
|
|
|
|
private void OnGridWidthHeightChanged()
|
|
{
|
|
_tgs.columnCount = _gridWidthHeight.x;
|
|
_tgs.rowCount = _gridWidthHeight.y;
|
|
}
|
|
|
|
[HideIf("HasMap")]
|
|
[Button("铺满网格")]
|
|
private void FillMapWithGrid()
|
|
{
|
|
var width = GetHexCount(_mapScale.x, _tgs.regularHexagonsWidth, false);
|
|
var height = GetHexCount(_mapScale.y, _tgs.regularHexagonsWidth, true);
|
|
_tgs.rowCount = height;
|
|
_tgs.columnCount = width;
|
|
_gridWidthHeight = new Vector2Int(width, height);
|
|
}
|
|
|
|
[LabelText("摄像机初始视角")]
|
|
[LabelWidth(150)]
|
|
[OnValueChanged("OnInitialCameraPositionChanged")]
|
|
public Vector2Int initialCameraPosition;
|
|
|
|
private void OnInitialCameraPositionChanged()
|
|
{
|
|
if (_camera != null && HasMap)
|
|
{
|
|
initialCameraPosition.x = Math.Clamp(initialCameraPosition.x, 0, Height - 1);
|
|
initialCameraPosition.y = Math.Clamp(initialCameraPosition.y, 0, Width - 1);
|
|
var cameraController = _camera.gameObject.GetComponent<CameraController>();
|
|
if (_mapData != null)
|
|
_mapData.initialCameraPosition = initialCameraPosition;
|
|
cameraController.InitializeCameraPosition(initialCameraPosition);
|
|
}
|
|
}
|
|
|
|
public TextAsset MapDataJson
|
|
{
|
|
get => _mapDataJson;
|
|
private set
|
|
{
|
|
var data = JsonToMapData(value);
|
|
if (CheckMapData(data))
|
|
{
|
|
_mapDataJson = value;
|
|
MapData = data;
|
|
}
|
|
else
|
|
{
|
|
_mapDataJson = null;
|
|
MapData = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
[LabelText("地图数据")]
|
|
[ShowIf("HasSetGround")]
|
|
[OnValueChanged("OnMapDataJsonChanged")]
|
|
[SerializeField]
|
|
private TextAsset _mapDataJson;
|
|
|
|
[Space]
|
|
[HideLabel]
|
|
[ShowIf("HasMap")]
|
|
[SerializeField]
|
|
private MapData _mapData;
|
|
|
|
private void OnMapDataJsonChanged(TextAsset k_mapDataJson)
|
|
{
|
|
MapDataJson = k_mapDataJson;
|
|
}
|
|
|
|
[Button("创建地图数据")]
|
|
[ShowIf("HasSetGround")]
|
|
private void CreateMapData()
|
|
{
|
|
#if UNITY_EDITOR
|
|
var scene = gameObject.scene;
|
|
// var scenePath = scene.path;
|
|
var mapDataDir = Path.GetDirectoryName(Constants.MAP_CONFIG_FORMAT_PATH);
|
|
var count = AssetDatabase.FindAssets("t:TextAsset", new[] { mapDataDir }).Length;
|
|
var dataName = $"{scene.name}_{count + 1}";
|
|
var dataPath = $"{mapDataDir}/{dataName}.json";
|
|
using (var fileStream = File.Create(dataPath))
|
|
{
|
|
}
|
|
|
|
AssetDatabase.Refresh();
|
|
var textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(dataPath);
|
|
EditorGUIUtility.PingObject(textAsset);
|
|
if (MapDataJson == null)
|
|
MapDataJson = textAsset;
|
|
#endif
|
|
}
|
|
|
|
private int GetHexCount(float totalLength, float hexWidth, bool isDiagonal)
|
|
{
|
|
if (isDiagonal)
|
|
return Mathf.FloorToInt((4 * totalLength) / (3 * hexWidth) - 1 / 3f);
|
|
else
|
|
{
|
|
var sqrt3 = Mathf.Sqrt(3);
|
|
var countInFloat = (totalLength - (sqrt3 / 4 * hexWidth)) / (Mathf.Sqrt(3) / 2 * hexWidth);
|
|
return Mathf.FloorToInt(countInFloat);
|
|
}
|
|
}
|
|
|
|
private bool CheckMapData(MapData k_mapData)
|
|
{
|
|
if (k_mapData == null)
|
|
return false;
|
|
if (k_mapData.width != Width || k_mapData.height != Height)
|
|
{
|
|
Debug.LogError("当前地图数据宽高和当前地板宽高不匹配!");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private MapData JsonToMapData(TextAsset jsonText)
|
|
{
|
|
if (jsonText != null)
|
|
{
|
|
var jsonStr = jsonText.text;
|
|
if (string.IsNullOrEmpty(jsonStr))
|
|
{
|
|
var mapData = new MapData
|
|
{
|
|
width = Width,
|
|
height = Height
|
|
};
|
|
mapData.ResetBlocks();
|
|
return mapData;
|
|
}
|
|
else
|
|
{
|
|
return JsonConvert.DeserializeObject<MapData>(jsonStr);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
#region MainLife
|
|
|
|
private void OnEnable()
|
|
{
|
|
var objs = Object.FindObjectsOfType<TerrainGridSystem>();
|
|
if (objs == null || objs.Length == 0)
|
|
{
|
|
Debug.LogError("Terrain Grid System Is Null!");
|
|
return;
|
|
}
|
|
|
|
_tgs = null;
|
|
foreach (var tgs in objs)
|
|
{
|
|
if (tgs.gameObject.scene == gameObject.scene)
|
|
_tgs = tgs;
|
|
}
|
|
|
|
if (_tgs == null)
|
|
{
|
|
Debug.LogError("Terrain Grid System Is Null!");
|
|
return;
|
|
}
|
|
|
|
_gridWidthHeight = new Vector2Int(_tgs.columnCount, _tgs.rowCount);
|
|
MapData = JsonToMapData(_mapDataJson);
|
|
_tgs.showCells = true;
|
|
_tgs.colorizeTerritories = true;
|
|
_tgs.TerritoryDestroyAll();
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (Application.isPlaying)
|
|
{
|
|
if (_camera != null)
|
|
_camera.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
[Button("保存")]
|
|
public void SaveMapData()
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (_mapDataJson != null && !Application.isPlaying)
|
|
{
|
|
var path = AssetDatabase.GetAssetPath(_mapDataJson);
|
|
JsonHelper.SaveJson(path, _mapData);
|
|
Debug.Log($"保存地图数据成功!");
|
|
EditorSceneManager.SaveOpenScenes();
|
|
AssetDatabase.Refresh();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// [Button("打印树数量")]
|
|
// private void LogTreeCount()
|
|
// {
|
|
// var objs = Object.FindObjectsOfType<MeshRenderer>();
|
|
// var count = 0;
|
|
// var vertexCount = 0;
|
|
// var triangles = 0;
|
|
// var treeCountInScreen = 0;
|
|
// var mainCam = Camera.main;
|
|
// foreach (var treeRenderer in objs)
|
|
// {
|
|
// if (treeRenderer.gameObject.name.ToLower().Contains("tree"))
|
|
// {
|
|
// count++;
|
|
// var viewPortPoint = mainCam.WorldToViewportPoint(treeRenderer.transform.position);
|
|
// if (viewPortPoint.x >= 0 && viewPortPoint.x <= 1 && viewPortPoint.y >= 0 && viewPortPoint.y <= 1)
|
|
// {
|
|
// treeCountInScreen++;
|
|
// var mesh = treeRenderer.gameObject.GetComponent<MeshFilter>().sharedMesh;
|
|
// vertexCount += mesh.vertexCount;
|
|
// triangles += mesh.triangles.Length/3;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// Debug.Log($"tree count:{count} treeInScreen:{treeCountInScreen} vertexCount:{vertexCount} triangles:{triangles}");
|
|
// }
|
|
|
|
private void OnDestroy()
|
|
{
|
|
SaveMapData();
|
|
}
|
|
|
|
#endregion
|
|
|
|
//#endif
|
|
} |