28 KiB
28 KiB
#unity/白日梦/代码缓存
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<int> TreeViewOfInts = new ValueDropdownList<int>
{
{ "请选择警察或小偷", 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<GameObject>(currentEffectGoPath));
if (currentEffect != null)
{
currentEffect.transform.rotation = Quaternion.Euler(0, 0, 0);
currentEffect.AddComponent<ParticleSystem>();
currentEffect.GetComponent<ParticleSystem>().GetComponent<Renderer>().enabled = false;
}
GameObject MeshSyncmanager = new GameObject("MeshSyncmanager");
meshSyncmanager = MeshSyncmanager.AddComponent<MeshSyncmanager>();
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<GameObject>(goPath));
// currentEffect.transform.rotation = Quaternion.Euler(0, -180, 0);
// currentEffect.AddComponent<ParticleSystem>();
//
// currentEffect.GetComponent<ParticleSystem>().GetComponent<Renderer>().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<GameObject>(goPath);
SkinnedMeshRenderer[] smr = go.GetComponentsInChildren<SkinnedMeshRenderer>();
for (int j = 0; j < smr.Length; j++)
{
List<Material> materials = new List<Material>(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<string> LogicNameList = new List<string>();
for (int i = 0; i < propGuidsObject.Length; i++)
{
string guid = propGuidsObject[i];
string goPath = AssetDatabase.GUIDToAssetPath(guid);
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(goPath);
// SkinnedMeshRenderer[] smr = go.GetComponentsInChildren<SkinnedMeshRenderer>();
// for (int j = 0; j < smr.Length; j++)
// {
// List<Material> materials = new List<Material>(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>();
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<CameraOffCenterProjection>();
// Animation anim = GameObjectProp.GetComponent<Animation>();
// 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<AnimationClip>(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<GameObject>(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<Animation>());
//找到所有的HeadBoneAttach组件,将Attachmentment节点挂载到HeadBoneName节点下
HeadBoneAttach[] headBoneAttaches =
GameObjectCharacter.GetComponentsInChildren<HeadBoneAttach>();
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<Animation>().clip = newClip;
GameObjectCharacter.AddComponent<Animator>();
IdleManager.Instance.InitIdleAnimation(GameObjectProp);
// GameObjectCharacter.GetComponent<Animation>().AddClip(characterClip, characterClip.name);
// meshSyncmanager.AddAnims(GameObjectCharacter.GetComponent<Animation>());
// newAnimator.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath<AnimatorController>(
// "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;
/// <summary>
/// 判断角色id和编号是否为空
/// </summary>
/// <returns></returns>
public bool JudgeRoleAndNumber()
{
if (RoleIndex == null || NumberIndex == null)
{
return false;
}
return true;
}
/// <summary>
/// 判断表情动作和timeline是否存在
/// </summary>
/// <returns></returns>
public bool JudgeEmotionAndDirector()
{
if (GameObjectProp != null && GameObjectProp.GetComponent<PlayableDirector>() != null)
{
return true;
}
return false;
}
private void CreateLight()
{
//实例化局外灯光
if (GameObjectLight == null)
{
GameObjectLight = Instantiate(AssetDatabase.LoadAssetAtPath<GameObject>(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<PlayableDirector>().Play();
}
[ShowIf("@JudgeEmotionAndDirector()")]
[Button("暂停播放")]
public void DirectorPause()
{
GameObjectProp.GetComponent<PlayableDirector>().Pause();
}
[ShowIf("@JudgeEmotionAndDirector()")]
[Button("停止播放")]
public void DirectorStop()
{
GameObjectProp.GetComponent<PlayableDirector>().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<SkinPartInfo> SkinPartTable;
IdBasedList<DropItem> DropItemTable;
IdBasedList<IngameEmotionInfo> IngameEmotionInfo;
IdBasedList<ShopSuiteInfo> ShopSuiteTable;
IdBasedList<SkinGroupInfo> 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<int> SkinPartTableIDList = new List<int>();
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<int> DropItemTableList = new List<int>();
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 "";
}
/// <summary>
/// 处理TimeLine相关逻辑
/// </summary>
private void TimeLineLogicManager()
{
PlayableDirector playableDirector = GameObjectProp.GetComponent<PlayableDirector>();
if (playableDirector != null)
{
Dictionary<string,PlayableBinding> bindingDict = new Dictionary<string, PlayableBinding>();
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
}
}