NLDClient-yudde/ProjectNLD/Assets/Editor/LevelEditor/LevelEditorWindow.cs

671 lines
23 KiB
C#
Raw Normal View History

using TGS;
using System;
2023-08-22 19:08:45 +08:00
using Gameplay;
using Framework;
using System.IO;
using UnityEditor;
using UnityEngine;
using System.Linq;
2024-06-04 16:50:16 +08:00
using cfg.FightCfg;
using Gameplay.Utils;
2023-08-22 19:08:45 +08:00
using Gameplay.Level;
using Sirenix.Utilities;
using Sirenix.OdinInspector;
2023-08-22 19:08:45 +08:00
using Sirenix.Utilities.Editor;
using System.Collections.Generic;
using Sirenix.OdinInspector.Editor;
2024-06-04 16:50:16 +08:00
using UnityEngine.Serialization;
using Constants = Framework.Constants;
2023-08-22 19:08:45 +08:00
using ObjectFieldAlignment = Sirenix.OdinInspector.ObjectFieldAlignment;
2023-11-21 15:04:56 +08:00
//todo 序列化bug
2023-08-22 19:08:45 +08:00
public class LevelEditorWindow : OdinEditorWindow
{
private static readonly Color regionColor = MapUtils.GetRGBAColor("FF960072");
2023-08-22 19:08:45 +08:00
[Serializable]
public class RegionData
{
2024-04-02 16:53:46 +08:00
[LabelText("出战区")] [OnValueChanged("OnRegionChanged")]
public int preparingRegionId;
2024-04-02 16:53:46 +08:00
[LabelText("出战区朝向")] public LevelData.CharacterToward preparingRegionToward;
2024-04-02 16:53:46 +08:00
[LabelText("撤退区")] public int fallbackRegionId;
2024-04-02 16:53:46 +08:00
[LabelText("敌方撤退区")] public int enemyFallbackRegionId;
2024-04-02 16:53:46 +08:00
[LabelText("PVP防守区")] public int pvpDefendRegionId;
2023-12-26 18:19:05 +08:00
2024-04-02 16:53:46 +08:00
[LabelText("PVP防守方朝向")] public LevelData.CharacterToward pvpDefendToward;
2023-12-26 18:19:05 +08:00
[LabelText("扛旗终点区")] [ShowIf("needSetFlagRegion")]
public int flagTargetRegionId;
[LabelText("占领进度")] [ShowIf("needSetCaptureProgress")]
public int captureProgress;
[HideInInspector] public bool needSetFlagRegion;
[HideInInspector] public bool needSetCaptureProgress;
private void OnRegionChanged()
{
var regionsList = currWindow._curMap.MapData.regions;
for (int i = 0; i < regionsList.Count; i++)
{
2023-12-22 15:26:48 +08:00
currWindow._curMap.SetRegionColor(i, false, regionColor);
}
2023-11-21 15:04:56 +08:00
2023-12-22 15:26:48 +08:00
currWindow._curMap.SetRegionColor(preparingRegionId, true, regionColor);
}
}
[Serializable]
public class NPCEditorInfo
{
2024-04-02 16:53:46 +08:00
[HideLabel] public LevelData.NPCInfo npcInfo;
2023-12-22 15:26:48 +08:00
private bool _isEditing;
public NPCEditorInfo(LevelData.NPCInfo npcInfo)
{
this.npcInfo = npcInfo;
}
[Button("开始编辑巡逻信息")]
[HideIf("_isEditing")]
private void StartEditNPC()
{
LevelEditorWindow.currWindow.StartEditPatrolInfo(npcInfo);
_isEditing = true;
}
[Button("完成编辑巡逻信息")]
[ShowIf("_isEditing")]
private void FinishEditNPC()
{
LevelEditorWindow.currWindow.FinishEditPatrolInfo();
_isEditing = false;
}
}
2023-08-22 19:08:45 +08:00
2024-06-04 16:50:16 +08:00
[Serializable]
public class ProtectEditorInfo
{
[HorizontalGroup("Protect")] [HideLabel]
public LevelData.ProtectUnit protectUnitInfo;
[HorizontalGroup("Protect")]
[TableColumnWidth(50, Resizable = false)]
[PreviewField(150, ObjectFieldAlignment.Center)]
[LabelText("护送对象预览图")]
[AssetList(Path = Constants.LEVEL_PROTECT_UNIT_PATH)]
[OnValueChanged("OnProtectUnitChanged")]
public GameObject protectUnitPrefab;
public ProtectEditorInfo(LevelData.ProtectUnit protectUnitInfo)
{
this.protectUnitInfo = protectUnitInfo;
InitData();
}
private void InitData()
{
prefabPathDic = new Dictionary<string, int>();
var protectCfg = EditorTableManager.instance.tables.ProtectUnitConfig;
dataProtectUnits = protectCfg.DataList;
foreach (var data in dataProtectUnits)
{
prefabPathDic.Add(data.PrefabPath, data.ID);
}
if (protectCfg.DataMap.TryGetValue(protectUnitInfo.id, out var dataConfig))
{
protectUnitPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(dataConfig.PrefabPath);
if (protectUnitPrefab == null)
DebugUtil.LogError("检查 ProtectUnitConfig 表,该ID: {0} 没有对应模型配置", protectUnitInfo.id);
}
}
private void OnProtectUnitChanged()
{
if (prefabPathDic == null)
{
InitData();
}
var path = AssetDatabase.GetAssetPath(protectUnitPrefab);
if (!prefabPathDic.TryGetValue(path, out var id))
{
DebugUtil.LogError("检查 ProtectUnitConfig 表,该模型没有对应配置: {0}", path);
}
else
{
protectUnitInfo.id = id;
}
}
private Dictionary<string, int> prefabPathDic;
private List<DataProtectUnit> dataProtectUnits;
}
public static LevelEditorWindow currWindow;
2023-11-21 15:04:56 +08:00
2023-12-18 19:42:46 +08:00
private MapManager _mapManager;
2023-12-22 15:26:48 +08:00
private Dictionary<Vector2Int, GameObject> _npcDic;
2023-08-22 19:08:45 +08:00
private Map _curMap;
2023-10-19 15:00:19 +08:00
2023-11-21 15:04:56 +08:00
private LevelEditor _levelEditor;
2023-12-22 15:26:48 +08:00
private LevelData.NPCInfo _currEditingNPCInfo;
public bool IsEditingPatrolInfo => _currEditingNPCInfo != null;
private bool ResponseClickOnCell => isEditingNPC || IsEditingPatrolInfo;
2024-04-02 16:53:46 +08:00
[LabelText("当前关卡数据"), Indent] [OnValueChanged("OnCurrentLevelDataChanged")]
2023-08-22 19:08:45 +08:00
public LevelData currentLevelData = null;
2023-12-22 15:26:48 +08:00
2024-04-02 16:53:46 +08:00
[LabelText("当前地区数据"), Indent] [OnValueChanged("OnCurrentLevelDataChanged")]
public RegionData curRegionData = null;
2023-12-22 15:26:48 +08:00
2024-06-04 16:50:16 +08:00
[LabelText("添加NPC"), Indent] [LabelWidth(100)] [SerializeField]
2023-12-22 15:26:48 +08:00
public bool isEditingNPC;
/// <summary>
/// 关卡ID 通过关卡数据 json文件名 获得
/// </summary>
2024-06-04 16:50:16 +08:00
[FormerlySerializedAs("LevelID")]
[LabelText("手动指定关卡ID"), Indent]
[LabelWidth(100)]
[SerializeField]
[ShowIf("NeedManualInputLevelID")]
[OnValueChanged("GetLevelMonsterClass")]
[InfoBox("无法正确获得关卡ID,请手动指定")]
2024-06-04 16:50:16 +08:00
public string levelID;
2024-06-04 16:50:16 +08:00
[LabelText("怪物ID"), Indent]
[LabelWidth(100)]
[SerializeField]
[OnValueChanged("MonsterIDChanged")]
[ValueDropdown("GetMonsterIDs")]
2023-12-22 15:26:48 +08:00
[ShowIf("isEditingNPC")]
public int curMonsterID;
2024-06-04 16:50:16 +08:00
[PreviewField(150, ObjectFieldAlignment.Center), Indent, ReadOnly] [LabelText("NPC预制体预览图"), ShowIf("isEditingNPC")]
public GameObject npcObject;
2023-12-21 12:48:58 +08:00
//当前怪物类ID
private int _curMonsterClassID;
private IEnumerable<int> GetMonsterIDs()
{
return monsterIDs;
}
2024-04-02 16:53:46 +08:00
private void MonsterIDChanged()
2023-12-21 12:48:58 +08:00
{
var monsterClassCfg = EditorTableManager.instance.tables.MonsterClass;
var monsterCfg = EditorTableManager.instance.tables.Monster;
if (monsterCfg.DataMap.TryGetValue(curMonsterID, out var monster))
2023-12-21 12:48:58 +08:00
{
_curMonsterClassID = monster.MonsterClassID;
2023-12-21 12:48:58 +08:00
}
if (monsterClassCfg.DataMap.TryGetValue(_curMonsterClassID, out var monsterClass))
{
var prefabPath = PathEx.GetEnemySrcModelPath(monsterClass.NameId);
npcObject = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (npcObject == null)
{
DebugUtil.LogError("请检查怪物类: {0}的预制体路径是否存在,对应的完整路径: {1}", _curMonsterClassID, prefabPath);
}
}
2023-12-21 12:48:58 +08:00
}
2023-12-22 15:26:48 +08:00
2024-06-04 16:50:16 +08:00
[LabelText("当前怪物列表"), Indent] public List<NPCEditorInfo> currentNpcInfo = null;
[LabelText("编辑护送对象"), Indent] public bool isEditingProtectUnit;
2024-06-04 16:50:16 +08:00
[LabelText("护送对象列表"), ShowIf("isEditingProtectUnit"), Indent]
public List<ProtectEditorInfo> currentProtectUnits = null;
2023-12-22 15:26:48 +08:00
2024-06-04 16:50:16 +08:00
[Button("保存当前关卡"), Indent]
2023-08-22 19:08:45 +08:00
private void SaveCurrentLevel()
{
CheckCorrectLevel();
2023-11-21 15:04:56 +08:00
//var configFilePath = string.Format(Constants.LEVEL_CONFIG_FORMAT_PATH, currentLevelData.id);
currentLevelData.preparingRegionId = curRegionData.preparingRegionId;
currentLevelData.fallbackRegionId = curRegionData.fallbackRegionId;
currentLevelData.enemyFallbackRegionId = curRegionData.enemyFallbackRegionId;
currentLevelData.preparingRegionToward = curRegionData.preparingRegionToward;
2023-12-26 18:19:05 +08:00
currentLevelData.pvpDefendRegionId = curRegionData.pvpDefendRegionId;
currentLevelData.pvpDefendToward = curRegionData.pvpDefendToward;
2023-11-21 15:04:56 +08:00
//NPC列表
2024-06-04 16:50:16 +08:00
currentLevelData.npcInfos = currentNpcInfo.Select(editorNPCInfo => editorNPCInfo.npcInfo).ToList();
//占领进度 抗旗终点
currentLevelData.captureProgress = curRegionData.captureProgress;
currentLevelData.flagTargetRegionId = curRegionData.flagTargetRegionId;
2024-06-04 16:50:16 +08:00
//护送对象
currentLevelData.protectUnitInfos =
currentProtectUnits.Select(editorProtectInfo => editorProtectInfo.protectUnitInfo).ToList();
2023-11-21 15:04:56 +08:00
_levelEditor.SaveLevelData();
}
2023-08-22 19:08:45 +08:00
2023-11-21 15:04:56 +08:00
public static void OpenWindow(LevelEditor levelEditor)
2023-08-22 19:08:45 +08:00
{
MapEditorSettings.Init();
2023-12-22 15:26:48 +08:00
currWindow = GetWindow<LevelEditorWindow>();
currWindow.position = GUIHelper.GetEditorWindowRect().AlignCenter(800, 600);
currWindow.currentLevelData = null;
currWindow._levelEditor = levelEditor;
currWindow.LoadLevel(levelEditor.LevelData);
var level = Path.GetFileNameWithoutExtension(levelEditor.LevelDataJson.name);
2024-06-04 16:50:16 +08:00
currWindow.levelID = level.Substring(level.Length - 6);
currWindow.GetLevelMonsterClass();
currWindow.CheckFlagAndCapture();
2024-06-04 16:50:16 +08:00
DebugUtil.Log("关卡数据:{0}", currWindow.levelID);
}
/// <summary>
/// 该关卡的怪物ID
/// </summary>
[HideInInspector] public List<int> monsterIDs;
/// <summary>
/// 需要手动输入关卡ID
/// </summary>
[HideInInspector] public bool NeedManualInputLevelID;
public void GetLevelMonsterClass()
{
var levelCfg = EditorTableManager.instance.tables.Level;
2024-06-04 16:50:16 +08:00
if (!int.TryParse(levelID, out var levelIndex) ||
!levelCfg.DataMap.TryGetValue(levelIndex, out var level))
{
NeedManualInputLevelID = true;
DebugUtil.LogError("无对应的关卡ID请手动输入关卡ID");
curMonsterID = 0;
npcObject = null;
return;
}
monsterIDs = new List<int>();
var monsterCfg = EditorTableManager.instance.tables.Monster;
foreach (var monster in monsterCfg.DataMap)
{
var strID = monster.Key.ToString();
var tempID = strID.Substring(0, 6);
//关卡ID相同
2024-06-04 16:50:16 +08:00
if (tempID.Equals(levelID))
{
monsterIDs.Add(monster.Key);
}
}
if (monsterIDs.Count <= 0)
{
2024-06-04 16:50:16 +08:00
DebugUtil.LogError("请检查Monster表,没有{0}关卡的怪物数据", levelID);
}
2023-08-22 19:08:45 +08:00
}
private void CheckFlagAndCapture()
{
2024-06-04 17:21:01 +08:00
curRegionData.needSetFlagRegion = _curMap.MapData.flagStartPoints.Count > 0;
curRegionData.needSetCaptureProgress = _curMap.MapData.capturePoints.Count > 0;
}
private const string PreparingRegionErrorMessage = "关卡出战区设置错误,该地图没有:<{0}>号地区。\n";
private const string FallbackRegionErrorMessage = "关卡撤退区设置错误,该地图没有:<{0}>号地区。\n";
private const string EnemyFallbackRegionErrorMessage = "关卡敌方撤退区设置错误,该地图没有:<{0}>号地区。\n";
private const string FlagTargetRegionErrorMessage = "抗旗终点区设置错误,该地图没有:<{0}>号地区。\n";
2024-06-04 16:50:16 +08:00
private const string ProtectUnitInfoErrorMessage = "护送 {0} 的起点和终点相同或出错,请检查。\n";
private const string FixedMessage = "已将错误区域设置为默认<0>号地区。";
2023-08-22 19:08:45 +08:00
private void CheckCorrectLevel()
{
if (_curMap == null)
2023-08-22 19:08:45 +08:00
{
return;
}
if (curRegionData.needSetCaptureProgress && curRegionData.captureProgress == 0)
DebugUtil.LogError("该地图有占领地格,无占领进度");
if (curRegionData.needSetFlagRegion && curRegionData.flagTargetRegionId <= 0)
DebugUtil.LogError("该地图有抗旗地格,抗旗终点区似乎无修改,默认为0号区域");
2023-08-22 19:08:45 +08:00
var errorMessage = string.Empty;
if (!_curMap.MapData.IsRegionExist(curRegionData.preparingRegionId))
2023-08-22 19:08:45 +08:00
{
errorMessage += string.Format(PreparingRegionErrorMessage,
curRegionData.preparingRegionId);
curRegionData.preparingRegionId = 0;
2023-08-22 19:08:45 +08:00
}
2023-11-21 15:04:56 +08:00
if (!_curMap.MapData.IsRegionExist(curRegionData.fallbackRegionId))
2023-08-22 19:08:45 +08:00
{
errorMessage += string.Format(FallbackRegionErrorMessage,
curRegionData.fallbackRegionId);
curRegionData.fallbackRegionId = 0;
2023-08-22 19:08:45 +08:00
}
2023-11-21 15:04:56 +08:00
if (!_curMap.MapData.IsRegionExist(curRegionData.enemyFallbackRegionId))
2023-08-22 19:08:45 +08:00
{
errorMessage += string.Format(EnemyFallbackRegionErrorMessage,
curRegionData.enemyFallbackRegionId);
curRegionData.enemyFallbackRegionId = 0;
}
if (!_curMap.MapData.IsRegionExist(curRegionData.flagTargetRegionId))
{
errorMessage += string.Format(FlagTargetRegionErrorMessage,
curRegionData.flagTargetRegionId);
curRegionData.flagTargetRegionId = 0;
2023-08-22 19:08:45 +08:00
}
2024-06-04 16:50:16 +08:00
foreach (var protectEditor in currentProtectUnits)
{
if (protectEditor.protectUnitInfo.protectStartPoint == protectEditor.protectUnitInfo.protectTargetPoint ||
protectEditor.protectUnitInfo.protectTargetPoint < 0 ||
protectEditor.protectUnitInfo.protectStartPoint < 0)
{
errorMessage += string.Format(ProtectUnitInfoErrorMessage,
protectEditor.protectUnitInfo.id);
break;
}
}
if (!string.IsNullOrEmpty(errorMessage))
2023-08-22 19:08:45 +08:00
{
CustomPopUpWindow.PopUp(errorMessage + FixedMessage);
2023-08-22 19:08:45 +08:00
}
}
2023-12-20 15:55:42 +08:00
private void Awake()
{
2023-12-22 15:26:48 +08:00
SceneView.duringSceneGui += OnSceneGUI;
2023-12-20 15:55:42 +08:00
}
2023-10-19 15:00:19 +08:00
protected override void OnEnable()
{
2023-11-15 17:59:47 +08:00
TerrainTypeConfig.Load();
_npcDic = new Dictionary<Vector2Int, GameObject>();
2023-10-19 15:00:19 +08:00
base.OnEnable();
}
2023-12-22 15:26:48 +08:00
2023-08-22 19:08:45 +08:00
protected override void OnDisable()
{
2023-12-22 15:26:48 +08:00
currWindow = null;
2023-12-18 19:42:46 +08:00
//MapEditorUtils.UnLoadMap(EditorMap.Instance);
2023-11-21 15:04:56 +08:00
//DestroyImmediate(GameObject.Find("Main Camera"));
DestroyNpcPrefab();
_npcDic = null;
2023-08-22 19:08:45 +08:00
base.OnDisable();
}
2023-11-21 15:04:56 +08:00
protected override void OnDestroy()
2023-08-22 19:08:45 +08:00
{
2023-11-21 15:04:56 +08:00
base.OnDestroy();
2023-12-22 15:26:48 +08:00
if (_curMap != null)
2023-11-21 15:04:56 +08:00
_curMap.TerrainGridSystem.OnMouseClickOnGrid -= OnCellClick;
2023-12-22 15:26:48 +08:00
SaveCurrentLevel();
SceneView.duringSceneGui -= OnSceneGUI;
2023-08-22 19:08:45 +08:00
}
2023-11-21 15:04:56 +08:00
private bool banSaveLevelList = false;
2023-08-22 19:08:45 +08:00
private void OnCurrentLevelDataChanged()
{
Debug.Log($"{GetType()}.OnCurrentLevelDataChanged");
}
2023-10-19 15:00:19 +08:00
private const string descKey = "LevelDesc";
private const string nameKey = "LevelName";
2023-11-21 15:04:56 +08:00
private void LoadLevel(LevelData levelData)
2023-08-22 19:08:45 +08:00
{
DestroyNpcPrefab();
_npcDic.Clear();
2023-11-21 15:04:56 +08:00
currentLevelData = levelData;
//加载地区信息
curRegionData = new RegionData();
curRegionData.preparingRegionId = currentLevelData.preparingRegionId;
curRegionData.fallbackRegionId = currentLevelData.fallbackRegionId;
curRegionData.enemyFallbackRegionId = currentLevelData.enemyFallbackRegionId;
curRegionData.preparingRegionToward = currentLevelData.preparingRegionToward;
2023-12-26 18:19:05 +08:00
curRegionData.pvpDefendRegionId = currentLevelData.pvpDefendRegionId;
curRegionData.pvpDefendToward = currentLevelData.pvpDefendToward;
2024-04-02 16:53:46 +08:00
//加载抗旗和占领
curRegionData.flagTargetRegionId = currentLevelData.flagTargetRegionId;
curRegionData.captureProgress = currentLevelData.captureProgress;
2024-04-02 16:53:46 +08:00
2023-12-18 19:42:46 +08:00
_mapManager = FindObjectOfType<MapManager>();
_curMap = _mapManager.Map;
2023-11-21 15:04:56 +08:00
_curMap.TerrainGridSystem.OnMouseClickOnGrid += OnCellClick;
2024-04-02 16:53:46 +08:00
var npcConfigDic = EditorTableManager.instance.tables.MonsterClass.DataMap;
var monsterConfigDic = EditorTableManager.instance.tables.Monster.DataMap;
//加载NPC到场景中
2024-06-04 16:50:16 +08:00
currentNpcInfo = new();
foreach (var npcInfo in currentLevelData.npcInfos)
{
2024-06-04 16:50:16 +08:00
currentNpcInfo.Add(new(npcInfo));
if (!monsterConfigDic.TryGetValue(npcInfo.id, out var monsterClassData))
{
DebugUtil.LogError("请检查配置,没有 {0} 的怪物类ID", npcInfo.id);
continue;
}
var monsterClassID = monsterClassData.MonsterClassID;
2024-04-02 16:53:46 +08:00
if (npcConfigDic.TryGetValue(monsterClassID, out var monster))
{
DebugUtil.Log("monsterNameId:{0}", monster.NameId);
string npcId = "P_" + monster.NameId;
var npc = AssetDatabase.LoadAssetAtPath<GameObject>(string.Format(Constants.LEVEL_NPC_PATH, npcId));
var position = _curMap.BlockPosition2WorldPosition(npcInfo.position);
_npcDic.Add(npcInfo.position, Instantiate(npc, position, npc.transform.rotation));
}
}
2024-06-04 16:50:16 +08:00
//加载护送对象
currentProtectUnits = new List<ProtectEditorInfo>();
foreach (var protectUnit in currentLevelData.protectUnitInfos)
{
currentProtectUnits.Add(new ProtectEditorInfo(protectUnit));
}
}
private void OnCellClick(TerrainGridSystem tgs, int cellindex, int buttonindex)
{
2024-06-04 16:50:16 +08:00
if (isEditingProtectUnit) DebugUtil.LogWarning("当前点击索引: {0}", cellindex);
2023-12-22 15:26:48 +08:00
if (!ResponseClickOnCell) return;
var clickPosition = _curMap.TGSCellIndex2BlockPosition(cellindex);
2023-11-21 15:04:56 +08:00
int leftButton = 0;
int rightButton = 1;
2023-12-22 15:26:48 +08:00
if (buttonindex != leftButton && buttonindex != rightButton)
return;
bool opTrue = buttonindex == leftButton;
if (IsEditingPatrolInfo)
{
if (opTrue)
AddPatrolInfo(clickPosition);
else
RemovePatrolInfo(clickPosition);
}
else if (isEditingNPC)
{
2023-12-22 15:26:48 +08:00
if (opTrue)
{
2023-12-22 15:26:48 +08:00
AddNPC(clickPosition);
}
2023-12-22 15:26:48 +08:00
else
{
2023-12-22 15:26:48 +08:00
RemoveNPC(clickPosition);
}
2023-12-22 15:26:48 +08:00
}
}
2023-11-21 15:04:56 +08:00
2023-12-22 15:26:48 +08:00
private void AddNPC(Vector2Int clickPosition)
{
if (npcObject == null || curMonsterID == 0)
2023-12-22 15:26:48 +08:00
{
DebugUtil.LogError("请选择正确的NPC!!");
return;
}
2023-11-21 15:04:56 +08:00
if (_npcDic == null)
{
_npcDic = new Dictionary<Vector2Int, GameObject>();
}
2023-12-22 15:26:48 +08:00
if (_npcDic.ContainsKey(clickPosition))
{
DebugUtil.LogError("该位置已有NPC存在,请重新选!!!");
return;
}
2023-12-22 15:26:48 +08:00
LevelData.NPCInfo npcInfo = new LevelData.NPCInfo();
/*string npcId = npcObject.name.Replace("P_", "");
2024-04-02 16:53:46 +08:00
var monsterId = 0;
2024-04-02 16:53:46 +08:00
var npcConfigDic = EditorTableManager.instance.tables.MonsterClass.DataMap;
var monsterConfigDic = EditorTableManager.instance.tables.Monster.DataMap;
2024-04-02 16:53:46 +08:00
var npcmatchingItem = npcConfigDic.FirstOrDefault(pair => pair.Value.NameId == npcId).Value;
if (npcmatchingItem != null)
{
var monsterClass = monsterConfigDic
.FirstOrDefault(pair => pair.Value.MonsterClassID == npcmatchingItem.MonsterClassID).Value;
if (monsterClass != null)
{
monsterId = monsterClass.MonsterID;
DebugUtil.Log($"匹配的对应怪物ClassID: {npcmatchingItem.MonsterClassID}, NameID: {npcmatchingItem.NameId}");
}
else
{
DebugUtil.LogError("没有相应配置,请重选,其怪物类ID为:{0}", npcmatchingItem.MonsterClassID);
return;
}
}
if (monsterId <= 0) return;
npcInfo.id = monsterConfigDic[monsterId].MonsterID;*/
npcInfo.id = curMonsterID;
2023-12-22 15:26:48 +08:00
npcInfo.position = clickPosition;
//默认等级为1
npcInfo.level = 1;
2024-06-04 16:50:16 +08:00
currentNpcInfo.Add(new(npcInfo));
2023-12-22 15:26:48 +08:00
var position = _curMap.BlockPosition2WorldPosition(npcInfo.position);
_npcDic.Add(npcInfo.position, Instantiate(npcObject, position, npcObject.transform.rotation));
DebugUtil.Log("添加了怪物: [ {0} ] 到 [ {1} ]位置上, 其预制体为: {2}", npcInfo.id, npcInfo.position, npcObject.name);
2023-12-22 15:26:48 +08:00
}
private void RemoveNPC(Vector2Int clickPosition)
{
if (_npcDic.TryGetValue(clickPosition, out var npcObj))
{
2024-06-04 16:50:16 +08:00
var npc = currentNpcInfo.FirstOrDefault(npc => npc.npcInfo.position == clickPosition);
2023-12-22 15:26:48 +08:00
if (npc != null)
{
2024-06-04 16:50:16 +08:00
currentNpcInfo.Remove(npc);
2023-12-22 15:26:48 +08:00
DebugUtil.Log("从[ {0} ]位置上移除了[{1}]NPC", clickPosition, npcObj.name);
DestroyImmediate(npcObj);
_npcDic.Remove(clickPosition);
}
}
}
2023-12-22 15:26:48 +08:00
private void AddPatrolInfo(Vector2Int clickPosition)
{
_currEditingNPCInfo.patrolInfos.Add(new LevelData.PatrolInfo()
{
patrolPoint = clickPosition,
});
}
private void RemovePatrolInfo(Vector2Int clickPosition)
{
var index = _currEditingNPCInfo.patrolInfos.FindLastIndex(pInfo => pInfo.patrolPoint == clickPosition);
if (index >= 0)
_currEditingNPCInfo.patrolInfos.RemoveAt(index);
}
public void StartEditPatrolInfo(LevelData.NPCInfo npcInfo)
{
_currEditingNPCInfo = npcInfo;
}
public void FinishEditPatrolInfo()
{
_currEditingNPCInfo = null;
}
private void DestroyNpcPrefab()
{
foreach (var npc in _npcDic)
{
DestroyImmediate(npc.Value);
}
2023-08-22 19:08:45 +08:00
}
2023-12-22 15:26:48 +08:00
protected override void OnGUI()
{
base.OnGUI();
if (_levelEditor == null || _mapManager == null || _mapManager.Map != _curMap ||
_levelEditor.LevelData != currentLevelData)
{
Debug.LogError("数据已变更,请重新打开关卡编辑器");
Close();
}
}
private void OnSceneGUI(SceneView sceneView)
{
DrawPatrolPath();
}
private void DrawPatrolPath()
{
if (!IsEditingPatrolInfo) return;
2023-12-22 15:26:48 +08:00
Vector3 lastWorldPos = Vector3.zero;
for (int i = 0; i < _currEditingNPCInfo.patrolInfos.Count; i++)
{
var gridPos = _currEditingNPCInfo.patrolInfos[i].patrolPoint;
var worldPos = _curMap.BlockPosition2WorldPosition(gridPos);
Handles.color = Color.blue;
Handles.DrawSolidDisc(worldPos, Vector3.up, 0.4f);
if (i > 0)
{
Handles.color = Color.yellow;
2023-12-26 18:19:05 +08:00
EditorUtil.DrawArrowInScene(lastWorldPos, worldPos, 0.5f);
2023-12-22 15:26:48 +08:00
}
//Handles.color = Color.black;
2023-12-26 18:19:05 +08:00
Handles.Label(worldPos, i.ToString());
2023-12-22 15:26:48 +08:00
lastWorldPos = worldPos;
}
}
2023-08-22 19:08:45 +08:00
}