using System; using PhxhSDK; using Gameplay; using Framework; using System.Linq; using UnityEngine; using Gameplay.Emoji; using Gameplay.Utils; using Gameplay.Common; using Gameplay.Performance; using UnityEngine.Playables; using Cysharp.Threading.Tasks; using System.Collections.Generic; using Random = UnityEngine.Random; using Constants = Framework.Constants; using cfg.VihecleCultivateCfg; using Gameplay.Net; public class TeamPreviewNode : MonoBehaviour { private const string VehicleBatteryPointName = "Battery_point01"; public Transform[] characterPos; public Transform[] vehiclesPos; public Transform cRoot; public Transform vRoot; public struct CharAddData { public uint ID; public int Idx; } public struct VehicleAddData { public uint ID; public int Idx; } public RenderTexture RTexture => _rTexture; private Dictionary _vehicleDic; private Dictionary _characterDic; private uint[] _vehicleIDs; private uint[] _charIDs; private bool _isLoading; private int _teamIdx; private bool _isReleasing; private RenderTexture _rTexture; private Dictionary _assetsLoadDic = new Dictionary(); private List _emojiMgrList = new List(); #region Static public static async UniTask LoadNode() { var prefab = await AssetManager.Instance.LoadAssetAsync(Constants.TEAM_EDIT_PREFAB_PATH); var go = Instantiate(prefab, Vector3.up, Quaternion.identity); var component = go.GetComponent(); return component; } public static void ReleaseNode(TeamPreviewNode node) { node.ReleaseRt(); Destroy(node.gameObject); } private void ReleaseRt() { if (_rTexture) { RenderTexturePool.Instance.Destroy(_rTexture); _rTexture = null; } } #endregion #region MainLife private void Awake() { _characterDic = new Dictionary(); _vehicleDic = new Dictionary(); EventManager.Instance.Register(EventManager.EventName.TeamEditCharacterModelCreate, (Action)OnCharModelCreate); EventManager.Instance.Register(EventManager.EventName.TeamEditCharacterModelClear, (Action)OnCharModelClear); EventManager.Instance.Register(EventManager.EventName.TeamEditVehicleModelCreate, (Action)OnVehicleModelCreate); EventManager.Instance.Register(EventManager.EventName.TeamEditVehicleModelClear, (Action)OnVehicleModelClear); EventManager.Instance.Register(EventManager.EventName.TeamEditAllModelClear, ClearAllGo); EventManager.Instance.Register(EventManager.EventName.TeamEditModelUpdate, RefreshNode); } private void OnDestroy() { EventManager.Instance.Unregister(EventManager.EventName.TeamEditCharacterModelCreate, (Action)OnCharModelCreate); EventManager.Instance.Unregister(EventManager.EventName.TeamEditCharacterModelClear, (Action)OnCharModelClear); EventManager.Instance.Unregister(EventManager.EventName.TeamEditVehicleModelCreate, (Action)OnVehicleModelCreate); EventManager.Instance.Unregister(EventManager.EventName.TeamEditVehicleModelClear, (Action)OnVehicleModelClear); EventManager.Instance.Unregister(EventManager.EventName.TeamEditAllModelClear, ClearAllGo); EventManager.Instance.Unregister(EventManager.EventName.TeamEditModelUpdate, RefreshNode); UnLoad(); AssetManager.Instance.Unload(Constants.TEAM_EDIT_PREFAB_PATH); } private void UnLoad() { foreach (var kv in _assetsLoadDic) { var path = kv.Key; AssetManager.Instance.Unload(path); } foreach (var emojiMgr in _emojiMgrList) { emojiMgr.Dispose(); } _emojiMgrList.Clear(); _characterDic.Clear(); _vehicleDic.Clear(); } private void ClearObjs() { cRoot.transform.ClearChilds(true); vRoot.transform.ClearChilds(true); _characterDic.Clear(); _vehicleDic.Clear(); } #endregion #region 对外方法 /// /// 刷新节点 /// public async UniTask Refresh() { ClearObjs(); var teamCamera = TeamEditCameraObj.Instance.teamEditCamera; teamCamera.targetTexture = _rTexture; for (var i = 0; i < _charIDs.Length; i++) { var dataDic = CharacterDataInfoManager.Instance.DataDic; var id = _charIDs[i]; var isValid = dataDic.ContainsKey(id); if (isValid) { var trans = characterPos[i]; if (!_isLoading) { _isLoading = true; await AddCharacterGo(trans, id, i); } } } for (var i = 0; i < _vehicleIDs.Length; i++) { var dataDic = VehicleCultivateDataManager.Instance.DataDic; var id = _vehicleIDs[i]; var isValid = dataDic.ContainsKey(id); if (isValid) { var trans = vehiclesPos[i]; if (!_isLoading) { _isLoading = true; await AddVehicleGo(trans, id, i); } } } _isLoading = false; } public void SetData(int teamIdx, uint[] charIDs, uint[] vehicleIDs) { _teamIdx = teamIdx; _charIDs = (uint[])charIDs.Clone(); _vehicleIDs = vehicleIDs; } public void CreateRt() { if (!_rTexture) { _rTexture = RenderTexturePool.Instance.Create("TeamPreviewNode", PerformanceManager.instance.fullScreenWidth, PerformanceManager.instance.fullScreenHeight); } } public void Clear() { ClearAllGo(); _rTexture.Release(); } #endregion #region 加载模型 /// /// 添加角色模型 /// async UniTask AddCharacterGo(Transform trans, uint id, int idx) { var charData = CharacterDataInfoManager.Instance.DataDic[id]; var charCfg = charData.Cfg; var skinID = charData.SkinID > 0 ? (int)charData.SkinID : Constants.DEFULT_SKINID; var data = TableManager.Instance.Tables.SkinCfg.Get(skinID, charCfg.RoleID); if (data != null) { var prefabPath = PathEx.GetCharacterDisplayModelPath(data.NameID); var prefab = await AssetManager.Instance.LoadAssetAsync(prefabPath); _assetsLoadDic.TryAdd(prefabPath, (int)id); if (!trans) { return; } var go = Instantiate(prefab, trans.position, trans.rotation, cRoot.transform); if (go) { _characterDic[idx] = go; go.SetLayerEx(LayerDefine.TeamEdit); var anim = CommonUtils.GetChildComponent(go); var playableDir = go.GetComponent(); if (playableDir) { playableDir.enabled = false; } if (anim) { int randomIdx = Random.Range(0, 3); // if (idx < 2 || idx > 4) // { // anim.Play("standready001"); // } // else // { // anim.Play("squatready001"); // } switch (randomIdx) { case 1: { anim.Play("standready001"); break; } case 2: { anim.Play("standready001"); break; } default: { anim.Play("squatready001"); break; } } } var charDataCfg = TableManager.Instance.Tables.CharacterAttri; if (charDataCfg.DataMap.TryGetValue((int)id, out var charSingleData)) { var emojiMgr = new UnitEmojiManager(go, charSingleData.EmojiEyesColor, charSingleData.EmojiEyeBowsType, charSingleData.EmojiEyeBowsColor); emojiMgr.SwitchEmoji(charSingleData.DefaultDisplayEmojiId); _emojiMgrList.Add(emojiMgr); } } } _isLoading = false; } /// /// 添加载具模型 /// async UniTask AddVehicleGo(Transform trans, uint id, int idx) { var vehicleDataDic = VehicleCultivateDataManager.Instance.DataDic; if (vehicleDataDic.TryGetValue(id, out var vehicleData)) { if (vehicleData != null) { var prefabPath = PathEx.GetVehicleGameModelPath(vehicleData.Cfg.ID); var prefab = await AssetManager.Instance.LoadAssetAsync(prefabPath); _assetsLoadDic.TryAdd(prefabPath, (int)id); if (!trans) return; var go = Instantiate(prefab, trans.position, trans.rotation, vRoot.transform); if (go) { _vehicleDic[idx] = go; go.SetLayerEx(LayerDefine.TeamEdit); go.transform.localScale = new Vector3(1.5f, 1.5f, 1.5f); // 炮台部分 var config = VehicleDataHelper.CombineConfigData(vehicleData); // 炮台挂点 var allTrans = go.GetComponentsInChildren(); var fireTrans = allTrans.First(t => t.name == VehicleBatteryPointName); var rawConfig = TableManager.Instance.Tables.BatteryConfig.GetOrDefault(config.weaponId); var batteryPath = PathEx.GetBatteryModelPath(rawConfig.ModelPath); var sampleObj = await AssetManager.Instance.LoadAssetAsync(batteryPath); if (sampleObj != null) { sampleObj.SetLayerEx(LayerDefine.TeamEdit); var rootObj = Instantiate(sampleObj, fireTrans); rootObj.transform.ResetLocals(); } else { DebugUtil.LogError("加载炮台失败: {0}", batteryPath); } //设置涂装 var paintCfg = Actor.Instance.Character.GetVehicleDevelopment(id).paint_set; if (paintCfg != null) { for (int i = 1; i < (int)PaintType.Max; i++) { var paintID = paintCfg[i]; if (paintID == 0) continue; var paintPath = PathEx.GetVehiclePaintPath((int)id, (int)paintID); //加载涂装材质球 var material = await CommonUtils.GetVehiclePaintMaterial(paintPath);//临时方法 var root = VehicleDataHelper.FindVehiclePartRoot(go, (int)id, (PaintType)i); if (material != null && root != null) { var renderers = root.GetComponent(); renderers.materials = new Material[] { material }; } } } else DebugUtil.LogError("载具涂装配置为空!"); } } } _isLoading = false; } /// /// 根据索引加载角色模型 /// private async UniTask LoadCharacterModel(uint id, int idx) { // DebugUtil.LogError("需要在:{0}加上{1}角色", idx, id); if (idx < 0) return; if (_isLoading) return; if (_charIDs[idx] != id) { ClearCharacterGo(idx); _charIDs[idx] = id; _isLoading = true; await AddCharacterGo(characterPos[idx], id, idx); } } /// /// 根据索引加载载具模型 /// private async UniTask LoadVehicleModel(uint id, int idx) { //DebugUtil.LogError("需要在:{0}加上{1}载具", idx, id); if (idx < 0) return; if (_isLoading) return; if (_vehicleIDs[idx] != id) { ClearVehicleGo(idx); _vehicleIDs[idx] = id; _isLoading = true; await AddVehicleGo(vehiclesPos[idx], id, idx); } /*DebugUtil.LogError("添加完{0}位置,载具的关系:-------", idx); for (int i = 0; i < _vehicleIDs.Length; i++) { DebugUtil.LogError("{0}位置是{1}", i, _vehicleIDs[i]); } DebugUtil.LogError("-----------------------");*/ } #endregion #region 清除模型 /// /// 指挥官清空后使用 /// private void ClearAllGo() { for (int i = 0; i < characterPos.Length; i++) { ClearCharacterGo(i); } for (int i = 0; i < vehiclesPos.Length; i++) { ClearVehicleGo(i); } } private void ClearCharacterGo(int idx) { if (_isLoading) { return; } _isLoading = true; if (_characterDic.TryGetValue(idx, out var go)) { if (go) { DestroyImmediate(go); _charIDs[idx] = Team.NoneID; _characterDic.Remove(idx); } } _isLoading = false; } private void ClearVehicleGo(int idx) { if (_isLoading) { return; } _isLoading = true; if (_vehicleDic.TryGetValue(idx, out var go)) { if (go) { DestroyImmediate(go); _vehicleIDs[idx] = Team.NoneID; _vehicleDic.Remove(idx); } } _isLoading = false; } #endregion #region 事件监听 private async void RefreshNode(int teamIdx) { var team = TeamEditManager.Instance.GetTeamByIndex(teamIdx); if (team == null) return; var charIDs = team.GetAllCharacters().ToArray(); var vehicleIDs = team.GetVehicleIDs().ToArray(); SetData(teamIdx, charIDs, vehicleIDs); await Refresh(); } private async void OnCharModelCreate(CharAddData charAddData) { await LoadCharacterModel(charAddData.ID, charAddData.Idx); } private void OnCharModelClear(int idx) { if (idx >= 0) { ClearCharacterGo(idx); } } private async void OnVehicleModelCreate(VehicleAddData vehicleAddData) { await LoadVehicleModel(vehicleAddData.ID, vehicleAddData.Idx); } private void OnVehicleModelClear(int idx) { if (idx >= 0) { ClearVehicleGo(idx); } } #endregion }