2024-06-04 12:59:37 +08:00
|
|
|
|
using TGS;
|
|
|
|
|
|
using Framework;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using System.Linq;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
using Gameplay.Level;
|
|
|
|
|
|
using Sirenix.Utilities;
|
2024-06-04 12:59:37 +08:00
|
|
|
|
using Sirenix.OdinInspector;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
using Sirenix.Utilities.Editor;
|
|
|
|
|
|
using System.Collections.Generic;
|
2024-11-18 16:50:35 +08:00
|
|
|
|
using cfg.FightCfg;
|
2025-06-04 15:23:36 +08:00
|
|
|
|
using cfg.LevelCfg;
|
2024-11-18 16:50:35 +08:00
|
|
|
|
using cfg.MonsterCfg;
|
|
|
|
|
|
using cfg.VehicleCfg;
|
2024-06-04 12:59:37 +08:00
|
|
|
|
using Sirenix.OdinInspector.Editor;
|
2024-11-18 16:50:35 +08:00
|
|
|
|
using Level = cfg.LevelCfg.Level;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
using ObjectFieldAlignment = Sirenix.OdinInspector.ObjectFieldAlignment;
|
2025-06-26 14:56:16 +08:00
|
|
|
|
using static Gameplay.Level.LevelData;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
public partial class LevelEditorWindow : OdinEditorWindow
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2025-02-27 13:31:47 +08:00
|
|
|
|
[MenuItem("Tools/*地图场景/关卡编辑器", false, (int)NLDMenuID.LevelEditor)]
|
|
|
|
|
|
private static void OpenLevelEditorWindow()
|
|
|
|
|
|
{
|
|
|
|
|
|
var window = GetWindow<LevelEditorWindow>();
|
|
|
|
|
|
window.position = GUIHelper.GetEditorWindowRect().AlignCenter(800, 600);
|
|
|
|
|
|
window.titleContent = new GUIContent("关卡编辑器");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-07 18:15:12 +08:00
|
|
|
|
public static void OpenWindow(LevelEditor levelEditor)
|
|
|
|
|
|
{
|
|
|
|
|
|
MapEditorSettings.Init();
|
|
|
|
|
|
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);
|
|
|
|
|
|
currWindow.levelID = level.Substring(level.Length - 6);
|
2025-07-02 14:51:53 +08:00
|
|
|
|
//currWindow.GetLevelMonsterClass();
|
2024-11-07 18:15:12 +08:00
|
|
|
|
DebugUtil.Log("关卡数据:{0}", currWindow.levelID);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
private static LevelEditorWindow currWindow;
|
2024-11-07 15:50:33 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
private MapManager _mapManager;
|
2024-11-04 18:43:29 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
private Map _curMap;
|
2024-11-07 15:50:33 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
private LevelEditor _levelEditor;
|
2025-02-17 17:11:38 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#region 配置表
|
2025-02-17 17:11:38 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
private Level LevelCfg => EditorTableManager.instance.tables.Level;
|
|
|
|
|
|
private Monster MonsterCfg => EditorTableManager.instance.tables.Monster;
|
2025-06-10 15:46:40 +08:00
|
|
|
|
private MonsterClass MonsterClassCfg => EditorTableManager.instance.tables.MonsterClass;
|
2025-05-28 17:49:04 +08:00
|
|
|
|
private VehicleConfig VehicleCfg => EditorTableManager.instance.tables.VehicleConfig;
|
|
|
|
|
|
private FightNPCConfig FightNpcCfg => EditorTableManager.instance.tables.FightNPCConfig;
|
2025-06-10 15:46:40 +08:00
|
|
|
|
private BuildConfig FightBuildCfg => EditorTableManager.instance.tables.BuildConfig;
|
2024-11-04 18:19:57 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#endregion
|
2024-11-04 18:19:57 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#region 地块颜色
|
2024-11-04 18:19:57 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
private static readonly Color RegionColor = MapUtils.GetRGBAColor("FF960072");
|
2024-11-04 18:19:57 +08:00
|
|
|
|
|
2025-12-10 19:41:23 +08:00
|
|
|
|
private static readonly Color ShowRegionColor = Color.red;
|
|
|
|
|
|
|
2025-11-17 15:09:39 +08:00
|
|
|
|
private static readonly Color CaptureRegionColor = Color.yellow;
|
|
|
|
|
|
|
2025-11-17 17:47:26 +08:00
|
|
|
|
private static readonly Color RetreatRegionColor = Color.cyan;
|
|
|
|
|
|
|
2025-12-23 16:58:55 +08:00
|
|
|
|
private static readonly Color GroupHighlightColor = new Color(1f, 0.5f, 0f, 0.8f);
|
|
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#endregion
|
2024-11-04 18:19:57 +08:00
|
|
|
|
|
2025-12-09 13:05:27 +08:00
|
|
|
|
#region 任务相关
|
|
|
|
|
|
|
2025-12-09 16:21:59 +08:00
|
|
|
|
[BoxGroup("任务列表")] [LabelText("任务列表"), Indent]
|
|
|
|
|
|
public List<TaskInfoEditor> taskInfos = new List<TaskInfoEditor>();
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-17 16:44:57 +08:00
|
|
|
|
/*#region 胜利失败星级条件
|
2025-12-09 16:21:59 +08:00
|
|
|
|
|
2025-12-09 19:01:17 +08:00
|
|
|
|
private int successTaskID;
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("胜利失败星级条件")]
|
|
|
|
|
|
[HorizontalGroup("胜利失败星级条件/1")]
|
|
|
|
|
|
[LabelText("胜利条件"), Indent]
|
|
|
|
|
|
[ReadOnly]
|
|
|
|
|
|
[InfoBox("胜利条件任务无效,请在任务列表中检查配置。", InfoMessageType.Error, "@!IsTaskInvalid(successTaskID)")]
|
2025-12-09 16:21:59 +08:00
|
|
|
|
public string successTask;
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("胜利失败星级条件")]
|
|
|
|
|
|
[HorizontalGroup("胜利失败星级条件/1")]
|
|
|
|
|
|
[Button("搜索/选择胜利任务", ButtonSizes.Small)]
|
2025-12-09 19:01:17 +08:00
|
|
|
|
[InfoBox("胜利条件任务无效,请在任务列表中检查配置。", InfoMessageType.Error, "@!IsTaskInvalid(successTaskID)")]
|
2025-12-09 16:21:59 +08:00
|
|
|
|
private void OpenSuccessTaskSelector()
|
|
|
|
|
|
{
|
2025-12-09 19:01:17 +08:00
|
|
|
|
ShowTaskSelector("选择胜利条件任务", taskName => successTask = taskName, id => successTaskID = id);
|
2025-12-09 16:21:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-09 19:01:17 +08:00
|
|
|
|
private int failTaskID;
|
|
|
|
|
|
|
2025-12-09 16:21:59 +08:00
|
|
|
|
[FoldoutGroup("胜利失败星级条件")] [HorizontalGroup("胜利失败星级条件/2")] [LabelText("失败条件"), Indent] [ReadOnly]
|
|
|
|
|
|
public string failTask;
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("胜利失败星级条件")]
|
|
|
|
|
|
[HorizontalGroup("胜利失败星级条件/2")]
|
|
|
|
|
|
[Button("搜索/选择失败任务", ButtonSizes.Small)]
|
|
|
|
|
|
private void OpenFailTaskSelector()
|
|
|
|
|
|
{
|
2025-12-09 19:01:17 +08:00
|
|
|
|
ShowTaskSelector("选择失败条件任务", taskName => failTask = taskName, id => failTaskID = id);
|
2025-12-09 16:21:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-09 19:01:17 +08:00
|
|
|
|
private List<int> starTaskIDs = new List<int>() { 0, 0, 0 };
|
|
|
|
|
|
|
2025-12-09 16:21:59 +08:00
|
|
|
|
[FoldoutGroup("胜利失败星级条件")] [HorizontalGroup("胜利失败星级条件/3")] [LabelText("1星条件"), Indent] [ReadOnly]
|
|
|
|
|
|
public string oneStarTask;
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("胜利失败星级条件")]
|
|
|
|
|
|
[HorizontalGroup("胜利失败星级条件/3")]
|
|
|
|
|
|
[Button("搜索/选择1星任务", ButtonSizes.Small)]
|
|
|
|
|
|
private void OpenOneStarTaskSelector()
|
|
|
|
|
|
{
|
2025-12-09 19:01:17 +08:00
|
|
|
|
ShowTaskSelector("选择1星条件任务", taskName => oneStarTask = taskName, id => starTaskIDs[0] = id);
|
2025-12-09 16:21:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("胜利失败星级条件")] [HorizontalGroup("胜利失败星级条件/4")] [LabelText("2星条件"), Indent] [ReadOnly]
|
|
|
|
|
|
public string twoStarTask;
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("胜利失败星级条件")]
|
|
|
|
|
|
[HorizontalGroup("胜利失败星级条件/4")]
|
|
|
|
|
|
[Button("搜索/选择2星任务", ButtonSizes.Small)]
|
|
|
|
|
|
private void OpenTwoStarTaskSelector()
|
|
|
|
|
|
{
|
2025-12-09 19:01:17 +08:00
|
|
|
|
ShowTaskSelector("选择2星条件任务", taskName => twoStarTask = taskName, id => starTaskIDs[1] = id);
|
2025-12-09 16:21:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("胜利失败星级条件")] [HorizontalGroup("胜利失败星级条件/5")] [LabelText("3星条件"), Indent] [ReadOnly]
|
|
|
|
|
|
public string threeStarTask;
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("胜利失败星级条件")]
|
|
|
|
|
|
[HorizontalGroup("胜利失败星级条件/5")]
|
|
|
|
|
|
[Button("搜索/选择3星任务", ButtonSizes.Small)]
|
|
|
|
|
|
private void OpenThreeStarTaskSelector()
|
|
|
|
|
|
{
|
2025-12-09 19:01:17 +08:00
|
|
|
|
ShowTaskSelector("选择3星条件任务", taskName => threeStarTask = taskName, id => starTaskIDs[2] = id);
|
2025-12-09 16:21:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-17 16:44:57 +08:00
|
|
|
|
#endregion*/
|
2025-12-09 13:05:27 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#region 关卡数据
|
2023-12-22 15:26:48 +08:00
|
|
|
|
|
2025-12-30 13:45:24 +08:00
|
|
|
|
[FoldoutGroup("当前关卡数据")] [HideLabel]
|
2025-05-28 17:49:04 +08:00
|
|
|
|
public LevelData currentLevelData = null;
|
2024-11-04 18:43:29 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#endregion
|
2023-12-22 15:26:48 +08:00
|
|
|
|
|
2025-12-30 13:45:24 +08:00
|
|
|
|
#region 触发器
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("当前关卡数据")] [BoxGroup("当前关卡数据/触发器列表")] [Indent, LabelText("触发器")]
|
|
|
|
|
|
public List<LevelTriggerDataEditor> levelTriggerData = new List<LevelTriggerDataEditor>();
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 波次管理
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("当前关卡数据")]
|
|
|
|
|
|
[BoxGroup("当前关卡数据/波次管理")]
|
|
|
|
|
|
[LabelText("编辑波次"), Indent]
|
|
|
|
|
|
[OnValueChanged(nameof(OnIsEditingWaveChanged))]
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
public bool isEditingWave;
|
|
|
|
|
|
|
|
|
|
|
|
private void OnIsEditingWaveChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isEditingWave)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 刷新波次信息显示
|
|
|
|
|
|
RefreshWaveInfoEditors();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("当前关卡数据")]
|
|
|
|
|
|
[BoxGroup("当前关卡数据/波次管理")]
|
|
|
|
|
|
[LabelText("波次列表(管理怪物组)"), Indent]
|
|
|
|
|
|
[ShowIf(nameof(isEditingWave))]
|
|
|
|
|
|
[InfoBox("说明:波次管理基于怪物组ID,不是NPC索引。一个怪物组只能属于一个波次。直接添加项来创建新波次,波次ID可修改。", InfoMessageType.Info)]
|
|
|
|
|
|
[ListDrawerSettings(
|
|
|
|
|
|
CustomRemoveIndexFunction = nameof(CustomRemoveWave),
|
|
|
|
|
|
DraggableItems = false,
|
|
|
|
|
|
ShowFoldout = true
|
|
|
|
|
|
)]
|
|
|
|
|
|
public List<WaveInfoEditor> waveInfoEditors = new();
|
|
|
|
|
|
|
|
|
|
|
|
private void CustomRemoveWave(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index >= 0 && index < waveInfoEditors.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
var wave = waveInfoEditors[index];
|
|
|
|
|
|
|
|
|
|
|
|
// 清除该波次中所有怪物组的怪物的波次信息
|
|
|
|
|
|
if (currentEnemyNpcInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var groupId in wave.enemies)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var npc in currentEnemyNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (npc.npcInfo.groups != null && npc.npcInfo.groups.Contains(groupId))
|
|
|
|
|
|
{
|
|
|
|
|
|
npc.npcInfo.waveIndex = 0;
|
|
|
|
|
|
npc.npcInfo.isHideOnLoad = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
waveInfoEditors.RemoveAt(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-30 15:46:47 +08:00
|
|
|
|
|
2025-12-30 13:45:24 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 刷新波次信息编辑器
|
|
|
|
|
|
/// </summary>
|
2025-12-30 15:46:47 +08:00
|
|
|
|
[FoldoutGroup("当前关卡数据")]
|
|
|
|
|
|
[BoxGroup("当前关卡数据/波次管理")]
|
|
|
|
|
|
[Button("刷新至怪物属性"), Indent]
|
|
|
|
|
|
[ShowIf(nameof(isEditingWave))]
|
2025-12-30 13:45:24 +08:00
|
|
|
|
private void RefreshWaveInfoEditors()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (waveInfoEditors == null)
|
|
|
|
|
|
waveInfoEditors = new List<WaveInfoEditor>();
|
|
|
|
|
|
|
2025-12-30 15:46:47 +08:00
|
|
|
|
if (currentEnemyNpcInfo == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
// 第一步:重建 _enemyNpcObjectWaveDic 字典
|
|
|
|
|
|
// 创建新的字典结构
|
|
|
|
|
|
var newWaveDic = new Dictionary<int, Dictionary<NpcEditorInfo, GameObject>>();
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历所有NPC,根据当前的waveIndex重新组织字典
|
|
|
|
|
|
foreach (var npc in currentEnemyNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
int oldWaveIndex = npc.npcInfo.waveIndex;
|
|
|
|
|
|
|
|
|
|
|
|
// 从旧字典中找到这个NPC的GameObject
|
|
|
|
|
|
GameObject npcObj = null;
|
|
|
|
|
|
if (_enemyNpcObjectWaveDic != null && _enemyNpcObjectWaveDic.TryGetValue(oldWaveIndex, out var oldNpcDic))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (oldNpcDic.TryGetValue(npc, out npcObj))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 找到了GameObject
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果找不到,尝试在所有波次中查找
|
|
|
|
|
|
if (npcObj == null && _enemyNpcObjectWaveDic != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var waveDic in _enemyNpcObjectWaveDic.Values)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (waveDic.TryGetValue(npc, out npcObj))
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 将GameObject添加到新字典中(按照即将更新的waveIndex)
|
|
|
|
|
|
if (npcObj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 先暂存到旧的waveIndex,后面会更新
|
|
|
|
|
|
if (!newWaveDic.ContainsKey(oldWaveIndex))
|
|
|
|
|
|
{
|
|
|
|
|
|
newWaveDic[oldWaveIndex] = new Dictionary<NpcEditorInfo, GameObject>();
|
|
|
|
|
|
}
|
|
|
|
|
|
newWaveDic[oldWaveIndex][npc] = npcObj;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第二步:清空所有NPC的波次信息
|
|
|
|
|
|
foreach (var npc in currentEnemyNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
npc.npcInfo.waveIndex = 0;
|
|
|
|
|
|
npc.npcInfo.isHideOnLoad = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第三步:根据波次编辑器更新NPC属性
|
|
|
|
|
|
var finalWaveDic = new Dictionary<int, Dictionary<NpcEditorInfo, GameObject>>();
|
|
|
|
|
|
|
2025-12-30 13:45:24 +08:00
|
|
|
|
foreach (var wave in waveInfoEditors)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var groupId in wave.enemies)
|
|
|
|
|
|
{
|
2025-12-30 15:46:47 +08:00
|
|
|
|
foreach (var npc in currentEnemyNpcInfo)
|
2025-12-30 13:45:24 +08:00
|
|
|
|
{
|
2025-12-30 15:46:47 +08:00
|
|
|
|
if (npc.npcInfo.groups != null && npc.npcInfo.groups.Contains(groupId))
|
2025-12-30 13:45:24 +08:00
|
|
|
|
{
|
2025-12-30 15:46:47 +08:00
|
|
|
|
npc.npcInfo.waveIndex = wave.waveID;
|
|
|
|
|
|
npc.npcInfo.isHideOnLoad = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 更新到最终字典(使用新的waveIndex)
|
|
|
|
|
|
// 从临时字典中找到GameObject
|
|
|
|
|
|
GameObject npcObj = null;
|
|
|
|
|
|
foreach (var waveDic in newWaveDic.Values)
|
2025-12-30 13:45:24 +08:00
|
|
|
|
{
|
2025-12-30 15:46:47 +08:00
|
|
|
|
if (waveDic.TryGetValue(npc, out npcObj))
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (npcObj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!finalWaveDic.ContainsKey(wave.waveID))
|
|
|
|
|
|
{
|
|
|
|
|
|
finalWaveDic[wave.waveID] = new Dictionary<NpcEditorInfo, GameObject>();
|
|
|
|
|
|
}
|
|
|
|
|
|
finalWaveDic[wave.waveID][npc] = npcObj;
|
2025-12-30 13:45:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-30 15:46:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 第四步:处理不在任何波次中的NPC(waveIndex = 0)
|
|
|
|
|
|
foreach (var npc in currentEnemyNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (npc.npcInfo.waveIndex == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 从临时字典中找到GameObject
|
|
|
|
|
|
GameObject npcObj = null;
|
|
|
|
|
|
foreach (var waveDic in newWaveDic.Values)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (waveDic.TryGetValue(npc, out npcObj))
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (npcObj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!finalWaveDic.ContainsKey(0))
|
|
|
|
|
|
{
|
|
|
|
|
|
finalWaveDic[0] = new Dictionary<NpcEditorInfo, GameObject>();
|
|
|
|
|
|
}
|
|
|
|
|
|
finalWaveDic[0][npc] = npcObj;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第五步:替换原字典
|
|
|
|
|
|
_enemyNpcObjectWaveDic = finalWaveDic;
|
|
|
|
|
|
|
|
|
|
|
|
DebugUtil.Log("已刷新波次信息至怪物属性,并更新了预制体字典");
|
2025-12-30 13:45:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-09 16:21:59 +08:00
|
|
|
|
#region 战役关卡
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("当前关卡数据")]
|
|
|
|
|
|
[BoxGroup("当前关卡数据/支线(战役)")]
|
|
|
|
|
|
[LabelText("设置该关卡为评分关卡"), Indent]
|
|
|
|
|
|
[OnValueChanged(nameof(OnScoreLevelChanged))]
|
|
|
|
|
|
public bool scoreLevel;
|
|
|
|
|
|
|
|
|
|
|
|
private void OnScoreLevelChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
currentLevelData.scoreLevel = scoreLevel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("当前关卡数据")]
|
|
|
|
|
|
[BoxGroup("当前关卡数据/支线(战役)")]
|
|
|
|
|
|
[Indent, ShowIf("@currentLevelData.scoreLevel")]
|
|
|
|
|
|
[LabelText("评分条件")]
|
|
|
|
|
|
public List<ScoreTaskEditor> scoreTasks = new List<ScoreTaskEditor>();
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
#region 关卡引导
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("关卡引导")] [BoxGroup("关卡引导/关卡进度")] [LabelText("关卡进度"), Indent]
|
2025-12-09 16:21:59 +08:00
|
|
|
|
public List<ProgressGuideDataEditor> progressGuideDatas = new();
|
2025-06-10 18:45:59 +08:00
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
[FoldoutGroup("关卡引导")] [BoxGroup("关卡引导/立标数据")] [LabelText("立标数据"), Indent]
|
2025-12-09 16:21:59 +08:00
|
|
|
|
public List<SetFlagGuideDataEditor> setFlagEditorInfos = new();
|
2025-06-10 18:45:59 +08:00
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
[FoldoutGroup("关卡引导")] [BoxGroup("关卡引导/信息板数据")] [LabelText("信息板数据"), Indent]
|
2025-12-09 16:21:59 +08:00
|
|
|
|
public List<InfoPanelGuideDataEditor> infoPanelGuideDatas = new();
|
2025-06-10 18:45:59 +08:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-07-08 20:07:21 +08:00
|
|
|
|
#region 关卡AI广播
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
[FoldoutGroup("关卡AI广播")] [BoxGroup("关卡AI广播/数据")] [LabelText("AI广播数据"), Indent]
|
2025-12-09 16:21:59 +08:00
|
|
|
|
public List<AIBroadcastDataEditor> listAIBroadcastData = new();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-07-08 20:07:21 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-10 19:41:23 +08:00
|
|
|
|
#region 地区相关
|
|
|
|
|
|
|
2025-12-12 19:11:47 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 每种地区对应的显示颜色
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static readonly Dictionary<ShowRegionType, Color> ShowRegionTypeColors =
|
|
|
|
|
|
new Dictionary<ShowRegionType, Color>
|
|
|
|
|
|
{
|
|
|
|
|
|
{ ShowRegionType.CaptureRegion, CaptureRegionColor },
|
|
|
|
|
|
{ ShowRegionType.RetreatRegion, RetreatRegionColor },
|
|
|
|
|
|
{ ShowRegionType.EnemyRetreatRegion, Color.green },
|
|
|
|
|
|
{ ShowRegionType.FlagStratRegion, new Color(1f, 0.5f, 0f) },
|
|
|
|
|
|
{ ShowRegionType.FlagEndRegion, new Color(1f, 0.3f, 0.3f) },
|
|
|
|
|
|
{ ShowRegionType.MinesRegion, Color.black },
|
|
|
|
|
|
{ ShowRegionType.DefenseRegion, Color.magenta },
|
|
|
|
|
|
{ ShowRegionType.BlockRegion, Color.blue },
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-12-22 15:33:08 +08:00
|
|
|
|
[FoldoutGroup("地区相关")] [LabelText("显示地区颜色")] [EnumToggleButtons] [OnValueChanged(nameof(OnShowRegionTypeChanged))]
|
2025-12-10 19:41:23 +08:00
|
|
|
|
public ShowRegionType showRegionType;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-12-12 19:11:47 +08:00
|
|
|
|
/// 根据当前选择的地区类型集合,高亮对应的地区格子,每种地区使用独立颜色。
|
2025-12-10 19:41:23 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnShowRegionTypeChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_curMap == null || currentLevelData == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
ClearShowRegionColor();
|
|
|
|
|
|
|
|
|
|
|
|
if (showRegionType == ShowRegionType.None)
|
2025-12-12 19:11:47 +08:00
|
|
|
|
{
|
|
|
|
|
|
SceneView.RepaintAll();
|
2025-12-10 19:41:23 +08:00
|
|
|
|
return;
|
2025-12-12 19:11:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var mask = showRegionType;
|
|
|
|
|
|
if (mask.HasFlag(ShowRegionType.All))
|
|
|
|
|
|
{
|
|
|
|
|
|
mask |= ShowRegionType.All;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var kv in ShowRegionTypeColors)
|
|
|
|
|
|
{
|
|
|
|
|
|
var type = kv.Key;
|
|
|
|
|
|
var color = kv.Value;
|
2025-12-10 19:41:23 +08:00
|
|
|
|
|
2025-12-12 19:11:47 +08:00
|
|
|
|
if (!mask.HasFlag(type))
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
var points = GetRegionPoints(type);
|
|
|
|
|
|
if (points == null || points.Count == 0)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
_curMap.SetBlocksColor(points, true, color);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SceneView.RepaintAll();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 按地区类型获取需要高亮的格子索引列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private List<int> GetRegionPoints(ShowRegionType type)
|
|
|
|
|
|
{
|
2025-12-10 19:41:23 +08:00
|
|
|
|
var points = new HashSet<int>();
|
|
|
|
|
|
|
2025-12-12 19:11:47 +08:00
|
|
|
|
switch (type)
|
2025-12-10 19:41:23 +08:00
|
|
|
|
{
|
|
|
|
|
|
case ShowRegionType.CaptureRegion:
|
|
|
|
|
|
if (captureEditorInfos != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var capture in captureEditorInfos)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (capture?.capturePointEditorInfos == null) continue;
|
|
|
|
|
|
foreach (var p in capture.capturePointEditorInfos)
|
|
|
|
|
|
{
|
|
|
|
|
|
points.Add(p.capturePoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ShowRegionType.RetreatRegion:
|
|
|
|
|
|
if (retreatEditorInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var info in retreatEditorInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
points.Add(info.retreatPoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ShowRegionType.EnemyRetreatRegion:
|
|
|
|
|
|
if (enemyRetreatEditorInfo?.fallbackReusablePoints != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var pos in enemyRetreatEditorInfo.fallbackReusablePoints)
|
|
|
|
|
|
{
|
|
|
|
|
|
points.Add(_curMap.BlockPosition2TGSCellIndex(pos));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ShowRegionType.FlagStratRegion:
|
|
|
|
|
|
if (flagEditorInfo?.flagStartPoints != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var pos in flagEditorInfo.flagStartPoints)
|
|
|
|
|
|
{
|
|
|
|
|
|
points.Add(_curMap.BlockPosition2TGSCellIndex(pos));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ShowRegionType.FlagEndRegion:
|
|
|
|
|
|
if (flagEditorInfo?.flagEndPoints != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var pos in flagEditorInfo.flagEndPoints)
|
|
|
|
|
|
{
|
|
|
|
|
|
points.Add(_curMap.BlockPosition2TGSCellIndex(pos));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ShowRegionType.MinesRegion:
|
|
|
|
|
|
if (minesRegionList != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var area in minesRegionList)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (area?.Positions == null) continue;
|
|
|
|
|
|
foreach (var cell in area.Positions)
|
|
|
|
|
|
{
|
|
|
|
|
|
points.Add(cell);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ShowRegionType.DefenseRegion:
|
|
|
|
|
|
if (defenseRegionList != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var area in defenseRegionList)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (area?.Positions == null) continue;
|
|
|
|
|
|
foreach (var cell in area.Positions)
|
|
|
|
|
|
{
|
|
|
|
|
|
points.Add(cell);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case ShowRegionType.BlockRegion:
|
|
|
|
|
|
if (blockRegionList != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var area in blockRegionList)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (area?.Positions == null) continue;
|
|
|
|
|
|
foreach (var cell in area.Positions)
|
|
|
|
|
|
{
|
|
|
|
|
|
points.Add(cell);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-12 19:11:47 +08:00
|
|
|
|
return points.ToList();
|
2025-12-10 19:41:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
#region 撤离相关
|
|
|
|
|
|
|
2025-12-10 19:41:23 +08:00
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[BoxGroup("地区相关/撤离相关")]
|
|
|
|
|
|
[VerticalGroup("地区相关/撤离相关/编辑")]
|
2025-12-10 16:37:58 +08:00
|
|
|
|
[LabelText("编辑撤离数据"), Indent]
|
|
|
|
|
|
[OnValueChanged("OnIsEditingRetreatChanged")]
|
|
|
|
|
|
public bool isEditingRetreat;
|
|
|
|
|
|
|
2025-12-10 19:41:23 +08:00
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[BoxGroup("地区相关/撤离相关")]
|
2025-12-10 16:37:58 +08:00
|
|
|
|
[LabelText("当前撤离数据"), Indent]
|
|
|
|
|
|
[ShowIf("isEditingRetreat")]
|
|
|
|
|
|
[ListDrawerSettings(CustomRemoveIndexFunction = "CustomRemoveRetreatPoint",
|
|
|
|
|
|
DraggableItems = false)]
|
|
|
|
|
|
public List<RetreatEditorInfo> retreatEditorInfo = new();
|
|
|
|
|
|
|
|
|
|
|
|
private void CustomRemoveRetreatPoint(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index >= retreatEditorInfo.Count) return;
|
|
|
|
|
|
var point = retreatEditorInfo[index].retreatPoint;
|
|
|
|
|
|
_curMap.TerrainGridSystem.CellHideRegionSurface(point);
|
|
|
|
|
|
retreatEditorInfo.RemoveAt(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 敌人撤离相关
|
|
|
|
|
|
|
2025-12-10 19:41:23 +08:00
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[BoxGroup("地区相关/敌人撤离相关")]
|
|
|
|
|
|
[LabelText("编辑敌人撤离数据"), Indent]
|
|
|
|
|
|
[OnValueChanged("OnIsEditingEnemyRetreatChanged")]
|
|
|
|
|
|
public bool isEditingEnemyRetreat;
|
|
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
private void OnIsEditingEnemyRetreatChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isEditingEnemyRetreat)
|
|
|
|
|
|
return;
|
|
|
|
|
|
isEditingFallbackReusable = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool isEditingFallbackReusable;
|
|
|
|
|
|
|
2025-12-10 19:41:23 +08:00
|
|
|
|
[FoldoutGroup("地区相关")] [BoxGroup("地区相关/敌人撤离相关")] [LabelText("当前撤离数据"), Indent] [ShowIf("isEditingEnemyRetreat")]
|
2025-12-10 16:37:58 +08:00
|
|
|
|
public EnemyRetreatEditorInfo enemyRetreatEditorInfo = new();
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 出战防守区
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("地区相关")] [BoxGroup("地区相关/出战防守")] [LabelText("当前地区数据"), Indent]
|
|
|
|
|
|
public RegionData curRegionData = null;
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#region 占领相关
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
[FoldoutGroup("地区相关")] [BoxGroup("地区相关/占领相关")] [VerticalGroup("地区相关/占领相关/编辑")] [LabelText("编辑占领区"), Indent]
|
|
|
|
|
|
public bool isEditingCapture = false;
|
2025-11-17 15:09:39 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[BoxGroup("地区相关/占领相关")]
|
|
|
|
|
|
[VerticalGroup("地区相关/占领相关/编辑")]
|
|
|
|
|
|
[LabelText("编辑占领区"), Indent]
|
|
|
|
|
|
[ShowIf("isEditingCapture")]
|
|
|
|
|
|
public List<CaptureEditorInfo> captureEditorInfos = new();
|
2024-11-07 17:22:30 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#endregion
|
2025-11-17 15:09:39 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#region 扛旗相关
|
2025-11-17 15:09:39 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
[FoldoutGroup("地区相关")] [BoxGroup("地区相关/扛棋相关")] [LabelText("当前扛旗数据"), Indent]
|
|
|
|
|
|
public FlagEditorInfo flagEditorInfo = new();
|
2025-11-17 15:09:39 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#endregion
|
2025-11-17 15:09:39 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#region 雷区
|
2025-11-17 15:09:39 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[BoxGroup("地区相关/雷区信息")]
|
|
|
|
|
|
[HorizontalGroup("地区相关/雷区信息/Region")]
|
|
|
|
|
|
[LabelText("编辑雷区"), Indent]
|
|
|
|
|
|
[OnValueChanged("OnCanEditorMinesAreaTypeChanged")]
|
|
|
|
|
|
[LabelWidth(100)]
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private bool canEditorMinesArea;
|
2025-11-17 15:09:39 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void OnCanEditorMinesAreaTypeChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (canEditorMinesArea)
|
2024-11-11 13:46:47 +08:00
|
|
|
|
{
|
2025-12-10 16:37:58 +08:00
|
|
|
|
canEditorBlockArea = false;
|
|
|
|
|
|
canEditorDefenseArea = false;
|
2025-12-10 17:39:34 +08:00
|
|
|
|
_isEditorSingleBlockRegion = false;
|
|
|
|
|
|
_isEditorSingleDefenseRegion = false;
|
2025-12-10 16:37:58 +08:00
|
|
|
|
ClearDefenseRegionColor();
|
|
|
|
|
|
ClearBlockRegionColor();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ClearMinesRegionColor();
|
|
|
|
|
|
SceneView.RepaintAll();
|
2025-12-10 17:39:34 +08:00
|
|
|
|
_isEditorSingleMinesRegion = false;
|
2025-12-10 16:37:58 +08:00
|
|
|
|
_currEditMinesRegionArea = null;
|
2024-11-11 13:46:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[VerticalGroup("地区相关/雷区信息/RegionInfo"), Indent]
|
|
|
|
|
|
[LabelText("雷区列表")]
|
|
|
|
|
|
[ShowIf("canEditorMinesArea")]
|
|
|
|
|
|
[ListDrawerSettings(CustomAddFunction = "CustomAddMinesRegion",
|
|
|
|
|
|
CustomRemoveIndexFunction = "CustomRemoveMinesRegion",
|
|
|
|
|
|
DraggableItems = false)]
|
|
|
|
|
|
public List<MinesRegionArea> minesRegionList = new();
|
|
|
|
|
|
|
|
|
|
|
|
private void CustomAddMinesRegion()
|
2025-11-17 17:47:26 +08:00
|
|
|
|
{
|
2025-12-10 16:37:58 +08:00
|
|
|
|
var region = new LevelData.Region();
|
|
|
|
|
|
currentLevelData.minesRegions.Add(region);
|
|
|
|
|
|
UpdateMinesRegion();
|
2025-11-17 17:47:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
private void CustomRemoveMinesRegion(int index)
|
2025-11-17 17:47:26 +08:00
|
|
|
|
{
|
2025-12-10 16:37:58 +08:00
|
|
|
|
ClearMinesRegionColor();
|
|
|
|
|
|
currentLevelData.minesRegions.RemoveAt(index);
|
|
|
|
|
|
UpdateMinesRegion();
|
2025-11-17 17:47:26 +08:00
|
|
|
|
}
|
2025-02-21 17:03:56 +08:00
|
|
|
|
|
2024-11-07 18:15:12 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
#region 阻挡区信息
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[BoxGroup("地区相关/阻挡区信息")]
|
|
|
|
|
|
[HorizontalGroup("地区相关/阻挡区信息/Region")]
|
|
|
|
|
|
[LabelText("编辑阻挡区"), Indent]
|
|
|
|
|
|
[OnValueChanged("OnCanEditorBlockAreaChanged")]
|
|
|
|
|
|
[LabelWidth(100)]
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private bool canEditorBlockArea;
|
|
|
|
|
|
|
|
|
|
|
|
private void OnCanEditorBlockAreaChanged()
|
2025-11-25 17:02:53 +08:00
|
|
|
|
{
|
2025-12-10 16:37:58 +08:00
|
|
|
|
if (canEditorBlockArea)
|
|
|
|
|
|
{
|
|
|
|
|
|
canEditorMinesArea = false;
|
|
|
|
|
|
canEditorDefenseArea = false;
|
2025-12-10 17:39:34 +08:00
|
|
|
|
_isEditorSingleDefenseRegion = false;
|
2025-12-10 16:37:58 +08:00
|
|
|
|
ClearDefenseRegionColor();
|
|
|
|
|
|
ClearMinesRegionColor();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ClearBlockRegionColor();
|
|
|
|
|
|
SceneView.RepaintAll();
|
|
|
|
|
|
_currEditBlockRegion = null;
|
2025-12-10 17:39:34 +08:00
|
|
|
|
_isEditorSingleBlockRegion = false;
|
2025-12-10 16:37:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[LabelText("阻挡区列表")]
|
|
|
|
|
|
[ShowIf("canEditorBlockArea")]
|
|
|
|
|
|
[VerticalGroup("地区相关/阻挡区信息/RegionInfo"), Indent]
|
|
|
|
|
|
[ListDrawerSettings(CustomAddFunction = "CustomAddBlockRegion",
|
|
|
|
|
|
CustomRemoveIndexFunction = "CustomRemoveBlockRegionIndex",
|
|
|
|
|
|
DraggableItems = false)]
|
|
|
|
|
|
public List<BlockRegionArea> blockRegionList = new();
|
|
|
|
|
|
|
|
|
|
|
|
private void CustomAddBlockRegion()
|
|
|
|
|
|
{
|
|
|
|
|
|
var region = new BlockRegion();
|
|
|
|
|
|
currentLevelData.blockRegions.Add(region);
|
|
|
|
|
|
UpdateBlockRegion();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void CustomRemoveBlockRegionIndex(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index < blockRegionList.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (blockRegionList[index].obj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError($"删除{blockRegionList[index].id}的指示");
|
|
|
|
|
|
DestroyImmediate(blockRegionList[index].obj);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ClearBlockRegionColor();
|
|
|
|
|
|
currentLevelData.blockRegions.RemoveAt(index);
|
|
|
|
|
|
UpdateBlockRegion();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-25 17:02:53 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-10 16:37:58 +08:00
|
|
|
|
#region 刷怪触发区
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[BoxGroup("地区相关/刷怪触发区")]
|
|
|
|
|
|
[HorizontalGroup("地区相关/刷怪触发区/Region")]
|
|
|
|
|
|
[LabelText("编辑触发区"), Indent]
|
|
|
|
|
|
[OnValueChanged("OnCanEditorDefenseAreaChanged")]
|
|
|
|
|
|
[LabelWidth(100)]
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private bool canEditorDefenseArea;
|
|
|
|
|
|
|
|
|
|
|
|
private void OnCanEditorDefenseAreaChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (canEditorDefenseArea)
|
|
|
|
|
|
{
|
|
|
|
|
|
canEditorBlockArea = false;
|
|
|
|
|
|
canEditorMinesArea = false;
|
2025-12-10 17:39:34 +08:00
|
|
|
|
_isEditorSingleBlockRegion = false;
|
2025-12-10 16:37:58 +08:00
|
|
|
|
ClearBlockRegionColor();
|
|
|
|
|
|
ClearMinesRegionColor();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ClearDefenseRegionColor();
|
|
|
|
|
|
SceneView.RepaintAll();
|
|
|
|
|
|
_currEditDefenseRegion = null;
|
2025-12-10 17:39:34 +08:00
|
|
|
|
_isEditorSingleDefenseRegion = false;
|
2025-12-10 16:37:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[FoldoutGroup("地区相关")]
|
|
|
|
|
|
[LabelText("刷怪触发区列表")]
|
|
|
|
|
|
[ShowIf("canEditorDefenseArea")]
|
|
|
|
|
|
[VerticalGroup("地区相关/刷怪触发区/RegionInfo"), Indent]
|
|
|
|
|
|
[ListDrawerSettings(CustomAddFunction = "CustomAddDefenseRegion",
|
|
|
|
|
|
CustomRemoveIndexFunction = "CustomRemoveDefenseRegion",
|
|
|
|
|
|
DraggableItems = false)]
|
|
|
|
|
|
public List<DefenseRegionArea> defenseRegionList = new();
|
|
|
|
|
|
|
|
|
|
|
|
private void CustomAddDefenseRegion()
|
|
|
|
|
|
{
|
|
|
|
|
|
var region = new LevelData.Region();
|
|
|
|
|
|
currentLevelData.defenseRegions.Add(region);
|
|
|
|
|
|
UpdateDefenseRegion();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void CustomRemoveDefenseRegion(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
ClearDefenseRegionColor();
|
|
|
|
|
|
currentLevelData.defenseRegions.RemoveAt(index);
|
|
|
|
|
|
UpdateDefenseRegion();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#endregion
|
2025-02-21 17:03:56 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#endregion
|
2025-02-21 17:03:56 +08:00
|
|
|
|
|
|
|
|
|
|
#region 指定路线
|
|
|
|
|
|
|
2025-06-04 12:56:03 +08:00
|
|
|
|
[BoxGroup("制定路线")] [LabelText("编辑指定路径"), Indent]
|
2025-05-28 17:49:04 +08:00
|
|
|
|
public bool isEditingRoad;
|
2025-02-21 17:03:56 +08:00
|
|
|
|
|
2025-06-04 12:56:03 +08:00
|
|
|
|
[BoxGroup("制定路线")] [LabelText("编辑指定路线"), Indent] [ShowIf("isEditingRoad")]
|
2025-06-26 14:56:16 +08:00
|
|
|
|
public List<PrescribedRoadEditorInfo> roadEditorInfos = new();
|
2025-02-21 17:03:56 +08:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-06-26 15:25:35 +08:00
|
|
|
|
#region 指定区域
|
|
|
|
|
|
|
2025-12-10 13:23:32 +08:00
|
|
|
|
[BoxGroup("巡逻区域")] [LabelText("编辑巡逻区域"), Indent]
|
2025-06-26 15:25:35 +08:00
|
|
|
|
public bool isEditingArea;
|
|
|
|
|
|
|
2025-12-10 13:23:32 +08:00
|
|
|
|
[BoxGroup("巡逻区域")] [LabelText("编辑巡逻区域"), Indent] [ShowIf("isEditingArea")]
|
2025-06-26 15:25:35 +08:00
|
|
|
|
public List<PrescribedAreaEditorInfo> areaEditorInfos = new();
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#region 显示地图索引
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-08-25 17:34:39 +08:00
|
|
|
|
[BoxGroup("显示地格索引")]
|
|
|
|
|
|
[LabelText("显示类型"), Indent]
|
|
|
|
|
|
[OnValueChanged("ShowCellIndex")]
|
2025-05-28 17:49:04 +08:00
|
|
|
|
[LabelWidth(100)]
|
|
|
|
|
|
[SerializeField]
|
2025-08-25 17:34:39 +08:00
|
|
|
|
private CellDebugInfo cellDebugInfo = CellDebugInfo.Nothing;
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-08-25 17:34:39 +08:00
|
|
|
|
private void ShowCellIndex()
|
2024-11-04 18:19:57 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (_curMap == null || _curMap.TerrainGridSystem == null) return;
|
2025-08-25 17:34:39 +08:00
|
|
|
|
_curMap.TerrainGridSystem.displayCellDebugInfo = cellDebugInfo;
|
2024-11-04 18:19:57 +08:00
|
|
|
|
var obj = FindObjectOfType<TerrainGridSystem>().gameObject;
|
|
|
|
|
|
Selection.activeGameObject = obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2024-11-13 17:14:27 +08:00
|
|
|
|
#region 敌方Npc
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-08-28 15:12:14 +08:00
|
|
|
|
private GameObject enemyObjRoot;
|
|
|
|
|
|
|
2025-06-06 18:02:48 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 波次/怪物ID对应的NPC预制体
|
|
|
|
|
|
/// </summary>
|
2025-06-30 18:46:13 +08:00
|
|
|
|
private Dictionary<int, Dictionary<NpcEditorInfo, GameObject>> _enemyNpcObjectWaveDic;
|
2025-05-28 17:49:04 +08:00
|
|
|
|
|
|
|
|
|
|
[BoxGroup("敌方Npc")]
|
|
|
|
|
|
[LabelText("编辑NPC"), Indent]
|
|
|
|
|
|
[LabelWidth(100)]
|
|
|
|
|
|
[SerializeField]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[OnValueChanged("OnIsEditingEnemyNpcChanged")]
|
|
|
|
|
|
public bool isEditingEnemyNpc;
|
2024-11-18 16:50:35 +08:00
|
|
|
|
|
2025-08-28 14:37:55 +08:00
|
|
|
|
[BoxGroup("敌方Npc")] [LabelText("显示所有怪物序号ID"), Indent] [OnValueChanged("ShowAllEnemyNpcId")] [SerializeField]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
public bool isShowAllEnemyNpcID;
|
2024-11-18 16:50:35 +08:00
|
|
|
|
|
2025-08-28 14:37:55 +08:00
|
|
|
|
[BoxGroup("敌方Npc")] [LabelText("筛选怪物ID"), Indent, LabelWidth(100)] [SerializeField] [ShowIf("isEditingEnemyNpc")]
|
2025-07-02 14:51:53 +08:00
|
|
|
|
public string selectEnemyMonsterId;
|
2025-07-01 13:19:07 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
[BoxGroup("敌方Npc")]
|
2024-11-12 20:31:06 +08:00
|
|
|
|
[LabelText("怪物ID"), Indent, LabelWidth(100)]
|
2024-05-29 14:03:39 +08:00
|
|
|
|
[SerializeField]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[OnValueChanged("EnemyMonsterIDChanged")]
|
|
|
|
|
|
[ValueDropdown("GetEnemyMonsterIDs")]
|
|
|
|
|
|
[ShowIf("isEditingEnemyNpc")]
|
2025-12-22 15:33:08 +08:00
|
|
|
|
public string curEnemyMonsterIDStr;
|
|
|
|
|
|
|
|
|
|
|
|
private int curEnemyMonsterID;
|
2024-05-29 14:03:39 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
[BoxGroup("敌方Npc")]
|
|
|
|
|
|
[PreviewField(150, ObjectFieldAlignment.Center), Indent, ReadOnly]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[LabelText("NPC预制体预览图"), ShowIf("isEditingEnemyNpc")]
|
|
|
|
|
|
public GameObject enemyNpcObject;
|
2023-12-21 12:48:58 +08:00
|
|
|
|
|
2025-12-10 18:54:43 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 真实敌人列表
|
|
|
|
|
|
/// </summary>
|
2025-12-10 19:41:23 +08:00
|
|
|
|
[HideInInspector] public List<NpcEditorInfo> currentEnemyNpcInfo = null;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
|
2025-12-22 15:33:08 +08:00
|
|
|
|
private IEnumerable<string> GetEnemyMonsterIDs()
|
2024-05-29 14:03:39 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (string.IsNullOrEmpty(selectEnemyMonsterId))
|
|
|
|
|
|
return _allMonsterIDs.Keys;
|
|
|
|
|
|
_selectMonsterIDs.Clear();
|
|
|
|
|
|
foreach (var enemyMonster in _allMonsterIDs.Keys)
|
2025-07-02 14:51:53 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (enemyMonster.Contains(selectEnemyMonsterId))
|
|
|
|
|
|
_selectMonsterIDs.Add(enemyMonster);
|
2025-07-02 14:51:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-22 15:33:08 +08:00
|
|
|
|
return _selectMonsterIDs;
|
2024-05-29 14:03:39 +08:00
|
|
|
|
}
|
2024-04-02 16:53:46 +08:00
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
private void EnemyMonsterIDChanged()
|
2023-12-21 12:48:58 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (!_allMonsterIDs.TryGetValue(curEnemyMonsterIDStr, out var id))
|
|
|
|
|
|
return;
|
|
|
|
|
|
curEnemyMonsterID = id;
|
2025-06-30 18:46:13 +08:00
|
|
|
|
var obj = LoadEnemyNpcPrefab(curEnemyMonsterID);
|
2024-11-04 18:19:57 +08:00
|
|
|
|
if (obj != null)
|
2025-06-30 18:46:13 +08:00
|
|
|
|
enemyNpcObject = obj;
|
2024-11-04 18:19:57 +08:00
|
|
|
|
}
|
2023-12-21 12:48:58 +08:00
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
private void OnIsEditingEnemyNpcChanged()
|
2024-11-18 16:50:35 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (isEditingEnemyNpc)
|
2025-06-30 18:46:13 +08:00
|
|
|
|
{
|
2024-11-18 16:50:35 +08:00
|
|
|
|
isEditingSelfNpc = false;
|
2025-06-30 18:46:13 +08:00
|
|
|
|
isEditingMidNpc = false;
|
2025-12-22 15:33:08 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var npcEditorInfo in currentEnemyNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
npcEditorInfo.isChangePos = false;
|
2025-06-30 18:46:13 +08:00
|
|
|
|
}
|
2025-12-29 14:41:29 +08:00
|
|
|
|
|
2025-12-22 15:49:23 +08:00
|
|
|
|
isEditingNpcPos = false;
|
2025-12-22 15:45:40 +08:00
|
|
|
|
currWindow._currNpcEditorInfo = null;
|
|
|
|
|
|
currWindow._currEditingNpcInfo = null;
|
2025-12-29 14:41:29 +08:00
|
|
|
|
|
2025-12-23 16:58:55 +08:00
|
|
|
|
// 清除所有组的高亮显示
|
2025-12-23 18:36:45 +08:00
|
|
|
|
ClearAllGroupHighlights();
|
2024-11-18 16:50:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
private void ShowAllEnemyNpcId()
|
2024-11-04 18:19:57 +08:00
|
|
|
|
{
|
2025-08-28 14:37:55 +08:00
|
|
|
|
foreach (var npc in currentEnemyNpcInfo)
|
2024-09-05 13:26:43 +08:00
|
|
|
|
{
|
2025-06-30 18:46:13 +08:00
|
|
|
|
npc.isShowNpcID = isShowAllEnemyNpcID;
|
|
|
|
|
|
if (isShowAllEnemyNpcID)
|
2024-09-05 12:28:32 +08:00
|
|
|
|
{
|
2024-11-04 18:19:57 +08:00
|
|
|
|
if (!_showNpcInfos.Contains(npc))
|
2024-09-05 12:28:32 +08:00
|
|
|
|
{
|
2024-11-04 18:19:57 +08:00
|
|
|
|
_showNpcInfos.Add(npc);
|
2024-09-05 12:28:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-11-04 18:19:57 +08:00
|
|
|
|
else
|
2024-05-29 14:03:39 +08:00
|
|
|
|
{
|
2024-11-04 18:19:57 +08:00
|
|
|
|
_showNpcInfos.Remove(npc);
|
2024-05-29 14:03:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-12-21 12:48:58 +08:00
|
|
|
|
}
|
2025-12-10 19:41:23 +08:00
|
|
|
|
|
2025-12-29 14:41:29 +08:00
|
|
|
|
[BoxGroup("敌方Npc")]
|
|
|
|
|
|
[Button("保存"), ShowIf("isEditingEnemyNpc")]
|
|
|
|
|
|
private void SaveNewGroup()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (enemyNpcGroups == null || enemyNpcGroups.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning("没有分组需要保存");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int changedCount = 0;
|
|
|
|
|
|
foreach (var group in enemyNpcGroups)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (group != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
group.ApplyGroupIdChange(false);
|
|
|
|
|
|
changedCount++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 所有修改完成后,统一刷新一次视图
|
|
|
|
|
|
RefreshEnemyNpcGroups();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 18:54:43 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 敌方 NPC 的分组展示数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[BoxGroup("敌方Npc")]
|
|
|
|
|
|
[LabelText("按组查看怪物"), Indent, ShowIf("isEditingEnemyNpc")]
|
|
|
|
|
|
[ShowInInspector]
|
|
|
|
|
|
[ListDrawerSettings(HideAddButton = true, HideRemoveButton = true, DraggableItems = false, ShowFoldout = true)]
|
|
|
|
|
|
public List<EnemyNpcGroupView> enemyNpcGroups = new();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-23 18:36:45 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 清除所有组的高亮显示
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void ClearAllGroupHighlights()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (enemyNpcGroups == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var group in enemyNpcGroups)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (group != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 强制清除高亮
|
|
|
|
|
|
group.ForceClearHighlight();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-12 20:31:06 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2024-11-13 17:14:27 +08:00
|
|
|
|
#region 己方Npc
|
2024-11-12 20:31:06 +08:00
|
|
|
|
|
2025-12-29 14:41:29 +08:00
|
|
|
|
private const int SelfID = 800;
|
2025-05-28 17:49:04 +08:00
|
|
|
|
|
2025-08-28 15:12:14 +08:00
|
|
|
|
private GameObject selfObjRoot;
|
|
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
private Dictionary<Vector2Int, GameObject> _selfNpcObjectDic;
|
|
|
|
|
|
|
|
|
|
|
|
[BoxGroup("己方Npc")]
|
|
|
|
|
|
[LabelText("编辑己方NPC"), Indent]
|
|
|
|
|
|
[LabelWidth(100)]
|
|
|
|
|
|
[OnValueChanged("OnIsEditingSelfNpcChanged")]
|
|
|
|
|
|
[SerializeField]
|
2024-11-13 17:14:27 +08:00
|
|
|
|
public bool isEditingSelfNpc;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
[BoxGroup("己方Npc")] [LabelText("显示所有己方序号ID"), Indent] [OnValueChanged("ShowAllSelfNpcId")] [SerializeField]
|
2024-11-18 16:50:35 +08:00
|
|
|
|
public bool isShowAllSelfNpcID;
|
|
|
|
|
|
|
2025-08-28 14:37:55 +08:00
|
|
|
|
[BoxGroup("己方Npc")] [LabelText("筛选怪物ID"), Indent, LabelWidth(100)] [SerializeField] [ShowIf("isEditingSelfNpc")]
|
2025-07-02 14:51:53 +08:00
|
|
|
|
public string selectSelfMonsterId;
|
2025-07-01 13:19:07 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
[BoxGroup("己方Npc")]
|
2024-11-13 17:14:27 +08:00
|
|
|
|
[LabelText("己方NpcID"), Indent, LabelWidth(100)]
|
2024-11-12 20:31:06 +08:00
|
|
|
|
[SerializeField]
|
2024-11-13 17:14:27 +08:00
|
|
|
|
[OnValueChanged("SelfNpcIDChanged")]
|
|
|
|
|
|
[ValueDropdown("GetSelfNpcIDs")]
|
|
|
|
|
|
[ShowIf("isEditingSelfNpc")]
|
2025-12-22 15:33:08 +08:00
|
|
|
|
public string curSelfNpcIDStr;
|
|
|
|
|
|
|
|
|
|
|
|
private int curSelfNpcID;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
[BoxGroup("己方Npc")]
|
2024-11-13 13:21:36 +08:00
|
|
|
|
[PreviewField(150, ObjectFieldAlignment.Center), Indent, ReadOnly]
|
2024-11-13 17:14:27 +08:00
|
|
|
|
[LabelText("己方NPC预制体预览图"), ShowIf("isEditingSelfNpc")]
|
|
|
|
|
|
public GameObject selfNpcObject;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
[BoxGroup("己方Npc")]
|
2024-11-13 17:14:27 +08:00
|
|
|
|
[LabelText("当前己方NPC列表"), Indent, ShowIf("isEditingSelfNpc")]
|
2024-11-13 13:21:36 +08:00
|
|
|
|
[ListDrawerSettings(HideAddButton = true, HideRemoveButton = true)]
|
2024-11-18 16:50:35 +08:00
|
|
|
|
public List<NpcEditorInfo> currentSelfNpcInfo = null;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
|
2025-12-22 15:33:08 +08:00
|
|
|
|
private IEnumerable<string> GetSelfNpcIDs()
|
2024-11-12 20:31:06 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (string.IsNullOrEmpty(selectSelfMonsterId))
|
|
|
|
|
|
return _allMonsterIDs.Keys;
|
|
|
|
|
|
_selectMonsterIDs.Clear();
|
|
|
|
|
|
foreach (var enemyMonster in _allMonsterIDs.Keys)
|
2025-07-02 14:51:53 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (enemyMonster.Contains(selectSelfMonsterId))
|
|
|
|
|
|
_selectMonsterIDs.Add(enemyMonster);
|
2025-07-02 14:51:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-22 15:33:08 +08:00
|
|
|
|
return _selectMonsterIDs;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-13 17:14:27 +08:00
|
|
|
|
private void SelfNpcIDChanged()
|
2024-11-12 20:31:06 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (!_allMonsterIDs.TryGetValue(curSelfNpcIDStr, out var id))
|
|
|
|
|
|
return;
|
|
|
|
|
|
curSelfNpcID = id;
|
2024-11-13 17:14:27 +08:00
|
|
|
|
var obj = LoadSelfNpcPrefab(curSelfNpcID);
|
2024-11-12 20:31:06 +08:00
|
|
|
|
if (obj != null)
|
2024-11-13 17:14:27 +08:00
|
|
|
|
selfNpcObject = obj;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-18 16:50:35 +08:00
|
|
|
|
private void OnIsEditingSelfNpcChanged()
|
|
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (isEditingSelfNpc)
|
2025-06-30 18:46:13 +08:00
|
|
|
|
{
|
|
|
|
|
|
isEditingEnemyNpc = false;
|
|
|
|
|
|
isEditingMidNpc = false;
|
2025-12-22 15:33:08 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var npcEditorInfo in currentSelfNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
npcEditorInfo.isChangePos = false;
|
2025-06-30 18:46:13 +08:00
|
|
|
|
}
|
2025-12-29 14:41:29 +08:00
|
|
|
|
|
2025-12-22 15:49:23 +08:00
|
|
|
|
isEditingNpcPos = false;
|
2025-12-22 15:45:40 +08:00
|
|
|
|
currWindow._currNpcEditorInfo = null;
|
|
|
|
|
|
currWindow._currEditingNpcInfo = null;
|
2024-11-18 16:50:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ShowAllSelfNpcId()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var npc in currentSelfNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
npc.isShowNpcID = isShowAllSelfNpcID;
|
|
|
|
|
|
if (isShowAllSelfNpcID)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!_showNpcInfos.Contains(npc))
|
|
|
|
|
|
{
|
|
|
|
|
|
_showNpcInfos.Add(npc);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_showNpcInfos.Remove(npc);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-12 20:31:06 +08:00
|
|
|
|
#endregion
|
2024-06-04 16:50:16 +08:00
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
#region 中立Npc
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-29 14:41:29 +08:00
|
|
|
|
private const int MidID = 500;
|
|
|
|
|
|
|
2025-08-28 15:12:14 +08:00
|
|
|
|
private GameObject midObjRoot;
|
|
|
|
|
|
|
2025-06-30 14:51:47 +08:00
|
|
|
|
/// <summary>
|
2025-06-30 18:46:13 +08:00
|
|
|
|
/// 中立 波次/怪物ID对应的NPC预制体
|
2025-06-30 14:51:47 +08:00
|
|
|
|
/// </summary>
|
2025-06-30 18:46:13 +08:00
|
|
|
|
private Dictionary<int, Dictionary<NpcEditorInfo, GameObject>> _midNpcObjectWaveDic;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[BoxGroup("中立Npc")]
|
2025-12-22 15:33:08 +08:00
|
|
|
|
[LabelText("编辑中立NPC"), Indent]
|
2025-06-30 14:51:47 +08:00
|
|
|
|
[LabelWidth(100)]
|
|
|
|
|
|
[SerializeField]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[OnValueChanged("OnIsEditingMidNpcChanged")]
|
|
|
|
|
|
public bool isEditingMidNpc;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
|
2025-08-28 14:37:55 +08:00
|
|
|
|
[BoxGroup("中立Npc")] [LabelText("显示所有怪物序号ID"), Indent] [OnValueChanged("ShowAllMidNpcId")] [SerializeField]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
public bool isShowAllMidNpcID;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
|
2025-08-28 14:37:55 +08:00
|
|
|
|
[BoxGroup("中立Npc")] [LabelText("筛选怪物ID"), Indent, LabelWidth(100)] [SerializeField] [ShowIf("isEditingMidNpc")]
|
2025-07-02 14:51:53 +08:00
|
|
|
|
public string selectMidMonsterId;
|
2025-07-01 13:19:07 +08:00
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[BoxGroup("中立Npc")]
|
|
|
|
|
|
[LabelText("怪物ID"), Indent, LabelWidth(100)]
|
2025-06-30 14:51:47 +08:00
|
|
|
|
[SerializeField]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[OnValueChanged("MidMonsterIDChanged")]
|
|
|
|
|
|
[ValueDropdown("GetMidMonsterIDs")]
|
|
|
|
|
|
[ShowIf("isEditingMidNpc")]
|
2025-12-22 15:33:08 +08:00
|
|
|
|
public string curMidMonsterIDStr;
|
|
|
|
|
|
|
|
|
|
|
|
private int curMidMonsterID;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[BoxGroup("中立Npc")]
|
2025-06-30 14:51:47 +08:00
|
|
|
|
[PreviewField(150, ObjectFieldAlignment.Center), Indent, ReadOnly]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[LabelText("NPC预制体预览图"), ShowIf("isEditingMidNpc")]
|
|
|
|
|
|
public GameObject midNpcObject;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
[BoxGroup("中立Npc")]
|
|
|
|
|
|
[LabelText("当前怪物列表"), Indent, ShowIf("isEditingMidNpc")]
|
2025-06-30 14:51:47 +08:00
|
|
|
|
[ListDrawerSettings(HideAddButton = true, HideRemoveButton = true, ShowFoldout = true)]
|
2025-06-30 18:46:13 +08:00
|
|
|
|
public List<NpcEditorInfo> currentMidNpcInfo = null;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
|
2025-12-22 15:33:08 +08:00
|
|
|
|
private IEnumerable<string> GetMidMonsterIDs()
|
2025-06-30 14:51:47 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (string.IsNullOrEmpty(selectMidMonsterId))
|
|
|
|
|
|
return _allMonsterIDs.Keys;
|
|
|
|
|
|
_selectMonsterIDs.Clear();
|
|
|
|
|
|
foreach (var enemyMonster in _allMonsterIDs.Keys)
|
2025-07-02 14:51:53 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (enemyMonster.Contains(selectMidMonsterId))
|
|
|
|
|
|
_selectMonsterIDs.Add(enemyMonster);
|
2025-07-02 14:51:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-22 15:33:08 +08:00
|
|
|
|
return _selectMonsterIDs;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
private void MidMonsterIDChanged()
|
2025-06-30 14:51:47 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (!_allMonsterIDs.TryGetValue(curMidMonsterIDStr, out var id))
|
|
|
|
|
|
return;
|
|
|
|
|
|
curMidMonsterID = id;
|
2025-06-30 18:46:13 +08:00
|
|
|
|
var obj = LoadMidNpcPrefab(curMidMonsterID);
|
|
|
|
|
|
if (obj != null)
|
|
|
|
|
|
midNpcObject = obj;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
private void OnIsEditingMidNpcChanged()
|
2025-06-30 14:51:47 +08:00
|
|
|
|
{
|
2025-12-22 15:33:08 +08:00
|
|
|
|
if (isEditingMidNpc)
|
2025-06-30 18:46:13 +08:00
|
|
|
|
{
|
|
|
|
|
|
isEditingEnemyNpc = false;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
isEditingSelfNpc = false;
|
2025-12-22 15:33:08 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var npcEditorInfo in currentMidNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
npcEditorInfo.isChangePos = false;
|
2025-06-30 18:46:13 +08:00
|
|
|
|
}
|
2025-12-22 15:49:23 +08:00
|
|
|
|
|
|
|
|
|
|
isEditingNpcPos = false;
|
2025-12-22 15:45:40 +08:00
|
|
|
|
currWindow._currNpcEditorInfo = null;
|
|
|
|
|
|
currWindow._currEditingNpcInfo = null;
|
2025-06-30 14:51:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-30 18:46:13 +08:00
|
|
|
|
private void ShowAllMidNpcId()
|
2025-06-30 14:51:47 +08:00
|
|
|
|
{
|
2025-06-30 18:46:13 +08:00
|
|
|
|
foreach (var npc in currentMidNpcInfo)
|
2025-06-30 14:51:47 +08:00
|
|
|
|
{
|
2025-06-30 18:46:13 +08:00
|
|
|
|
npc.isShowNpcID = isShowAllMidNpcID;
|
|
|
|
|
|
if (isShowAllMidNpcID)
|
2025-06-30 14:51:47 +08:00
|
|
|
|
{
|
2025-06-30 18:46:13 +08:00
|
|
|
|
if (!_showNpcInfos.Contains(npc))
|
|
|
|
|
|
{
|
|
|
|
|
|
_showNpcInfos.Add(npc);
|
|
|
|
|
|
}
|
2025-06-30 14:51:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2025-06-30 18:46:13 +08:00
|
|
|
|
{
|
|
|
|
|
|
_showNpcInfos.Remove(npc);
|
|
|
|
|
|
}
|
2025-06-30 14:51:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 阻挡球编辑
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
[BoxGroup("攻击阻挡球")]
|
|
|
|
|
|
[HorizontalGroup("攻击阻挡球/Block")]
|
|
|
|
|
|
[LabelText("编辑攻击阻挡球"), Indent]
|
|
|
|
|
|
[OnValueChanged("OnCanEditorBlockSphereChanged")]
|
|
|
|
|
|
[LabelWidth(100)]
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private bool canEditorBlockSphere;
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void OnCanEditorBlockSphereChanged()
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (canEditorBlockSphere)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
showBuildings = false;
|
|
|
|
|
|
HideObjectsExcept();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
blockSphereEditorList.Clear();
|
|
|
|
|
|
UpdateBlockSphereInfo();
|
|
|
|
|
|
foreach (var cellIndex in banAttackCells)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (blockSphereInfo.TryGetValue(cellIndex, out var sphereInfo))
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
var sphere = CreateSphere(cellIndex, sphereInfo.offestPos, Vector3.one * sphereInfo.scale);
|
|
|
|
|
|
var blockEditorInfo = new BlockSpereEditorInfo(sphereInfo, sphere);
|
|
|
|
|
|
blockSphereEditorList.Add(blockEditorInfo);
|
2025-08-28 14:37:55 +08:00
|
|
|
|
}
|
2025-12-10 17:39:34 +08:00
|
|
|
|
else
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
var pos = _curMap.TGSCellIndex2WorldPosition(cellIndex);
|
|
|
|
|
|
var sphere = CreateSphere(cellIndex, pos, Vector3.one * Calibre);
|
|
|
|
|
|
var blockEditorInfo = new BlockSpereEditorInfo(cellIndex, sphere);
|
|
|
|
|
|
blockSphereEditorList.Add(blockEditorInfo);
|
2025-08-28 14:37:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
editingBlockSphereList.Clear();
|
|
|
|
|
|
foreach (var editorInfo in blockSphereEditorList)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (editorInfo.isChanged)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
editingBlockSphereList.Add(editorInfo);
|
2025-08-28 14:37:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-10 17:39:34 +08:00
|
|
|
|
else
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
// 清理所有临时材质
|
|
|
|
|
|
foreach (var editorInfo in blockSphereEditorList)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (editorInfo.editingMaterial != null)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (editorInfo.sphere != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var renderer = editorInfo.sphere.GetComponent<Renderer>();
|
|
|
|
|
|
if (renderer != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
renderer.sharedMaterial = editorInfo.originalSharedMaterial;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
DestroyImmediate(editorInfo.editingMaterial);
|
2025-08-28 14:37:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
showBuildings = true;
|
|
|
|
|
|
ShowHiddenObjects();
|
|
|
|
|
|
DestroyBlockSphere();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
}
|
2025-12-10 17:39:34 +08:00
|
|
|
|
}
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
[LabelText("展示建筑")]
|
|
|
|
|
|
[HorizontalGroup("攻击阻挡球/BlockBuildings"), Indent]
|
|
|
|
|
|
[ShowIf("canEditorBlockSphere")]
|
|
|
|
|
|
[OnValueChanged("OnShowBuildingsChanged")]
|
|
|
|
|
|
public bool showBuildings;
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void OnShowBuildingsChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (showBuildings)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
|
|
|
|
|
ShowHiddenObjects();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
HideObjectsExcept();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[LabelText("添加地格")] [HorizontalGroup("攻击阻挡球/新数据"), Indent] [ShowIf("canEditorBlockSphere")]
|
|
|
|
|
|
public int addCellIndex;
|
|
|
|
|
|
|
|
|
|
|
|
[Button("添加编辑")]
|
|
|
|
|
|
[HorizontalGroup("攻击阻挡球/新数据/Add"), Indent]
|
|
|
|
|
|
[ShowIf("canEditorBlockSphere")]
|
|
|
|
|
|
public void AddBlockSphere()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!banAttackCells.Contains(addCellIndex))
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorUtility.DisplayDialog("错误", $"地格 {addCellIndex} 不是攻击阻挡地格!", "确定");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var blockSpereEditor in editingBlockSphereList)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (blockSpereEditor.cellIndex == addCellIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var blockSpereEditor in blockSphereEditorList)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (blockSpereEditor.cellIndex == addCellIndex)
|
|
|
|
|
|
{
|
|
|
|
|
|
editingBlockSphereList.Add(blockSpereEditor);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[LabelText("阻挡球列表")]
|
|
|
|
|
|
[HorizontalGroup("攻击阻挡球/EditList"), Indent]
|
|
|
|
|
|
[ShowIf("canEditorBlockSphere")]
|
|
|
|
|
|
[ListDrawerSettings(HideAddButton = true, CustomRemoveIndexFunction = "CustomRemoveBlockSphereIndex")]
|
|
|
|
|
|
public List<BlockSpereEditorInfo> editingBlockSphereList = new();
|
|
|
|
|
|
|
|
|
|
|
|
[HideInInspector] public List<BlockSpereEditorInfo> blockSphereEditorList = new();
|
|
|
|
|
|
|
|
|
|
|
|
private void CustomRemoveBlockSphereIndex(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index < editingBlockSphereList.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
editingBlockSphereList[index].Revert();
|
|
|
|
|
|
DebugUtil.Log($"删除并还原{editingBlockSphereList[index].cellIndex}的阻挡球编辑数据");
|
|
|
|
|
|
editingBlockSphereList.RemoveAt(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#endregion
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#region 保存
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
[Button("保存当前关卡"), Indent]
|
|
|
|
|
|
private void SaveCurrentLevel()
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
CheckCorrectLevel();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (!CheckTask())
|
|
|
|
|
|
return;
|
2026-01-04 13:40:25 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentLevelData.taskInfos = taskInfos.Select(t => t.taskInfo).ToList();
|
2026-01-04 13:40:25 +08:00
|
|
|
|
ProcessCondition();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-17 16:44:57 +08:00
|
|
|
|
/*// 胜利失败星级条件
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentLevelData.successTaskID = successTaskID;
|
|
|
|
|
|
currentLevelData.failTaskID = failTaskID;
|
|
|
|
|
|
for (var i = 0; i < starTaskIDs.Count; i++)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentLevelData.starTaskIDs[i] = starTaskIDs[i];
|
2025-12-17 16:44:57 +08:00
|
|
|
|
}*/
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
// 地区
|
|
|
|
|
|
currentLevelData.preparingRegionId = curRegionData.preparingRegionId;
|
|
|
|
|
|
currentLevelData.preparingRegionToward = curRegionData.preparingRegionToward;
|
|
|
|
|
|
currentLevelData.pvpDefendRegionId = curRegionData.pvpDefendRegionId;
|
|
|
|
|
|
currentLevelData.pvpDefendToward = curRegionData.pvpDefendToward;
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
// 评分关卡
|
|
|
|
|
|
currentLevelData.scoreTaskID = scoreTasks.Select(s => s.scoreTaskID).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
//触发器
|
|
|
|
|
|
currentLevelData.levelTriggerDatas = levelTriggerData.Select(e => e.levelTriggerData).ToList();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#region 敌方NPC
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
foreach (var npcEditor in currentEnemyNpcInfo)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
npcEditor.npcInfo.index = npcEditor.id;
|
|
|
|
|
|
}
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentLevelData.npcInfos = currentEnemyNpcInfo.Select(editorNpcInfo => editorNpcInfo.npcInfo).ToList();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#endregion
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-29 19:07:03 +08:00
|
|
|
|
#region 波次信息
|
|
|
|
|
|
|
|
|
|
|
|
// 验证波次ID是否有重复且大于0
|
|
|
|
|
|
if (waveInfoEditors != null && waveInfoEditors.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var waveIdSet = new HashSet<int>();
|
|
|
|
|
|
foreach (var waveEditor in waveInfoEditors)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (waveEditor.waveID <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorUtility.DisplayDialog("错误", $"波次ID必须大于0,当前有波次ID为 {waveEditor.waveID}!", "确定");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-12-30 13:45:24 +08:00
|
|
|
|
|
2025-12-29 19:07:03 +08:00
|
|
|
|
if (!waveIdSet.Add(waveEditor.waveID))
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorUtility.DisplayDialog("错误", $"波次ID {waveEditor.waveID} 重复,请修改后再保存!", "确定");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新所有敌方NPC的波次信息(基于怪物组)
|
|
|
|
|
|
foreach (var npc in currentEnemyNpcInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool inWave = false;
|
2025-12-30 13:45:24 +08:00
|
|
|
|
|
2025-12-29 19:07:03 +08:00
|
|
|
|
if (npc.npcInfo.groups != null && npc.npcInfo.groups.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 检查该NPC的任何一个组是否在某个波次中
|
|
|
|
|
|
foreach (var wave in waveInfoEditors)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var groupId in npc.npcInfo.groups)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (wave.enemies.Contains(groupId))
|
|
|
|
|
|
{
|
|
|
|
|
|
npc.npcInfo.waveIndex = wave.waveID;
|
|
|
|
|
|
npc.npcInfo.isHideOnLoad = true;
|
|
|
|
|
|
inWave = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-30 13:45:24 +08:00
|
|
|
|
|
2025-12-29 19:07:03 +08:00
|
|
|
|
if (inWave) break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果不在任何波次中,清除波次信息
|
|
|
|
|
|
if (!inWave)
|
|
|
|
|
|
{
|
|
|
|
|
|
npc.npcInfo.waveIndex = 0;
|
|
|
|
|
|
npc.npcInfo.isHideOnLoad = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-23 16:58:55 +08:00
|
|
|
|
#region 怪物组信息
|
|
|
|
|
|
|
|
|
|
|
|
// 保存敌方NPC的分组信息
|
|
|
|
|
|
currentLevelData.groupInfos.Clear();
|
|
|
|
|
|
if (enemyNpcGroups != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var groupView in enemyNpcGroups)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 跳过"无编组怪物"组(groupId为-1)
|
|
|
|
|
|
if (groupView.groupId < 0)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
var groupInfo = new GroupInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
groupID = groupView.groupId,
|
|
|
|
|
|
groupName = groupView.groupName
|
|
|
|
|
|
};
|
|
|
|
|
|
currentLevelData.groupInfos.Add(groupInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#region 己方NPC
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
foreach (var npcFightEditorInfo in currentSelfNpcInfo)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
npcFightEditorInfo.npcInfo.index = npcFightEditorInfo.id;
|
2025-08-28 14:37:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentLevelData.selfNpcInfos =
|
|
|
|
|
|
currentSelfNpcInfo.Select(editorFightNpcInfo => editorFightNpcInfo.npcInfo).ToList();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#endregion
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#region 中立NPC
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
foreach (var npcEditor in currentMidNpcInfo)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
npcEditor.npcInfo.index = npcEditor.id;
|
2025-08-28 14:37:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentLevelData.midNpcInfos = currentMidNpcInfo.Select(editorNpcInfo => editorNpcInfo.npcInfo).ToList();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#endregion
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
// 占领数据
|
|
|
|
|
|
currentLevelData.CapturePoints.Clear();
|
|
|
|
|
|
foreach (var captureInfo in captureEditorInfos)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
var points = captureInfo.capturePointEditorInfos.Select(x => x.capturePoint).ToList();
|
|
|
|
|
|
var flagPoint = 0;
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
foreach (var pointData in captureInfo.capturePointEditorInfos)
|
2025-08-28 14:37:55 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (pointData.captureFlag)
|
|
|
|
|
|
flagPoint = pointData.capturePoint;
|
2025-08-28 14:37:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
var capture = new CaptureInfo
|
2025-11-17 15:09:39 +08:00
|
|
|
|
{
|
|
|
|
|
|
captureRegionID = captureInfo.captureRegionID,
|
|
|
|
|
|
capturePoints = points,
|
|
|
|
|
|
captureFlag = flagPoint,
|
2024-11-07 17:22:30 +08:00
|
|
|
|
CaptureProgress = captureInfo.captureProgress,
|
2025-11-17 15:09:39 +08:00
|
|
|
|
captureEffectID = captureInfo.captureEffectID,
|
|
|
|
|
|
captureEffectPoint = captureInfo.captureEffectPoint,
|
2024-11-07 17:22:30 +08:00
|
|
|
|
};
|
|
|
|
|
|
currentLevelData.CapturePoints.Add(capture);
|
|
|
|
|
|
}
|
2024-06-04 12:59:37 +08:00
|
|
|
|
|
2024-11-07 18:15:12 +08:00
|
|
|
|
// 扛旗数据
|
|
|
|
|
|
currentLevelData.flagStartPoints.Clear();
|
|
|
|
|
|
currentLevelData.flagEndPoints.Clear();
|
|
|
|
|
|
foreach (var flag in flagEditorInfo.flagStartPoints)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cellIndex = _curMap.BlockPosition2TGSCellIndex(flag);
|
|
|
|
|
|
currentLevelData.flagStartPoints.Add(cellIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var flag in flagEditorInfo.flagEndPoints)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cellIndex = _curMap.BlockPosition2TGSCellIndex(flag);
|
|
|
|
|
|
currentLevelData.flagEndPoints.Add(cellIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-11 13:46:47 +08:00
|
|
|
|
// 撤离数据
|
2025-11-17 17:47:26 +08:00
|
|
|
|
currentLevelData.retreatPoints.retreatPoints.Clear();
|
|
|
|
|
|
currentLevelData.retreatPoints.retreatFlag = -1;
|
|
|
|
|
|
foreach (var retreatPoint in retreatEditorInfo)
|
2024-11-11 13:46:47 +08:00
|
|
|
|
{
|
2025-11-17 17:47:26 +08:00
|
|
|
|
if (retreatPoint.retreatFlag)
|
|
|
|
|
|
currentLevelData.retreatPoints.retreatFlag = retreatPoint.retreatPoint;
|
|
|
|
|
|
currentLevelData.retreatPoints.retreatPoints.Add(retreatPoint.retreatPoint);
|
2024-11-11 13:46:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-25 17:02:53 +08:00
|
|
|
|
// 撤离数据
|
|
|
|
|
|
currentLevelData.enemyRetreatReusablePoints.Clear();
|
|
|
|
|
|
foreach (var fallback in enemyRetreatEditorInfo.fallbackReusablePoints)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cellIndex = _curMap.BlockPosition2TGSCellIndex(fallback);
|
|
|
|
|
|
currentLevelData.enemyRetreatReusablePoints.Add(cellIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-21 17:03:56 +08:00
|
|
|
|
// 指定路径
|
2025-06-26 14:56:16 +08:00
|
|
|
|
currentLevelData.patrolRoadData = roadEditorInfos.Select(editorInfo => new PatrolData
|
2025-02-21 17:03:56 +08:00
|
|
|
|
{
|
2025-06-26 14:56:16 +08:00
|
|
|
|
id = editorInfo.roadID,
|
|
|
|
|
|
patrolInfos = editorInfo.roadPoints,
|
2025-06-11 17:37:11 +08:00
|
|
|
|
}).ToList();
|
2025-02-21 17:03:56 +08:00
|
|
|
|
|
2025-06-26 15:25:35 +08:00
|
|
|
|
// 指定区域
|
|
|
|
|
|
currentLevelData.patrolRegionData = areaEditorInfos.Select(editorInfo => new PatrolData
|
|
|
|
|
|
{
|
|
|
|
|
|
id = editorInfo.areaID,
|
|
|
|
|
|
patrolInfos = editorInfo.areaPoints,
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
2025-06-10 18:45:59 +08:00
|
|
|
|
// 关卡进度
|
2025-12-09 16:21:59 +08:00
|
|
|
|
currentLevelData.progressGuideDatas = progressGuideDatas.Select(p => p.progressGuideData).ToList();
|
2025-06-10 18:45:59 +08:00
|
|
|
|
|
|
|
|
|
|
// 立标数据
|
2025-12-09 16:21:59 +08:00
|
|
|
|
currentLevelData.setFlagGuideDatas = setFlagEditorInfos.Select(f => f.flagGuideData).ToList();
|
2025-06-10 18:45:59 +08:00
|
|
|
|
|
|
|
|
|
|
// 信息板数据
|
2025-12-09 16:21:59 +08:00
|
|
|
|
currentLevelData.infoPanelGuideDatas = infoPanelGuideDatas.Select(i => i.infoPanelGuideData).ToList();
|
2025-06-11 17:28:44 +08:00
|
|
|
|
|
2025-12-09 16:21:59 +08:00
|
|
|
|
// 关卡广播
|
|
|
|
|
|
currentLevelData.listAIBroadcastData = listAIBroadcastData.Select(a => a.aiBroadcastData).ToList();
|
2025-07-09 13:12:36 +08:00
|
|
|
|
|
2025-08-28 14:37:55 +08:00
|
|
|
|
// 阻挡球
|
|
|
|
|
|
SaveBlockSphereInfo();
|
|
|
|
|
|
|
2023-11-21 15:04:56 +08:00
|
|
|
|
_levelEditor.SaveLevelData();
|
2025-08-28 14:37:55 +08:00
|
|
|
|
_mapManager.SaveMapData();
|
2023-11-21 15:04:56 +08:00
|
|
|
|
}
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
2024-11-07 18:15:12 +08:00
|
|
|
|
#endregion
|
2024-06-04 12:59:37 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#region 关卡ID相关
|
2024-11-18 14:34:15 +08:00
|
|
|
|
|
2024-11-12 20:31:06 +08:00
|
|
|
|
/// <summary>
|
2025-05-28 17:49:04 +08:00
|
|
|
|
/// 关卡ID 通过关卡数据 json文件名 获得
|
2024-11-12 20:31:06 +08:00
|
|
|
|
/// </summary>
|
2025-05-28 17:49:04 +08:00
|
|
|
|
[LabelText("手动指定关卡ID"), Indent, LabelWidth(100), ShowIf("needManualInputLevelID")]
|
|
|
|
|
|
[InfoBox("无法正确获得关卡ID,请手动指定")]
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
public string levelID;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
|
2024-05-29 14:03:39 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 需要手动输入关卡ID
|
|
|
|
|
|
/// </summary>
|
2024-11-18 16:50:35 +08:00
|
|
|
|
[HideInInspector] public bool needManualInputLevelID;
|
2025-12-09 19:01:17 +08:00
|
|
|
|
|
2025-05-28 17:49:04 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
#region Npc某些值改变时响应事件
|
2023-11-16 15:57:47 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void ReorderEnemyNpcID()
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
for (var i = 0; i < currentEnemyNpcInfo.Count; i++)
|
2024-11-07 18:15:12 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentEnemyNpcInfo[i].id = i + 1;
|
|
|
|
|
|
currentEnemyNpcInfo[i].npcInfo.index = currentEnemyNpcInfo[i].id;
|
2024-11-07 18:15:12 +08:00
|
|
|
|
}
|
2025-12-30 13:45:24 +08:00
|
|
|
|
|
2025-12-29 19:07:03 +08:00
|
|
|
|
// 注意:波次存储的是怪物组ID,不是NPC ID,所以不需要更新波次信息
|
2025-12-10 17:39:34 +08:00
|
|
|
|
}
|
2024-11-07 18:15:12 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void ReorderMidNpcID()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var i = 0; i < currentMidNpcInfo.Count; i++)
|
2024-11-11 13:46:47 +08:00
|
|
|
|
{
|
2025-12-29 14:41:29 +08:00
|
|
|
|
currentMidNpcInfo[i].id = MidID + i + 1;
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentMidNpcInfo[i].npcInfo.index = currentMidNpcInfo[i].id;
|
2024-11-11 13:46:47 +08:00
|
|
|
|
}
|
2025-12-10 17:39:34 +08:00
|
|
|
|
}
|
2024-11-11 13:46:47 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void ReorderSelfNpcID()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var i = 0; i < currentSelfNpcInfo.Count; i++)
|
2025-11-25 17:02:53 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
currentSelfNpcInfo[i].id = SelfID + i + 1;
|
2025-11-25 17:02:53 +08:00
|
|
|
|
}
|
2024-11-07 17:22:30 +08:00
|
|
|
|
}
|
2024-11-04 18:19:57 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void ChangeEnemyNpcID(NpcEditorInfo npcEditorInfo, int newMonsterID)
|
2024-11-07 17:22:30 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (_enemyNpcObjectWaveDic.TryGetValue(npcEditorInfo.npcInfo.waveIndex, out var npcObjectDic))
|
2023-11-16 15:57:47 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (npcObjectDic.TryGetValue(npcEditorInfo, out var npcObj))
|
2024-06-04 16:50:16 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
var newObj = LoadEnemyNpcPrefab(newMonsterID);
|
|
|
|
|
|
if (newObj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var obj = Instantiate(newObj, npcObj.transform.position, npcObj.transform.rotation);
|
|
|
|
|
|
if (enemyObjRoot == null)
|
|
|
|
|
|
enemyObjRoot = new GameObject("enemyObjRoot");
|
|
|
|
|
|
if (obj != null)
|
|
|
|
|
|
obj.transform.SetParent(enemyObjRoot.transform);
|
2024-09-05 12:28:32 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
npcEditorInfo.npcInfo.id = newMonsterID;
|
|
|
|
|
|
npcEditorInfo.level = MonsterCfg.DataMap[newMonsterID].MonsterLevel;
|
|
|
|
|
|
npcObjectDic[npcEditorInfo] = obj;
|
2025-06-30 18:46:13 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
DestroyImmediate(npcObj);
|
|
|
|
|
|
DebugUtil.Log(
|
|
|
|
|
|
$"从[ {npcEditorInfo.npcInfo.position} ]的怪物ID改为:[ {npcEditorInfo.npcInfo.id} ]");
|
2025-06-30 18:46:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void ChangeMidNpcID(NpcEditorInfo npcEditorInfo, int newMonsterID)
|
2025-06-30 18:46:13 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (_midNpcObjectWaveDic.TryGetValue(npcEditorInfo.npcInfo.waveIndex, out var npcObjectDic))
|
2025-06-30 18:46:13 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (npcObjectDic.TryGetValue(npcEditorInfo, out var npcObj))
|
2025-06-30 18:46:13 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
var newObj = LoadMidNpcPrefab(newMonsterID);
|
|
|
|
|
|
if (newObj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var obj = Instantiate(newObj, npcObj.transform.position, npcObj.transform.rotation);
|
2025-06-30 18:46:13 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (midObjRoot == null)
|
|
|
|
|
|
midObjRoot = new GameObject("midObjRoot");
|
2024-11-18 16:50:35 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (obj != null)
|
|
|
|
|
|
obj.transform.SetParent(midObjRoot.transform);
|
2025-08-28 15:12:14 +08:00
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
npcEditorInfo.npcInfo.id = newMonsterID;
|
|
|
|
|
|
npcEditorInfo.level = MonsterCfg.DataMap[newMonsterID].MonsterLevel;
|
|
|
|
|
|
npcObjectDic[npcEditorInfo] = obj;
|
|
|
|
|
|
DestroyImmediate(npcObj);
|
|
|
|
|
|
DebugUtil.Log(
|
|
|
|
|
|
$"从[ {npcEditorInfo.npcInfo.position} ]的怪物ID改为:[ {npcEditorInfo.npcInfo.id} ]");
|
2025-06-06 18:02:48 +08:00
|
|
|
|
}
|
2024-04-02 16:53:46 +08:00
|
|
|
|
}
|
2023-11-16 15:57:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
private void ChangeSelfNpcID(NPCInfo npcInfoInfo, int newMonsterID)
|
2024-11-12 20:31:06 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
if (_selfNpcObjectDic.TryGetValue(npcInfoInfo.position, out var npcObj))
|
2024-11-12 20:31:06 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
var newObj = LoadSelfNpcPrefab(newMonsterID);
|
|
|
|
|
|
if (newObj != null)
|
2024-11-12 20:31:06 +08:00
|
|
|
|
{
|
2025-12-10 17:39:34 +08:00
|
|
|
|
var obj = Instantiate(newObj, npcObj.transform.position, npcObj.transform.rotation);
|
2025-08-28 15:12:14 +08:00
|
|
|
|
|
|
|
|
|
|
if (selfObjRoot == null)
|
|
|
|
|
|
selfObjRoot = new GameObject("selfObjRoot");
|
|
|
|
|
|
|
|
|
|
|
|
if (obj != null)
|
|
|
|
|
|
obj.transform.SetParent(selfObjRoot.transform);
|
|
|
|
|
|
|
2025-12-10 17:39:34 +08:00
|
|
|
|
npcInfoInfo.id = newMonsterID;
|
|
|
|
|
|
_selfNpcObjectDic[npcInfoInfo.position] = obj;
|
2024-11-12 20:31:06 +08:00
|
|
|
|
DestroyImmediate(npcObj);
|
|
|
|
|
|
DebugUtil.Log("位置上[ {0} ]的fight怪物ID改为: [ {1} ] ", npcInfoInfo.position, npcInfoInfo.id);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-28 14:37:55 +08:00
|
|
|
|
|
2025-06-30 14:51:47 +08:00
|
|
|
|
#endregion
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|