修复音频报错,增加地图编辑器

This commit is contained in:
wuwenbo 2025-12-31 17:11:45 +08:00
parent 435e334121
commit d77df89ddd
11 changed files with 404 additions and 32 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5fc75ba2ac9c4aa44be95bcd6889dd8f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -106,12 +106,7 @@ namespace Logic.Audio
if (!_clips.ContainsKey(musicName) || _clips[musicName].Count == 0) return;
if (_musicPlayer != null) StopMusic();
else _musicPlayer = GetPlayer();
if (_clips[musicName].Count > 1)
{
_musicPlayer.Clip = _clips[musicName][1];
_clips[musicName].RemoveAt(1);
}
else _musicPlayer.Clip = Object.Instantiate(_clips[musicName][0]);
_musicPlayer.Clip = _clips[musicName][0];
if (!_musicPlayer.Clip)
{
LogSystem.LogError($"音乐资源 {musicName} 未找到或加载失败!");
@ -129,19 +124,20 @@ namespace Logic.Audio
public void StopMusic()
{
if (_musicPlayer == null) return;
if (_musicPlayer.Stop()) _musicRecord[_musicPlayer.MusicName] = _musicPlayer.Source.time + _musicPlayer.FadeOutDuration;
if (_musicPlayer.Stop())
{
// 确保记录的时间不超过音频长度
float currentTime = _musicPlayer.Source.time + _musicPlayer.FadeOutDuration;
float maxTime = _musicPlayer.Length - 0.5f;
_musicRecord[_musicPlayer.MusicName] = Mathf.Clamp(currentTime, 0, Mathf.Max(0, maxTime));
}
}
public void PlayAudio(string musicName, float fadeIn = 0f, float fadeOut = 0f, bool isLoop = false)
{
if (!_clips.ContainsKey(musicName)) return;
var player = GetPlayer();
if (_clips[musicName].Count > 1)
{
player.Clip = _clips[musicName][1];
_clips[musicName].RemoveAt(1);
}
else player.Clip = Object.Instantiate(_clips[musicName][0]);
player.Clip = _clips[musicName][0];
if (!player.Clip)
{
LogSystem.LogError($"音频资源 {musicName} 未找到或加载失败!");
@ -273,26 +269,26 @@ namespace Logic.Audio
}
StartTime = Time.time;
Source.time = 0;
Source.clip = Clip;
// 确保 recordTime 在有效范围内,留一点余量避免边界问题
float maxSeekTime = Mathf.Max(0, Clip.length - 0.1f);
recordTime = Mathf.Clamp(recordTime, 0, maxSeekTime);
Source.volume = 0;
Source.loop = IsLoop;
Source.Play();
// 先播放再设置时间,某些音频格式需要这样
if (recordTime > 0 && Clip.loadState == AudioDataLoadState.Loaded)
Source.Play();
// 设置播放位置(在 Play 之后)
if (recordTime > 0 && Clip.length > 0)
{
try
float maxSeekTime = Clip.length - 0.5f;
if (maxSeekTime > 0 && recordTime < maxSeekTime)
{
Source.time = recordTime;
}
catch
{
Source.time = 0;
try
{
Source.time = recordTime;
}
catch (System.Exception e)
{
LogSystem.LogWarning($"AudioPlayer: 设置播放位置失败 - {e.Message}");
}
}
}

View File

@ -181,16 +181,17 @@ namespace TH1_Logic.Core
}
// 继续单机游戏
public void ContinueGame()
public void ContinueGame(MapData map = null)
{
//如果没有存档,退出
if (!HasArchive()) return;
//step #1 初始化Audio
InitGameAudio();
//step #2 读取存档的map
MapData = MapData.GetMapData();
if (map != null) MapData = map;
else MapData = MapData.GetMapData();
MapData.PlayerMap.SelfPlayerId = MapData.PlayerMap.PlayerDataList[0].Id;
AIActionScoreCalculator.RefreshCalMap(MapData, true);
@ -211,7 +212,6 @@ namespace TH1_Logic.Core
System.GC.WaitForPendingFinalizers();
}
// 开始单机游戏
public void StartGame()
{

View File

@ -0,0 +1,55 @@
/*
* @Author:
* @Description:
* @Date: 20251231 16:12:59
* @Modify:
*/
using UnityEditor;
using UnityEngine;
public class SaveMapDialog : EditorWindow
{
private string _name;
private string _defaultName;
private System.Action<string> _onConfirm;
public static void Show(string title, string name, string defaultName, System.Action<string> onConfirm)
{
var window = CreateInstance<SaveMapDialog>();
window.titleContent = new GUIContent(title);
window._name = name;
window._defaultName = defaultName;
window._onConfirm = onConfirm;
window.minSize = new Vector2(300, 80);
window.maxSize = new Vector2(300, 80);
window.ShowModalUtility();
}
private void OnGUI()
{
EditorGUILayout.Space(10);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(_name, GUILayout.Width(60)); // 改为 _name
_defaultName = EditorGUILayout.TextField(_defaultName); // 用户输入更新到 _defaultName
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space(10);
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("确定", GUILayout.Width(80)))
{
_onConfirm?.Invoke(_defaultName); // 传递用户输入的值
Close();
}
if (GUILayout.Button("取消", GUILayout.Width(80)))
{
Close();
}
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e1b995e574fc4a35be1807905f516812
timeCreated: 1767169008

View File

@ -0,0 +1,208 @@
/*
* @Author:
* @Description:
* @Date: 20250422 15:04:14
* @Modify:
*/
using System.Collections.Generic;
using System.IO;
using Logic.Achievement;
using Logic.CrashSight;
using Logic.HeroTask;
using Logic.Multilingual;
using NUnit.Framework;
using RuntimeData;
using TH1_Logic.Core;
using TH1_Logic.HeroTask;
using UnityEditor;
using UnityEngine;
namespace Logic.Editor
{
public class MapEditorWindow : EditorWindow
{
// 滑条
private Vector2 _barPosition;
// 背景
private GUIStyle _redBoxStyle;
private GUIStyle _whiteBoxStyle;
private List<string> _mapNameList;
private string _selectedMapName;
[MenuItem("Tools/地图编辑器")]
private static void ShowWindow()
{
var window = CreateWindow<MapEditorWindow>();
window.titleContent = new GUIContent("地图编辑器");
window.Show();
}
protected virtual void OnEnable()
{
EditorApplication.update += OnEditorUpdate;
RefreshMapNameList();
}
private void OnDisable()
{
EditorApplication.update -= OnEditorUpdate;
}
private void OnEditorUpdate()
{
// 每帧刷新窗口
Repaint();
}
private void OnGUI()
{
var grid = MapRecordManager.Instance.RecordGridData;
if (_redBoxStyle == null)
{
_redBoxStyle = InspectorUtils.GetHelpBoxStyle();
InspectorUtils.AddBorder(_redBoxStyle, new Color(0.5f, 0.4f, 0.4f, 0.6f));
}
if (_whiteBoxStyle == null)
{
_whiteBoxStyle = InspectorUtils.GetHelpBoxStyle();
InspectorUtils.AddBorder(_whiteBoxStyle, new Color(1f, 1f, 1f, 0.2f));
}
GUI.skin.button.wordWrap = true;
_barPosition = EditorGUILayout.BeginScrollView(_barPosition);
EditorGUILayout.BeginHorizontal();
if (InspectorUtils.InspectorButtonWithTextWidth("刷新"))
{
RefreshMapNameList();
grid?.Renderer(Main.MapData)?.InstantUpdateGrid();
}
if (InspectorUtils.InspectorButtonWithTextWidth("保存当前地图"))
{
string defaultName = string.IsNullOrEmpty(_selectedMapName) ? "NewMap" : _selectedMapName;
// 使用 EditorApplication.delayCall 延迟到布局结束后再显示对话框
EditorApplication.delayCall += () =>
{
SaveMapDialog.Show($"保存确认", $"地图名称", defaultName, (string value) =>
{
if (!string.IsNullOrEmpty(value))
{
MapRecordManager.Instance.SaveMapRecord(Main.MapData, value);
_selectedMapName = value;
RefreshMapNameList();
}
});
};
}
EditorGUILayout.EndHorizontal();
// 切换存储地图
EditorGUILayout.BeginHorizontal();
if (_mapNameList == null || _mapNameList.Count == 0)
{
InspectorUtils.InspectorTextWidthRich($"<b> 暂无已存储地图 </b>");
}
else
{
InspectorUtils.InspectorTextWidthRich($"<b> 选择地图 : </b>");
var index = GetIndexInMapNameList(_selectedMapName);
index = EditorGUILayout.Popup(index, _mapNameList.ToArray(), GUILayout.Width(300));
_selectedMapName = _mapNameList[index];
if (InspectorUtils.InspectorButtonWithTextWidth("切换"))
{
var map = MapRecordManager.Instance.LoadMapRecord(_selectedMapName);
Main.Instance.ContinueGame(map);
}
}
EditorGUILayout.EndHorizontal();
OnGUIGridData();
EditorGUILayout.EndScrollView();
}
private void OnGUIGridData()
{
var grid = MapRecordManager.Instance.RecordGridData;
if (grid == null) return;
EditorGUILayout.BeginVertical(_whiteBoxStyle);
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> ID : </b> {grid.Id} ");
InspectorUtils.InspectorTextWidthRich($"<b> 位置 : </b> x {grid.Pos.X} y {grid.Pos.Y} ");
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> CivId : </b> ");
grid.CivId = (uint)EditorGUILayout.IntField((int)grid.CivId, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> Terrain : </b> ");
grid.Terrain = (TerrainType) EditorGUILayout.EnumPopup(grid.Terrain, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> Feature : </b> ");
grid.Feature = (TerrainFeature) EditorGUILayout.EnumPopup(grid.Feature, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> Vegetation : </b> ");
grid.Vegetation = (Vegetation) EditorGUILayout.EnumPopup(grid.Vegetation, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> Resource : </b> ");
grid.Resource = (ResourceType) EditorGUILayout.EnumPopup(grid.Resource, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> Wonder : </b> ");
grid.Wonder = (WonderLibrary) EditorGUILayout.EnumPopup(grid.Wonder, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b> ResourceUnderBuilding : </b> ");
grid.ResourceUnderBuilding = (ResourceType) EditorGUILayout.EnumPopup(grid.ResourceUnderBuilding, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
private void RefreshMapNameList()
{
_mapNameList ??= new List<string>();
_mapNameList.Clear();
string folderPath = "Assets/Resources/MapRecord";
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
string[] files = Directory.GetFiles(folderPath, "*.bytes");
foreach (string file in files)
{
string fileName = Path.GetFileNameWithoutExtension(file);
if (!string.IsNullOrEmpty(fileName))
{
_mapNameList.Add(fileName);
}
}
LogSystem.LogInfo($"Init: 扫描完成,找到 {_mapNameList.Count} 个地图记录");
}
private int GetIndexInMapNameList(string name)
{
if (_mapNameList == null) return 0;
for (int i = 0; i < _mapNameList.Count; i++)
{
if (_mapNameList[i] == name) return i;
}
return 0;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 21c511dbd95449c49b3da0816a319807
timeCreated: 1767165289

View File

@ -64,7 +64,7 @@ namespace Logic
public void OnTileClicked(MapData mapData,GridData gridData)
{
MapRecordManager.Instance.RecordGridData = gridData;
AudioManager.Instance.PlayAudio("SFX/UNIT_click",0,0,false);
//如果当前是AI正在进行我方不可点击格子操作格子不会相应

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e00554aa172645f583dbc6f276651145
timeCreated: 1767080984

View File

@ -0,0 +1,93 @@
/*
* @Author:
* @Description:
* @Date: 20250905 15:09:36
* @Modify:
*/
using System.Collections.Generic;
using System.IO;
using Logic.CrashSight;
using MemoryPack;
using RuntimeData;
using UnityEngine;
namespace Logic
{
public class MapRecordManager
{
public static MapRecordManager Instance = new MapRecordManager();
public List<string> MapNameList;
public GridData RecordGridData;
// 保存 Map 到 Resource 文件夹下
public void SaveMapRecord(MapData map, string name)
{
if (map == null)
{
LogSystem.LogWarning("SaveMapRecord: map 为 null无法保存");
return;
}
if (string.IsNullOrEmpty(name))
{
LogSystem.LogWarning("SaveMapRecord: name 为空,无法保存");
return;
}
#if UNITY_EDITOR
try
{
// 确保文件夹存在
string folderPath = Path.Combine(Application.dataPath, "Resources", "MapRecord");
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
string filePath = Path.Combine(folderPath, $"{name}.bytes");
byte[] bytes = MemoryPackSerializer.Serialize(map);
File.WriteAllBytes(filePath, bytes);
// 刷新 AssetDatabase
UnityEditor.AssetDatabase.Refresh();
LogSystem.LogInfo($"SaveMapRecord: 地图 {name} 保存成功,路径: {filePath}");
}
catch (System.Exception e)
{
LogSystem.LogWarning($"SaveMapRecord: 保存失败 - {e.Message}");
}
#endif
}
// 读取 Map 从 Resource 文件夹下
public MapData LoadMapRecord(string name)
{
if (string.IsNullOrEmpty(name))
{
LogSystem.LogWarning("LoadMapRecord: name 为空,无法加载");
return null;
}
try
{
string resourcePath = $"MapRecord/{name}";
TextAsset textAsset = Resources.Load<TextAsset>(resourcePath);
if (textAsset == null)
{
LogSystem.LogWarning($"LoadMapRecord: 未找到资源 {resourcePath}");
return null;
}
MapData map = MemoryPackSerializer.Deserialize<MapData>(textAsset.bytes);
LogSystem.LogInfo($"LoadMapRecord: 地图 {name} 加载成功");
return map;
}
catch (System.Exception e)
{
LogSystem.LogWarning($"LoadMapRecord: 加载失败 - {e.Message}");
return null;
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 54fa5862d8aa47d6bec5037966d979b7
timeCreated: 1767081016