#unity/白日梦/代码缓存 ``` cs using System; using System.Collections.Generic; using System.IO; using EntranceModule.M; using LightUtility; using Sirenix.OdinInspector; using Unity.MeshSync; using UnityEditor; using UnityEngine; using ResourcesModule.LMNA; using Unity.MeshSync.Editor; using UnityEditor.Animations; using UnityEditor.SceneManagement; using UnityEngine.Playables; using UnityEngine.Timeline; using UnityEngine.UIElements; using Button = UnityEngine.UI.Button; namespace MeshSyncToolModule.M { public class MeshSyncEditorUI : MeshSyncDataPool { #region MeshSyncUI界面 private static MeshSyncEditorUI _meshSyncEditorUI; // private string[] RoleStyle = new string[] {"Police,Thief"}; private string SuitID = String.Empty; //服装ID private string PropID = String.Empty; //表情ID private MeshSyncmanager meshSyncmanager; [MenuItem("GameObject/3DMax同步")] public static void ShowWindow() { EditorSceneManager.OpenScene("Assets/Scripts/MThread/Common/ToolsModule/MeshSyncToolModule/Editor/MeshSyncFolder/MeshSyncScene.unity"); // MeshSyncMenu.CreateMeshSyncServerMenu(null); // if (_meshSyncEditorUI == null) { _meshSyncEditorUI = GetWindow(typeof(MeshSyncEditorUI)) as MeshSyncEditorUI; _meshSyncEditorUI.Init(); } if (MeshSyncServer == null) { MeshSyncServer = GameObject.Find("MeshSyncServer"); } _meshSyncEditorUI.Show(); } [ValueDropdown("TreeViewOfInts", ExpandAllMenuItems = false)] public int InterTreeView = 1; private ValueDropdownList TreeViewOfInts = new ValueDropdownList { { "请选择警察或小偷", 1 } }; [ShowIf("@InterTreeView>1")] [Button("确定")] public void Confirm() { smrDic.Clear(); currentPrefabPath = CharactersPathDic[InterTreeView].Substring(CharactersPathDic[InterTreeView].IndexOf("Assets")); currentPrefabPath = currentPrefabPath.Replace('\\', '/') + "/Prefabs/"; currentRelatedResourcesPath = CharactersPathDic[InterTreeView].Substring(CharactersPathDic[InterTreeView].IndexOf("Assets")); currentRelatedResourcesPath = currentRelatedResourcesPath.Replace('\\', '/') + "/RelatedResources/"; if (!Directory.Exists(currentPrefabPath)) { Debug.Log("路径不存在:" + currentPrefabPath); return; } string[] belongNameList = TreeViewOfInts[InterTreeView-1].Text.Split('/'); SuitID = belongNameList[belongNameList.Length - 1]; string PropPrefabsPath = PropPrefabPath + belongNameList[belongNameList.Length - 2] + "/PropPrefabs/"; //表情动作路径 string CharacterPath = CharactersPath + belongNameList[belongNameList.Length - 2] + "/SkinParts/" + belongNameList[belongNameList.Length - 1] + "/Prefabs"; //角色路径 //场景加载 string currentEffectGoPath = currentRelatedResourcesPath + LMNAResMapUtil.AssembleAssetName(SuitID+"_LobbyScene_Height",eAssetFunctionType.GameObject,eAssetLodLevel.None) + ".prefab"; currentEffect = Instantiate(AssetDatabase.LoadAssetAtPath(currentEffectGoPath)); if (currentEffect != null) { currentEffect.transform.rotation = Quaternion.Euler(0, 0, 0); currentEffect.AddComponent(); currentEffect.GetComponent().GetComponent().enabled = false; } GameObject MeshSyncmanager = new GameObject("MeshSyncmanager"); meshSyncmanager = MeshSyncmanager.AddComponent(); meshSyncmanager.AddAnims(SetAnimPath(currentRelatedResourcesPath + LMNAResMapUtil.AssembleAssetName( SuitID + "_LobbyCameraAnimation_Height", eAssetFunctionType.AnimationClip, eAssetLodLevel.None) + ".anim")); meshSyncmanager.GetCamera(GameObjectCamera); meshSyncmanager.GetTouchImg(GameObject.Find("TouchImg")); meshSyncmanager.GetBackGround(GameObject.Find("BackGroundImg")); meshSyncmanager.GetRestart(GameObject.Find("ReStartBtn")); //相机动画 // MeshSyncmanager.Inst.GetAnim(SetAnimPath(currentRelatedResourcesPath + LMNAResMapUtil.AssembleAssetName( // SuitID + "_LobbyCameraAnimation_Height", // eAssetFunctionType.AnimationClip, // eAssetLodLevel.None) + // ".anim")); //实例化局外灯光 CreateLight(); // string AssetPath = SkinPartConfigs + belongNameList[belongNameList.Length - 2] + "/SkinPartConfigs/sco&" + SuitID + ".asset"; // SuitePartSetting asset = AssetDatabase.LoadAssetAtPath(AssetPath,typeof(SuitePartSetting)) as SuitePartSetting; // for (int i = 0; i < asset.SkinRelatedResources.Count; i++) // { // if (asset.SkinRelatedResources[i].key == SkinResourceKey.LobbyScene) // { // string goPath = currentRelatedResourcesPath + // LMNAResMapUtil.AssembleAssetName(asset.SkinRelatedResources[i].prefabNameHeight,eAssetFunctionType.GameObject,eAssetLodLevel.None) + // ".prefab"; // currentEffect = Instantiate(AssetDatabase.LoadAssetAtPath(goPath)); // currentEffect.transform.rotation = Quaternion.Euler(0, -180, 0); // currentEffect.AddComponent(); // // currentEffect.GetComponent().GetComponent().enabled = false; // // } // else if (asset.SkinRelatedResources[i].key == SkinResourceKey.LobbyCameraAnimation) // { // currentLobbyCameraAnimationPath = // currentRelatedResourcesPath + LMNAResMapUtil.AssembleAssetName( // asset.SkinRelatedResources[i].prefabNameHeight, eAssetFunctionType.AnimationClip, // eAssetLodLevel.None) + // ".anim"; // // } // } //实例化 表情动作 string[] propGuidMat = AssetDatabase.FindAssets("t:Prefab", new[] {currentPrefabPath}); //遍历对应Prefab预制体guid列表,只拿其中一个prefab的数据就好(有可能存在多个分级的 预制体资源) for (int i = 0; i < propGuidMat.Length; i++) { string guid = propGuidMat[i]; string goPath = AssetDatabase.GUIDToAssetPath(guid); GameObject go = AssetDatabase.LoadAssetAtPath(goPath); SkinnedMeshRenderer[] smr = go.GetComponentsInChildren(); for (int j = 0; j < smr.Length; j++) { List materials = new List(smr[j].sharedMaterials); if (!smrDic.ContainsKey(smr[j].name.ToLower())) { smrDic.Add(smr[j].name.ToLower(), materials); } } break; } PropID = GetEmotionID(SuitID); //遍历表情动作guid列表,有可能存在不同编号的表情动作中,所以需要遍历全部 string[] propGuidsObject = AssetDatabase.FindAssets("t:Prefab", new[] {PropPrefabsPath}); List LogicNameList = new List(); for (int i = 0; i < propGuidsObject.Length; i++) { string guid = propGuidsObject[i]; string goPath = AssetDatabase.GUIDToAssetPath(guid); GameObject go = AssetDatabase.LoadAssetAtPath(goPath); // SkinnedMeshRenderer[] smr = go.GetComponentsInChildren(); // for (int j = 0; j < smr.Length; j++) // { // List materials = new List(smr[j].sharedMaterials); // if (!smrDic.ContainsKey(smr[j].name.ToLower())) // { // smrDic.Add(smr[j].name.ToLower(), materials); // } // } //实例化表情动作角色 if (PropID != String.Empty) { string logicName = go.name.Split('@')[1]; if (go.name.Contains(PropID) && !LogicNameList.Contains(logicName)) { GameObjectProp = Instantiate(go); GameObjectProp.transform.rotation = new Quaternion(0, 180, 0, 0); LogicNameList.Add(logicName); Transform[] GameObjectPropChildren = GameObjectProp.GetComponentsInChildren(); Transform newCamera = null; for (int j = 0; j < GameObjectPropChildren.Length; j++) { if (GameObjectPropChildren[j].name == "3DObjectCamera") { newCamera = GameObjectPropChildren[j]; break; } } if (newCamera != null) { GameObjectCamera = newCamera.gameObject; } IdleManager.Instance.CameraOffCenterProjection = GameObjectCamera.AddComponent(); // Animation anim = GameObjectProp.GetComponent(); // anim.wrapMode = WrapMode.Loop; } } } //加载 角色动画 // string characterAnimPath = // PropPrefabPath + belongNameList[belongNameList.Length - 2] + "/Animations/" + // LMNAResMapUtil.AssembleAssetName( // "lob_" + belongNameList[belongNameList.Length - 2] + "@" + PropID + ".anim", // eAssetFunctionType.AnimationClip, eAssetLodLevel.None); string newPath = CharactersPath + belongNameList[belongNameList.Length - 2] + "/SkinParts/" + SuitID + "/RelatedResources/"; AnimationClip characterClip = AssetDatabase.LoadAssetAtPath(GetCharacterClip(belongNameList)); if (characterClip != null) { characterClip.legacy = true; //实例化 角色模型 string[] characterGuidObject = AssetDatabase.FindAssets("t:Prefab", new[] {CharacterPath}); //遍历对应Prefab预制体guid列表,只拿其中一个prefab的数据就好(有可能存在多个分级的 预制体资源) for (int i = 0; i < characterGuidObject.Length; i++) { string guid = characterGuidObject[i]; string goPath = AssetDatabase.GUIDToAssetPath(guid); GameObject go = AssetDatabase.LoadAssetAtPath(goPath); //实例化表情动作角色 if (SuitID != String.Empty) { if (go.name.Contains(SuitID)) { GameObjectCharacter = Instantiate(go); GameObjectIdleManager = GameObject.Find("IdleManager"); GameObjectIdleTimeLine = GameObject.Find("IdleManager/IdleTimeLine"); TimeLineLogicManager(); GameObjectCharacter.transform.rotation = new Quaternion(0, 180, 0, 0); GameObjectCharacter.transform.parent = GameObjectIdleTimeLine.transform; GameObjectIdleTimeLine.SetActive(false); meshSyncmanager.AddAnims(GameObjectCharacter.GetComponent()); //找到所有的HeadBoneAttach组件,将Attachmentment节点挂载到HeadBoneName节点下 HeadBoneAttach[] headBoneAttaches = GameObjectCharacter.GetComponentsInChildren(); for (int j = 0; j < headBoneAttaches.Length; j++) { headBoneAttaches[j].m_Attachment.parent = GameObjectCharacter.transform.FindTransform(headBoneAttaches[j].m_HeadBoneName); } } } break; } if (GameObjectCharacter != null) { AnimationClip newClip = new AnimationClip(); EditorUtility.CopySerialized(characterClip, newClip); newClip.legacy = false; GameObjectCharacter.AddComponent().clip = newClip; GameObjectCharacter.AddComponent(); IdleManager.Instance.InitIdleAnimation(GameObjectProp); // GameObjectCharacter.GetComponent().AddClip(characterClip, characterClip.name); // meshSyncmanager.AddAnims(GameObjectCharacter.GetComponent()); // newAnimator.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath( // "Assets/MeshSyncFolder/MeshSyncController.controller"); // newAnimator.Play("Idle"); // AnimatorOverrideController animatorController = new AnimatorOverrideController(); // animatorController["Idle"] = characterClip; // newAnimator.runtimeAnimatorController = animatorController; } } RefreshMatrialData(); if (Directory.Exists("Assets/MeshSyncAssets")) { Directory.Delete("Assets/MeshSyncAssets",true); //清空生成数据 } // _meshSyncEditorUI.Close(); } [Title("如果需要新增资源,需要填写以下俩信息")] [Title("警察 或 小偷 编号")] public string RoleIndex; [Title("序号")] public string NumberIndex; /// /// 判断角色id和编号是否为空 /// /// public bool JudgeRoleAndNumber() { if (RoleIndex == null || NumberIndex == null) { return false; } return true; } /// /// 判断表情动作和timeline是否存在 /// /// public bool JudgeEmotionAndDirector() { if (GameObjectProp != null && GameObjectProp.GetComponent() != null) { return true; } return false; } private void CreateLight() { //实例化局外灯光 if (GameObjectLight == null) { GameObjectLight = Instantiate(AssetDatabase.LoadAssetAtPath(LobbyLightPrefabPath)); GameObjectLight.transform.rotation = new Quaternion(GameObjectLight.transform.rotation.x, GameObjectLight.transform.rotation.y + 180, GameObjectLight.transform.rotation.z, GameObjectLight.transform.rotation.w); } } [ShowIf("@JudgeEmotionAndDirector()")] [Button("播放动画")] public void DirectorPlay() { GameObjectProp.GetComponent().Play(); } [ShowIf("@JudgeEmotionAndDirector()")] [Button("暂停播放")] public void DirectorPause() { GameObjectProp.GetComponent().Pause(); } [ShowIf("@JudgeEmotionAndDirector()")] [Button("停止播放")] public void DirectorStop() { GameObjectProp.GetComponent().Stop(); } // [ShowIf("@RoleIndex != string.Empty && NumberIndex > 0")] [ShowIf("@JudgeRoleAndNumber()")] [Button("新增资源")] public void AddResource() { SetAnimPath( $"Assets/BundleResources/CommonRegion/OutsideGame/Skins/Characters/{RoleIndex}/SkinParts/{NumberIndex}/RelatedResources/ani&{NumberIndex}_LobbyCameraAnimation_Height.anim"); // currentLobbyCameraAnimationPath = // $"Assets/BundleResources/CommonRegion/OutsideGame/Skins/Characters/{RoleIndex}/SkinParts/{NumberIndex}/RelatedResources/ani&{NumberIndex}_LobbyCameraAnimation_Height.anim"; string path = currentLobbyCameraAnimationPath.Substring(0, currentLobbyCameraAnimationPath.LastIndexOf(@"/")); Debug.Log("所在路径是:" + path); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } CreateLight(); } // // [Button("关闭")] // public void CloseMeshSync() // { // MeshSyncServer_Smr = null; // smrDic.Clear(); // // IntTreviewIndex = 1; // newCharactersPath = ""; // currentPrefabPath = ""; // currentRelatedResourcesPath = ""; // currentLobbyCameraAnimationPath = ""; // // // DestroyImmediate(GameObjectLight); // DestroyImmediate(currentEffect); // // DestroyImmediate(MeshSyncServer); // // if (Directory.Exists("Assets/MeshSyncAssets")) // { // Directory.Delete("Assets/MeshSyncAssets",true); //清空生成数据 // } // // // _meshSyncEditorUI.Close(); // } #endregion #region MeshSync功能逻辑 public void Init() { AddTreeDirectory(CharactersPath, PoliceName,PoliceName); AddTreeDirectory(CharactersPath, ThiefName,ThiefName); } private string AddTreeViewOfInts(string frontName,string nowName) { IntTreviewIndex = IntTreviewIndex + 1; TreeViewOfInts.Add(frontName + "/" + nowName,IntTreviewIndex); return frontName + "/" + nowName; } private void AddTreeDirectory(string path,string JudgeName = "",string frontName = "") { DirectoryInfo source = new DirectoryInfo(path); foreach (DirectoryInfo directoryInfo in source.GetDirectories()) { if (directoryInfo.Name.Contains(JudgeName)) { string nextName = AddTreeViewOfInts(frontName, directoryInfo.Name); newCharactersPath = directoryInfo.FullName + @"\SkinParts"; CharactersPathDic.Add(IntTreviewIndex, directoryInfo.FullName); if (Directory.Exists(newCharactersPath)) { AddTreeDirectory(newCharactersPath, "", nextName); } } } } private static string GetEmotionID(string suitID) { //配置表 路径 string m_SkinPartTablePath = "Assets/ResourcesRaw/Mainland/Tables/Client/SkinPartTable.csv"; string m_DropItemTablePath = "Assets/ResourcesRaw/Mainland/Tables/Client/DropItemTable.csv"; string m_InGameEmotionPath = "Assets/ResourcesRaw/Mainland/Tables/Client/IngameEmotion.csv"; string m_ShopSuitePath = "Assets/ResourcesRaw/Mainland/Tables/Client/ShopSuiteTable.csv"; string m_SkinGroupPath = "Assets/ResourcesRaw/Mainland/Tables/Client/SkinGroupTable.csv"; //配置表 IdBasedList SkinPartTable; IdBasedList DropItemTable; IdBasedList IngameEmotionInfo; IdBasedList ShopSuiteTable; IdBasedList SkinGroupTable; CSVReader.LoadCSVTable(File.ReadAllText(m_SkinPartTablePath), out SkinPartTable, 1); CSVReader.LoadCSVTable(File.ReadAllText(m_DropItemTablePath), out DropItemTable, 1); CSVReader.LoadCSVTable(File.ReadAllText(m_InGameEmotionPath), out IngameEmotionInfo, 1); CSVReader.LoadCSVTable(File.ReadAllText(m_ShopSuitePath), out ShopSuiteTable, 1); CSVReader.LoadCSVTable(File.ReadAllText(m_SkinGroupPath), out SkinGroupTable, 1); List SkinPartTableIDList = new List(); for (int i = 0; i < SkinPartTable.Count; i++) { if (SkinPartTable[i].ConfigID== suitID) { SkinPartTableIDList.Add(SkinPartTable[i].Id); } } //判断是否存在套装 bool isRightSkinGroupSuite = false; int skinGroupTypeParam = -1; int skinGroupTypeID = -1; for (int i = 0; i < SkinGroupTable.Count; i++) { isRightSkinGroupSuite = true; for (int j = 0; j < SkinPartTableIDList.Count; j++) { if (!SkinGroupTable[i].SkinPartIds.Contains(SkinPartTableIDList[j])) { isRightSkinGroupSuite = false; break; } } if (isRightSkinGroupSuite) { skinGroupTypeParam = SkinGroupTable[i].Id; break; } } List DropItemTableList = new List(); for (int i = 0; i < DropItemTable.Count; i++) { if (skinGroupTypeParam != -1) { if (DropItemTable[i].Type == DropItemType.SkinGroup && DropItemTable[i].TypeParam == skinGroupTypeParam) { skinGroupTypeID = DropItemTable[i].Id; } } for (int j = 0; j < SkinPartTableIDList.Count; j++) { if (DropItemTable[i].TypeParam == SkinPartTableIDList[j]) { DropItemTableList.Add(DropItemTable[i].Id); break; } } } bool isRightShopSuite = false; int isRightShopSuiteID = -1; int isRightGroupSuiteID = -1; for (int i = 0; i < ShopSuiteTable.Count; i++) { if (skinGroupTypeID != -1) { if (ShopSuiteTable[i].ShopItemIDs.Length == 1 && ShopSuiteTable[i].ShopItemIDs.Contains(skinGroupTypeID)) //如果只有套装id { isRightShopSuiteID = ShopSuiteTable[i].ChangePartAnim; break; } } isRightShopSuite = true; for (int j = 0; j < DropItemTableList.Count; j++) { if (!ShopSuiteTable[i].ShopItemIDs.Contains(DropItemTableList[j])) { isRightShopSuite = false; break; } } if (isRightShopSuite) { isRightShopSuiteID = ShopSuiteTable[i].ChangePartAnim; break; } } if (isRightShopSuiteID != -1) { IngameEmotionInfo info = IngameEmotionInfo.Get(isRightShopSuiteID); return info.Config; } return ""; } /// /// 处理TimeLine相关逻辑 /// private void TimeLineLogicManager() { PlayableDirector playableDirector = GameObjectProp.GetComponent(); if (playableDirector != null) { Dictionary bindingDict = new Dictionary(); foreach (var bind in playableDirector.playableAsset.outputs) { if (!bindingDict.ContainsKey(bind.streamName)) { bindingDict.Add(bind.streamName,bind); } } if (bindingDict.TryGetValue("EmotionCharacterSignal", out PlayableBinding playableBinding)) { playableDirector.SetGenericBinding(playableBinding.sourceObject,GameObjectIdleManager); // TrackAsset playableTrack = playableBinding.sourceObject as TrackAsset; } } } private string GetCharacterClip(string[] belongNameList) { string Anim = String.Empty; //局外动画 string[] AnimGuids; string AnimPath = CharactersPath + belongNameList[belongNameList.Length - 2] + "/SkinParts/" + SuitID + "/RelatedResources/"; if (Directory.Exists(AnimPath)) { AnimGuids = AssetDatabase.FindAssets(LobbyAnimationIdle + " t:AnimationClip", new[] {AnimPath}); if (AnimGuids.Length == 1) //局外默认动画应该只有一个 { string guid = AnimGuids[0]; Anim = AssetDatabase.GUIDToAssetPath(guid); } } else { AnimPath = CharactersPath + belongNameList[belongNameList.Length - 2] + "/SkinParts/Default/RelatedResources/"; if (Directory.Exists(AnimPath)) { AnimGuids = AssetDatabase.FindAssets(LobbyAnimationIdle + " t:AnimationClip", new[] {AnimPath}); if (AnimGuids.Length == 1) //局外默认动画应该只有一个 { string guid = AnimGuids[0]; Anim = AssetDatabase.GUIDToAssetPath(guid); } } } return Anim; } #endregion } } ```