using System; using System.Collections.Generic; using Framework; using Gameplay.Level; using Gameplay.Performance; using Gameplay.Unit; using Gameplay.Vehicle.Impl; using PhxhSDK; using UnityEngine.Rendering; using Constants = Framework.Constants; namespace Gameplay.Vehicle.TireMark { using UnityEngine; public class TireMarkManager { private static TireMarkManager _instance; public static TireMarkManager instance { get { return _instance; } } public static void CreateInstance() { if (_instance != null) { DebugUtil.LogError("请勿重复创建TireMarkManager"); return; } _instance = new TireMarkManager(); } private float _unitSize = 50; public Transform rootTrans; private List _panels; private List _recorders; private List _drawDatas; public List drawDatas { get { return _drawDatas; } } public Material drawMat; private TireMarkManager() { _panels = new List(); _recorders = new List(); _drawDatas = new List(); } public void Init() { if (!PerformanceManager.instance.data.enableTireMark) return; // 获取地图大小 var map = LevelManager.Instance.CurrentLevel.Map; var tgsMap = map.TerrainGridSystem; var bounds = tgsMap.bounds; var xSize = bounds.size.x; var zSize = bounds.size.z; rootTrans = new GameObject("TireMarkManager").transform; // 创建平铺面板 var masSize = Mathf.Max(xSize, zSize); _unitSize = masSize; var panelSize = _unitSize; var xCount = Mathf.CeilToInt(xSize / panelSize); var zCount = Mathf.CeilToInt(zSize / panelSize); var startX = bounds.min.x + panelSize / 2; var startZ = bounds.min.z + panelSize / 2; var sampleObj = AssetManager.Instance.GetPreLoadResult(Constants.TIREMARK_UNIT_PATH); for (int i = 0; i < xCount; i++) { for (int j = 0; j < zCount; j++) { var createPos = new Vector3(startX + i * panelSize, 0.1f, startZ + j * panelSize); var instObj = Object.Instantiate(sampleObj, createPos, Quaternion.identity, rootTrans); instObj.name = "TireMarkUnit_" + i + "_" + j; instObj.transform.localScale = new Vector3(panelSize, 1, panelSize); var panel = new TireMarkPanel(instObj); panel.Init(); _panels.Add(panel); } } // 创建渲染用的材质 drawMat = AssetManager.Instance.GetPreLoadResult(Constants.TIREMARK_MAT_PATH); _RegistEvents(); } public void Dispose() { if (!PerformanceManager.instance.data.enableTireMark) return; _UnRegistEvents(); // 卸载资源 for (int i = 0; i < _panels.Count; i++) { var panel = _panels[i]; panel.Dispose(); } rootTrans.gameObject.Destroy(); AssetManager.Instance.Unload(Constants.TIREMARK_MAT_PATH); AssetManager.Instance.Unload(Constants.TIREMARK_UNIT_PATH); _panels = null; _instance = null; _recorders = null; _drawDatas = null; } private void _RegistEvents() { EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_READY, (Action)_OnUnitReady); } private void _UnRegistEvents() { EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_READY, (Action)_OnUnitReady); } private void _OnUnitReady(GameUnit unit) { if (!PerformanceManager.instance.data.enableTireMark) return; if (unit is NormalVehicle vehicle) { RegistVehicle(vehicle); } } public async void RegistVehicle(NormalVehicle vehicle) { if (!PerformanceManager.instance.data.enableTireMark) return; var vehicleObj = vehicle.Node.GameObject.transform; // var tailpoints = vehicleObj.Find("tailpoints"); var tireMarkId = vehicle.configData.tireMarkId; if (tireMarkId == 0) return; var tireMarkConfig = TableManager.Instance.Tables.TireMarkConfig.DataMap[tireMarkId]; var texturePath = tireMarkConfig.TexturePath; var texture = await AssetManager.Instance.LoadAssetAsync(texturePath); if (texture == null) { DebugUtil.LogError("加载tireMark贴图失败: {0}", texturePath); return; } var recorder = new TireMarkRecorder(vehicleObj); recorder.texture2D = texture; recorder.rawConfig = tireMarkConfig; RegistRecorder(recorder); } public void RegistRecorder(TireMarkRecorder recorder) { if (!PerformanceManager.instance.data.enableTireMark) return; recorder.Init(); _recorders.Add(recorder); } public void LogicUpdate(float dt) { if (!PerformanceManager.instance.data.enableTireMark) return; for (int i = 0; i < _recorders.Count; i++) { var recorder = _recorders[i]; recorder.LogicUpdate(dt); if (recorder.canDraw) { _drawDatas.Add(recorder.drawData); } } } private void _DrawDrawData(TireMarkDrawData drawData, CommandBuffer cmd) { if (!PerformanceManager.instance.data.enableTireMark) return; drawData.needCalc = true; for (int i = 0; i < _panels.Count; i++) { var panel = _panels[i]; panel.Draw(drawData, cmd, i); } } public void DrawDatas(CommandBuffer cmd) { if (!PerformanceManager.instance.data.enableTireMark) return; for (int i = 0; i < _drawDatas.Count; i++) { _DrawDrawData(_drawDatas[i], cmd); } _drawDatas.Clear(); } } }