990 lines
31 KiB
C#
990 lines
31 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Text;
|
||
using DMM.EditorExpand;
|
||
using LightUtility;
|
||
using ResourcesModule.LMNA;
|
||
using UnityEngine;
|
||
using UnityEditor;
|
||
using UtilityModule.EditorExpand;
|
||
using eAssetFunctionType = ResourcesModule.LMNA.eAssetFunctionType;
|
||
|
||
|
||
public class EmotionActionEditor : EditorWindow
|
||
{
|
||
private static EmotionActionEditor m_Window;
|
||
|
||
|
||
private const string emotionConfig = "/BundleResources/CommonRegion/Common/Skins/Emotions/";
|
||
|
||
private Dictionary<string,string> ResourcesRawDic = new Dictionary<string, string>
|
||
{
|
||
["lob_"] = "/ResourcesRaw/CommonRegion/OutsideGame/Skins/Emotions/",
|
||
["ing_"] = "/ResourcesRaw/CommonRegion/InGame/Skins/Emotions/"
|
||
};
|
||
|
||
private Dictionary<string,string> BundleResourcesDic = new Dictionary<string, string>
|
||
{
|
||
["com_"] = "Assets/BundleResources/CommonRegion/Common/Skins/Emotions/",
|
||
["lob_"] = "Assets/BundleResources/CommonRegion/OutsideGame/Skins/Emotions/",
|
||
["ing_"] = "Assets/BundleResources/CommonRegion/InGame/Skins/Emotions/"
|
||
};
|
||
|
||
private Dictionary<string,bool> fbxChildDic = new Dictionary<string, bool>();
|
||
private Dictionary<Transform,Transform> sonAndParentDic = new Dictionary<Transform, Transform>();
|
||
|
||
|
||
|
||
// 界面相关
|
||
Color m_BlueColor = new Color(129 / 255f, 209 / 255f, 248 / 255f, 1);
|
||
Color m_PinkColor = new Color(253 / 255f, 184 / 255f, 225 / 255f, 1);
|
||
Color m_RedColor = new Color(233 / 255f, 74 / 255f, 110 / 255f, 1);
|
||
Color m_PurpColor = new Color(125 / 255f, 128 / 255f, 227 / 255f, 1);
|
||
float m_RowHeight = 20f;
|
||
int m_RowFontSize = 12;
|
||
GUIStyle m_MainHeaderStyle;
|
||
GUIStyle m_SubHeaderStyle;
|
||
GUIStyle m_ButtonStyle;
|
||
GUIStyle m_TipsStyle;
|
||
GUIStyle m_ErrorTipsStyle;
|
||
GUIStyle m_LabelStyle;
|
||
GUIStyle m_TagLabelStyle;
|
||
GUIStyle m_ParamsLabelStyle;
|
||
|
||
|
||
private List<Dictionary<string,object>> AllFileList = new List<Dictionary<string, object>>();
|
||
|
||
|
||
List<FileInfo> nodeList = new List<FileInfo>();
|
||
List<FileInfo> alreadyUseNodeList = new List<FileInfo>();
|
||
List<bool> ChooseList = new List<bool>();
|
||
|
||
private bool isChoose;
|
||
private bool isSelected;
|
||
private bool isSuccess;
|
||
|
||
|
||
private GameObject m_FbxSenceObject;
|
||
|
||
private eAssetSceneType currentAssetSceneType = eAssetSceneType.Unknown;
|
||
private eAssetLodLevel currentAssetLodLevel = eAssetLodLevel.None;
|
||
|
||
private Dictionary<string,eAssetLodLevel> levelDic = new Dictionary<string, eAssetLodLevel>
|
||
{
|
||
["lv0"] = eAssetLodLevel.Lv0,
|
||
["lv1"] = eAssetLodLevel.Lv1,
|
||
["lv2"] = eAssetLodLevel.Lv2,
|
||
["lv3"] = eAssetLodLevel.Lv3,
|
||
["lv4"] = eAssetLodLevel.Lv4
|
||
};
|
||
|
||
private Dictionary<string, eAssetSceneType> sceneDic = new Dictionary<string, eAssetSceneType>
|
||
{
|
||
["lob"] = eAssetSceneType.Lobby,
|
||
["ing"] = eAssetSceneType.InGame
|
||
};
|
||
|
||
void InitStyles()
|
||
{
|
||
if (m_MainHeaderStyle == null)
|
||
{
|
||
m_MainHeaderStyle = new GUIStyle(GUI.skin.label);
|
||
m_MainHeaderStyle.fontSize = 20;
|
||
m_MainHeaderStyle.fontStyle = FontStyle.Bold;
|
||
m_MainHeaderStyle.normal.textColor = m_BlueColor;
|
||
}
|
||
|
||
if (m_SubHeaderStyle == null)
|
||
{
|
||
m_SubHeaderStyle = new GUIStyle(GUI.skin.label);
|
||
m_SubHeaderStyle.fontSize = 14;
|
||
m_SubHeaderStyle.fontStyle = FontStyle.Bold;
|
||
m_SubHeaderStyle.normal.textColor = m_BlueColor;
|
||
}
|
||
|
||
if (m_ButtonStyle == null)
|
||
{
|
||
m_ButtonStyle = new GUIStyle(GUI.skin.button);
|
||
m_ButtonStyle.fontSize = 14;
|
||
m_ButtonStyle.richText = true;
|
||
}
|
||
|
||
if (m_TipsStyle == null)
|
||
{
|
||
m_TipsStyle = new GUIStyle(GUI.skin.label);
|
||
m_TipsStyle.normal.textColor = m_PinkColor;
|
||
m_TipsStyle.fontSize = m_RowFontSize;
|
||
}
|
||
|
||
if (m_ErrorTipsStyle == null)
|
||
{
|
||
m_ErrorTipsStyle = new GUIStyle(GUI.skin.label);
|
||
m_ErrorTipsStyle.normal.textColor = m_RedColor;
|
||
m_ErrorTipsStyle.fontSize = m_RowFontSize;
|
||
}
|
||
|
||
if (m_LabelStyle == null)
|
||
{
|
||
m_LabelStyle = new GUIStyle(GUI.skin.label);
|
||
m_LabelStyle.normal.textColor = m_BlueColor;
|
||
m_LabelStyle.fontSize = 18;
|
||
}
|
||
|
||
if (m_TagLabelStyle == null)
|
||
{
|
||
m_TagLabelStyle = new GUIStyle(GUI.skin.label);
|
||
m_TagLabelStyle.normal.textColor = m_PinkColor;
|
||
m_TagLabelStyle.fontSize = 16;
|
||
}
|
||
|
||
if (m_ParamsLabelStyle == null)
|
||
{
|
||
m_ParamsLabelStyle = new GUIStyle(GUI.skin.label);
|
||
m_ParamsLabelStyle.normal.textColor = m_PurpColor;
|
||
m_ParamsLabelStyle.fontSize = 13;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
[MenuItem("美术工具/表情动作导入",false,2)]
|
||
static void ShowWindow()
|
||
{
|
||
if (m_Window == null)
|
||
{
|
||
m_Window = (EmotionActionEditor)GetWindow(typeof(EmotionActionEditor), true, "EmotionActionEditor");
|
||
m_Window.Show();
|
||
}
|
||
else
|
||
{
|
||
m_Window.Close();
|
||
m_Window = null;
|
||
}
|
||
}
|
||
|
||
bool checkName(string name)
|
||
{
|
||
string[] nameList_First = name.Split('&');
|
||
if (nameList_First.Length != 2 )
|
||
{
|
||
ShowTipsLog("模型资源命名不正确,特殊字符有问题");
|
||
return false;
|
||
}
|
||
|
||
string[] nameList_Second = nameList_First[1].Split('@');
|
||
if (nameList_Second.Length != 2)
|
||
{
|
||
ShowTipsLog("模型资源命名不正确,特殊字符有问题");
|
||
return false;
|
||
}
|
||
|
||
|
||
if (!(nameList_Second[0].Contains("lob_") || nameList_Second[0].Contains("ing_")))
|
||
{
|
||
ShowTipsLog("模型资源命名不正确,缺少局内外标识");
|
||
return false;
|
||
}
|
||
|
||
string[] nameList_Third = nameList_Second[1].Split('_');
|
||
string param = Path.GetFileNameWithoutExtension(nameList_Third[0]);
|
||
int skinNumber = 0;
|
||
|
||
if (!int.TryParse(param,out skinNumber))
|
||
{
|
||
ShowTipsLog("模型编号不是数字,请检查资源命名");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private void ScrollViewShow(List<FileInfo> mainList, List<FileInfo> notMainList, string txt)
|
||
{
|
||
|
||
for (int o = 0; o < ChooseList.Count; o++)
|
||
{
|
||
EditorGUILayout.BeginHorizontal();
|
||
|
||
EditorGUILayout.LabelField(mainList[o].Name);
|
||
EditorGUILayout.Space();
|
||
ChooseList[o] = EditorGUILayout.Toggle(ChooseList[o]);
|
||
|
||
|
||
|
||
EditorGUILayout.EndHorizontal();
|
||
}
|
||
|
||
for (int i = 0; i < mainList.Count; i++)
|
||
{
|
||
EditorGUILayout.BeginHorizontal();
|
||
|
||
GUILayout.Label(mainList[i].Name);
|
||
|
||
if (GUILayout.Button(txt,m_ButtonStyle))
|
||
{
|
||
if (!checkName(mainList[i].Name))
|
||
{
|
||
return;
|
||
}
|
||
notMainList.Add(mainList[i]);
|
||
mainList.RemoveAt(i);
|
||
}
|
||
|
||
|
||
EditorGUILayout.EndHorizontal();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
Vector2 _scrollPos;
|
||
|
||
private void DrawList()
|
||
{
|
||
EditorGUILayout.Space();
|
||
|
||
EditorGUILayout.BeginVertical();
|
||
|
||
EditorGUILayout.LabelField("文件夹里包含的FBX文件列表选择:");
|
||
|
||
EditorGUILayout.Space();
|
||
|
||
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos, false, true);
|
||
|
||
|
||
if (isSelected == false)
|
||
{
|
||
ScrollViewShow(nodeList, alreadyUseNodeList, "<color=#66D9EE>选择</color>");
|
||
}
|
||
else
|
||
{
|
||
ScrollViewShow(alreadyUseNodeList, nodeList, "<color=#66D9EE>取消选择</color>");
|
||
}
|
||
|
||
|
||
|
||
EditorGUILayout.EndScrollView();
|
||
|
||
EditorGUILayout.Space();
|
||
|
||
EditorGUILayout.EndVertical();
|
||
|
||
}
|
||
|
||
void OnGUI()
|
||
{
|
||
InitStyles();
|
||
|
||
EditorGUILayout.Space();
|
||
|
||
if (isChoose == false)
|
||
{
|
||
if (GUILayout.Button("选表情动作所在文件夹",m_ButtonStyle,GUILayout.Width(150),GUILayout.Height(m_RowHeight)))
|
||
{
|
||
isSuccess = OnClickLoadButton();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
EditorGUILayout.BeginHorizontal();
|
||
|
||
if (GUILayout.Button("导入", m_ButtonStyle, GUILayout.Width(150), GUILayout.Height(m_RowHeight)))
|
||
{
|
||
OnClickCreateButton(isSuccess);
|
||
}
|
||
|
||
if (alreadyUseNodeList.Count > 0)
|
||
{
|
||
if (GUILayout.Button(isSelected?"返回":"已选择列表", m_ButtonStyle, GUILayout.Width(150), GUILayout.Height(m_RowHeight)))
|
||
{
|
||
isSelected = !isSelected;
|
||
}
|
||
|
||
if (GUILayout.Button("撤销",m_ButtonStyle,GUILayout.Width(150),GUILayout.Height(m_RowHeight)))
|
||
{
|
||
for (int i = 0; i < alreadyUseNodeList.Count; i++)
|
||
{
|
||
nodeList.Add(alreadyUseNodeList[i]);
|
||
}
|
||
|
||
alreadyUseNodeList.Clear();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
isSelected = false;
|
||
}
|
||
|
||
EditorGUILayout.EndHorizontal();
|
||
|
||
DrawList();
|
||
|
||
}
|
||
|
||
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 修正Humanoid
|
||
/// </summary>
|
||
/// <param name="strFilePath"></param>
|
||
void FixHumanoidAnimationParams(string strFilePath)
|
||
{
|
||
ModelImporter importer = AssetImporter.GetAtPath(strFilePath) as ModelImporter;
|
||
DoFixHumanoidAnimationParams(importer, strFilePath);
|
||
|
||
}
|
||
|
||
private string[] LoopNames = {"loop", "Beituozhuai", "Tuozhuai", "Crawl", "Incage", "Run", "Unlock", "Stun"};
|
||
bool IsAnimationLoop(string animationName)
|
||
{
|
||
string lowerName = animationName.ToLower();
|
||
foreach (string loopName in LoopNames)
|
||
{
|
||
if (lowerName.Contains(loopName.ToLower()))
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void DoFixHumanoidAnimationParams(ModelImporter importer, string assetPath)
|
||
{
|
||
importer.animationType = ModelImporterAnimationType.Human;
|
||
|
||
ModelImporterClipAnimation[] clips = importer.clipAnimations;
|
||
if (clips.Length == 0) clips = importer.defaultClipAnimations;
|
||
if (clips.Length == 0)
|
||
{
|
||
Debug.LogError($"DoFixHumanoidAnimationParams clipAnimations is Empty:\n{assetPath}");
|
||
}
|
||
|
||
AvatarMask templateMask = new AvatarMask();
|
||
|
||
for (int i = 0; i < clips.Length; i++)
|
||
{
|
||
clips[i].lockRootRotation = true;
|
||
clips[i].keepOriginalOrientation = true;
|
||
clips[i].lockRootHeightY = true;
|
||
clips[i].keepOriginalPositionY = true;
|
||
clips[i].lockRootPositionXZ = true;
|
||
clips[i].keepOriginalPositionXZ = true;
|
||
if (IsAnimationLoop(importer.name))
|
||
{
|
||
clips[i].loop = true;
|
||
}
|
||
|
||
clips[i].maskType = ClipAnimationMaskType.CreateFromThisModel;
|
||
clips[i].ConfigureMaskFromClip(ref templateMask);
|
||
for (int j = 0; j < templateMask.transformCount; j++)
|
||
{
|
||
templateMask.SetTransformActive(j,true);
|
||
}
|
||
|
||
|
||
clips[i].ConfigureClipFromMask(templateMask);
|
||
}
|
||
|
||
DestroyImmediate(templateMask);
|
||
importer.clipAnimations = clips;
|
||
importer.SaveAndReimport();
|
||
}
|
||
|
||
void OnClickCreateButton(bool isSuccess = true)
|
||
{
|
||
if (isSuccess == false)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (alreadyUseNodeList.Count <= 0)
|
||
{
|
||
ShowTipsLog("未选择fbx文件");
|
||
return;
|
||
}
|
||
|
||
|
||
for (int j = 0; j < alreadyUseNodeList.Count; j++)
|
||
{
|
||
ImportResource(alreadyUseNodeList[j]);
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
|
||
for (int i = 0; i < AllFileList.Count; i++)
|
||
{
|
||
|
||
|
||
string belongPath = AllFileList[i]["belongPath"] as string;
|
||
string modelParam = AllFileList[i]["modelParam"] as string;
|
||
string style = AllFileList[i]["style"] as string;
|
||
string inOut = AllFileList[i]["inOut"] as string;
|
||
string AssetPath = AllFileList[i]["AssetPath"] as string;
|
||
string animPath = "";
|
||
|
||
//如果是局内的模型,需要特殊处理一下
|
||
if (inOut == "ing_" && style == "model")
|
||
{
|
||
FixHumanoidAnimationParams(AssetPath);
|
||
}
|
||
|
||
//表情动作,才生成对应的预制体,模型动作本身,不生成预制体
|
||
if (style == "model")
|
||
{
|
||
animPath = BundleResourcesDic[inOut] + belongPath + "/Animations/" + @"ani&" + inOut + belongPath +
|
||
@"@" + modelParam + ".anim";
|
||
}
|
||
else
|
||
{
|
||
GameObject fbxObject = GetFbxGameObject(AllFileList[i]["fbxPath"] as string);
|
||
CreatePrefab(ref fbxObject,AllFileList[i]);
|
||
|
||
}
|
||
|
||
string configPath = BundleResourcesDic["com_"] + belongPath + "/Configs/" + @"sco&" + modelParam +
|
||
".asset";
|
||
// List<string> allConfigPaths = EditorUtilities.SearchFiles(dir, new[] {$"sco&{modelParam}*.asset"});
|
||
IngameEmotionConfig config =
|
||
AssetDatabase.LoadAssetAtPath<IngameEmotionConfig>(EditorPathUtil.GetAssetPath(configPath));
|
||
|
||
if (config == null)
|
||
{
|
||
ShowTipsLog($"找不到对应的sco&{modelParam}配置文件,程序正在自动生成一个");
|
||
configPath = BundleResourcesDic["com_"] + belongPath + "/Configs/" + @"sco&" + modelParam +
|
||
".asset";
|
||
IngameEmotionConfig newSetting = CreateInstance<IngameEmotionConfig>();
|
||
AssetDatabase.CreateAsset(newSetting,configPath);
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
|
||
config = AssetDatabase.LoadAssetAtPath<IngameEmotionConfig>(EditorPathUtil.GetAssetPath(configPath));
|
||
}
|
||
|
||
OutIngameEmotionConfig.Instance.RefreshAllConfig(config,animPath);
|
||
}
|
||
|
||
|
||
ClearGC();
|
||
|
||
}
|
||
|
||
bool OnClickLoadButton()
|
||
{
|
||
bool success = true;
|
||
string defaultFolder = PlayerPrefs.GetString("EmotionActionFolder", "");
|
||
string folder = EditorUtility.OpenFolderPanel("Select Versions Folder", defaultFolder, "");
|
||
if (string.IsNullOrEmpty(folder))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
PlayerPrefs.SetString("EmotionActionFolder", folder);
|
||
DirectoryInfo diretion = new DirectoryInfo(folder);
|
||
|
||
FileInfo[] fbxFiles = diretion.GetFiles("*.fbx", SearchOption.AllDirectories);
|
||
|
||
if (fbxFiles.Length == 0)
|
||
{
|
||
NamingChecker.PopupErrorMessage("未检测到有fbx导入!");
|
||
return false;
|
||
}
|
||
|
||
ClearGC();
|
||
|
||
|
||
|
||
for (int i = 0; i < fbxFiles.Length; i++)
|
||
{
|
||
|
||
ChooseList.Add(false);
|
||
nodeList.Add(fbxFiles[i]);
|
||
|
||
// CheckName(fbxFiles[i]);
|
||
|
||
}
|
||
|
||
isChoose = true;
|
||
// AssetDatabase.Refresh();
|
||
|
||
|
||
return success;
|
||
}
|
||
|
||
|
||
GameObject GetFbxGameObject(string path)
|
||
{
|
||
string relativePath = NamingChecker.GetRelativePath(path);
|
||
Transform fbxTrans = AssetDatabase.LoadAssetAtPath(relativePath, typeof(Transform)) as Transform;
|
||
if (m_FbxSenceObject != null) // 不要重复生成,关闭的时候清不掉
|
||
{
|
||
DestroyImmediate(m_FbxSenceObject.gameObject);
|
||
}
|
||
m_FbxSenceObject = Instantiate(fbxTrans).gameObject;
|
||
return m_FbxSenceObject;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取fbx对应的prefab名字
|
||
/// </summary>
|
||
/// <param name="name"></param>
|
||
/// <returns></returns>
|
||
string GetPrefabName(string name)
|
||
{
|
||
string[] nameList = name.Split('&');
|
||
eAssetLodLevel level = eAssetLodLevel.None;
|
||
string finalName = String.Empty;
|
||
|
||
foreach (KeyValuePair<string,eAssetLodLevel> keyValuePair in levelDic)
|
||
{
|
||
if (nameList[0].Contains(keyValuePair.Key))
|
||
{
|
||
level = keyValuePair.Value;
|
||
currentAssetLodLevel = level;
|
||
break;
|
||
}
|
||
}
|
||
|
||
foreach (KeyValuePair<string,eAssetSceneType> keyValuePair in sceneDic)
|
||
{
|
||
if (nameList[1].Contains(keyValuePair.Key))
|
||
{
|
||
currentAssetSceneType = keyValuePair.Value;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
if (nameList.Length == 2 )
|
||
{
|
||
string[] logicNamelist = nameList[1].Split('_');
|
||
if (logicNamelist.Length > 4)
|
||
{
|
||
StringBuilder stringBuilder = new StringBuilder();
|
||
stringBuilder.Clear();
|
||
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
stringBuilder.Append(logicNamelist[i] + "_");
|
||
}
|
||
|
||
stringBuilder.Append(logicNamelist[3]);
|
||
|
||
|
||
|
||
string prefabName = stringBuilder.ToString();
|
||
|
||
stringBuilder.Clear();
|
||
finalName = LMNAResMapUtil.AssembleAssetName(prefabName, eAssetFunctionType.GameObject,
|
||
level);
|
||
|
||
}
|
||
}
|
||
|
||
return finalName;
|
||
}
|
||
|
||
private string currentName = "";
|
||
private Transform currentTrans;
|
||
void CreatePrefab(ref GameObject fbxGameObject,Dictionary<string,object> node)
|
||
{
|
||
string prefabName = "";
|
||
|
||
prefabName = fbxGameObject.name.Split('(')[0];
|
||
// realPrefabName = GetPrefabName(prefabName);
|
||
prefabName = DropPostfix(prefabName);
|
||
|
||
|
||
string belongPath = node["belongPath"] as string;
|
||
string inOut = node["inOut"] as string;
|
||
string AssetPath = node["AssetPath"] as string;
|
||
string finalPath = BundleResourcesDic[inOut] + belongPath + "/";
|
||
|
||
|
||
|
||
if (!Directory.Exists(finalPath))
|
||
{
|
||
ShowTipsLog($"该{belongPath}路径不存在,请检查命名是否正确");
|
||
DestroyImmediate(fbxGameObject.gameObject);
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
string PropPrefabsPath = finalPath + "PropPrefabs/";
|
||
|
||
if (!Directory.Exists(PropPrefabsPath))
|
||
{
|
||
Directory.CreateDirectory(PropPrefabsPath);
|
||
}
|
||
|
||
|
||
|
||
List<GameObject> rst = new List<GameObject>();
|
||
if (AssetPath.Contains("_prop"))
|
||
{
|
||
ModelImporter mi = AssetImporter.GetAtPath(AssetPath) as ModelImporter;
|
||
mi.animationType = ModelImporterAnimationType.Legacy;
|
||
mi.SaveAndReimport();
|
||
rst.Add(AssetDatabase.LoadAssetAtPath<GameObject>(AssetPath));
|
||
}
|
||
|
||
foreach (GameObject model in rst)
|
||
{
|
||
UnityEngine.Profiling.Profiler.BeginSample($"Instantiate {model}");
|
||
GameObject prefabInst = Instantiate(model);
|
||
UnityEngine.Profiling.Profiler.EndSample();
|
||
var animComponent = model.GetComponent<Animation>();
|
||
if (animComponent != null)
|
||
{
|
||
animComponent.playAutomatically = true;
|
||
animComponent.cullingType = AnimationCullingType.AlwaysAnimate;
|
||
}
|
||
Poolable poolComponent = prefabInst.GetComponent<Poolable>();
|
||
if (poolComponent == null)
|
||
{
|
||
prefabInst.AddComponent<Poolable>();
|
||
}
|
||
|
||
fbxChildDic.Clear();
|
||
sonAndParentDic.Clear();
|
||
|
||
//判断prefab是否已存在
|
||
string prefabPath = PropPrefabsPath + prefabName + ".prefab";
|
||
|
||
if (File.Exists(prefabPath))
|
||
{
|
||
|
||
GameObject alreadyPrefab =
|
||
Instantiate(AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath));
|
||
|
||
GetAllChild(prefabInst.transform, "", fbxChildDic);
|
||
CheckAllChild(alreadyPrefab.transform, "", prefabInst);
|
||
|
||
foreach (KeyValuePair<Transform,Transform> keyValuePair in sonAndParentDic)
|
||
{
|
||
keyValuePair.Key.parent = keyValuePair.Value;
|
||
}
|
||
|
||
sonAndParentDic.Clear();
|
||
|
||
//判断一下自身是否有挂载skinMeshrender
|
||
if (alreadyPrefab.GetComponent<SkinnedMeshRenderer>() != null)
|
||
{
|
||
|
||
List<Material> materials = new List<Material>(alreadyPrefab.GetComponent<SkinnedMeshRenderer>().sharedMaterials);
|
||
if (prefabInst.GetComponent<SkinnedMeshRenderer>() == null)
|
||
{
|
||
prefabInst.AddComponent<SkinnedMeshRenderer>();
|
||
}
|
||
|
||
prefabInst.GetComponent<SkinnedMeshRenderer>().sharedMaterials = materials.ToArray();
|
||
}
|
||
else if (alreadyPrefab.GetComponent<MeshRenderer>() != null)
|
||
{
|
||
List<Material> materials = new List<Material>(alreadyPrefab.GetComponent<MeshRenderer>().sharedMaterials);
|
||
if (prefabInst.GetComponent<MeshRenderer>() == null)
|
||
{
|
||
prefabInst.AddComponent<MeshRenderer>();
|
||
}
|
||
|
||
prefabInst.GetComponent<MeshRenderer>().sharedMaterials = materials.ToArray();
|
||
}
|
||
|
||
DestroyImmediate(alreadyPrefab.gameObject);
|
||
}
|
||
|
||
|
||
PrefabUtility.SaveAsPrefabAssetAndConnect(prefabInst, PropPrefabsPath + prefabName + ".prefab", InteractionMode.AutomatedAction);
|
||
AssetDatabase.SaveAssets();
|
||
DestroyImmediate(prefabInst.gameObject);
|
||
AssetDatabase.Refresh();
|
||
|
||
}
|
||
|
||
|
||
|
||
DestroyImmediate(fbxGameObject.gameObject);
|
||
}
|
||
void GetAllChild(Transform trans, string path,Dictionary<string,bool> dic)
|
||
{
|
||
if (trans.childCount > 0)
|
||
{
|
||
for (int i = 0; i < trans.childCount; i++)
|
||
{
|
||
currentName = path + "/" + trans.GetChild(i).name;
|
||
dic.Add(currentName,true);
|
||
GetAllChild(trans.GetChild(i).transform,currentName,dic);
|
||
}
|
||
}
|
||
}
|
||
|
||
void CheckAllChild(Transform trans, string path,GameObject fbx)
|
||
{
|
||
if (trans.childCount > 0)
|
||
{
|
||
for (int i = 0; i < trans.childCount; i++)
|
||
{
|
||
currentName = path + "/" + trans.GetChild(i).name;
|
||
if (fbxChildDic.ContainsKey(currentName))
|
||
{
|
||
|
||
if (trans.GetChild(i).GetComponent<SkinnedMeshRenderer>() != null)
|
||
{
|
||
List<Material> materials = new List<Material>(trans.GetChild(i).GetComponent<SkinnedMeshRenderer>().sharedMaterials);
|
||
string[] nameList = currentName.Split('/');
|
||
List<string> nameInList = new List<string>();
|
||
for (int j = 0; j < nameList.Length; j++)
|
||
{
|
||
if (nameList[j].Length > 0)
|
||
{
|
||
nameInList.Add(nameList[j]);
|
||
}
|
||
}
|
||
GetChild(fbx.transform, nameInList, 0);
|
||
if (currentTrans.GetComponent<SkinnedMeshRenderer>() == null)
|
||
{
|
||
currentTrans.gameObject.AddComponent<SkinnedMeshRenderer>();
|
||
}
|
||
|
||
currentTrans.GetComponent<SkinnedMeshRenderer>().sharedMaterials = materials.ToArray();
|
||
|
||
}
|
||
else if (trans.GetChild(i).GetComponent<MeshRenderer>() != null)
|
||
{
|
||
List<Material> materials = new List<Material>(trans.GetChild(i).GetComponent<MeshRenderer>().sharedMaterials);
|
||
string[] nameList = currentName.Split('/');
|
||
List<string> nameInList = new List<string>();
|
||
for (int j = 0; j < nameList.Length; j++)
|
||
{
|
||
if (nameList[j].Length > 0)
|
||
{
|
||
nameInList.Add(nameList[j]);
|
||
}
|
||
}
|
||
GetChild(fbx.transform, nameInList, 0);
|
||
if (currentTrans.GetComponent<MeshRenderer>() == null)
|
||
{
|
||
currentTrans.gameObject.AddComponent<MeshRenderer>();
|
||
}
|
||
|
||
currentTrans.GetComponent<MeshRenderer>().sharedMaterials = materials.ToArray();
|
||
}
|
||
|
||
CheckAllChild(trans.GetChild(i).transform,currentName,fbx);
|
||
}
|
||
else
|
||
{
|
||
string[] nameList = path.Split('/');
|
||
List<string> nameInList = new List<string>();
|
||
for (int j = 0; j < nameList.Length; j++)
|
||
{
|
||
if (nameList[j].Length > 0)
|
||
{
|
||
nameInList.Add(nameList[j]);
|
||
}
|
||
}
|
||
GetChild(fbx.transform, nameInList, 0);
|
||
|
||
sonAndParentDic.Add(trans.GetChild(i),currentTrans);
|
||
// trans.GetChild(i).parent = currentTrans;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void GetChild(Transform fbxTrans, List<string> nameList,int index)
|
||
{
|
||
if (nameList.Count == 0)
|
||
{
|
||
currentTrans = fbxTrans;
|
||
|
||
}
|
||
else
|
||
{
|
||
|
||
if (index == nameList.Count -1)
|
||
{
|
||
for (int j = 0; j < fbxTrans.childCount; j++)
|
||
{
|
||
if (fbxTrans.GetChild(j).name == nameList[index])
|
||
{
|
||
currentTrans = fbxTrans.GetChild(j);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
for (int i = 0; i < fbxTrans.childCount; i++)
|
||
{
|
||
if (fbxTrans.GetChild(i).name == nameList[index])
|
||
{
|
||
GetChild(fbxTrans.GetChild(i),nameList,index + 1);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
string DropPostfix(string name)
|
||
{
|
||
string postfix = NamingChecker.GetPostfix(name);
|
||
bool isValid = NamingChecker.IsValidPostfix(postfix);
|
||
if (isValid)
|
||
{
|
||
return name.Replace("_" + postfix, "").Replace("mdl", "pfb");
|
||
}
|
||
|
||
|
||
return name.Replace("mdl", "pfb");
|
||
}
|
||
|
||
void ImportResource(FileInfo file)
|
||
{
|
||
|
||
string name = file.Name;
|
||
|
||
// bool isRightName = true;
|
||
|
||
string style;
|
||
if (name.Contains("_prop"))
|
||
{
|
||
style = "prop";
|
||
}
|
||
else
|
||
{
|
||
style = "model";
|
||
}
|
||
|
||
string[] nameList_First = name.Split('&');
|
||
string[] nameList_Second = nameList_First[1].Split('@');
|
||
string[] nameList_Third = nameList_Second[1].Split('_');
|
||
|
||
|
||
// if (nameList_First.Length != 2 )
|
||
// {
|
||
// ShowTipsLog("模型资源命名不正确,特殊字符有问题");
|
||
// return false;
|
||
// }
|
||
|
||
// if (nameList_Second.Length != 2)
|
||
// {
|
||
// ShowTipsLog("模型资源命名不正确,特殊字符有问题");
|
||
// return false;
|
||
// }
|
||
|
||
|
||
// if (!(nameList_Second[0].Contains("lob_") || nameList_Second[0].Contains("ing_")))
|
||
// {
|
||
// ShowTipsLog("模型资源命名不正确,缺少局内外标识");
|
||
// return false;
|
||
// }
|
||
|
||
string param = Path.GetFileNameWithoutExtension(nameList_Third[0]);
|
||
int skinNumber = 0;
|
||
|
||
// if (!int.TryParse(param,out skinNumber))
|
||
// {
|
||
// ShowTipsLog("模型编号不是数字,请检查资源命名");
|
||
// return false;
|
||
// }
|
||
|
||
|
||
string belongPath = nameList_Second[0].Replace("lob_", "").Replace("ing_", "");
|
||
|
||
string frontPath = "";
|
||
string inOut = "";
|
||
|
||
if (nameList_Second[0].Contains("lob_"))
|
||
{
|
||
frontPath = ResourcesRawDic["lob_"];
|
||
inOut = "lob_";
|
||
}
|
||
else if (nameList_Second[0].Contains("ing_"))
|
||
{
|
||
frontPath = ResourcesRawDic["ing_"];
|
||
inOut = "ing_";
|
||
}
|
||
|
||
|
||
string fullPath = "";
|
||
string AssetPath = "";
|
||
|
||
if (style == "prop")
|
||
{
|
||
fullPath = Application.dataPath + frontPath + belongPath + "/Props/" + param + "/Animations/";
|
||
AssetPath = "Assets" + frontPath + belongPath + "/Props/" + param + "/Animations/" + name;
|
||
|
||
}
|
||
else if (style == "model")
|
||
{
|
||
fullPath = Application.dataPath + frontPath + belongPath + "/Animations/";
|
||
AssetPath = "Assets" + frontPath + belongPath + "/Animations/" + name;
|
||
}
|
||
|
||
|
||
|
||
|
||
if (!Directory.Exists(fullPath))
|
||
{
|
||
Directory.CreateDirectory(fullPath);
|
||
}
|
||
|
||
string fbxPath = fullPath + name;
|
||
|
||
|
||
if (File.Exists(fbxPath))
|
||
{
|
||
File.Delete(fbxPath);
|
||
}
|
||
|
||
file.CopyTo(fbxPath);
|
||
|
||
AllFileList.Add(OneEmotionAction(name, fbxPath, belongPath, file, inOut, AssetPath, param, style));
|
||
|
||
// return isRightName;
|
||
|
||
}
|
||
|
||
|
||
void ShowTipsLog(string txt)
|
||
{
|
||
EditorUtility.DisplayDialog("提示", txt, "了然");
|
||
|
||
}
|
||
|
||
Dictionary<string, object> OneEmotionAction(string name,string fbxPath,string belongPath,FileInfo file,string inOut,string AssetPath,string modelParam,string style)
|
||
{
|
||
Dictionary<string,object> node = new Dictionary<string, object>
|
||
{
|
||
["fbxPath"] = fbxPath,
|
||
["belongPath"] = belongPath,
|
||
["FileInfo"] = file,
|
||
["inOut"] = inOut,
|
||
["AssetPath"] = AssetPath,
|
||
["modelParam"] = modelParam,
|
||
["style"] = style
|
||
};
|
||
return node;
|
||
}
|
||
|
||
void ClearGC()
|
||
{
|
||
AllFileList.Clear();
|
||
nodeList.Clear();
|
||
alreadyUseNodeList.Clear();
|
||
ChooseList.Clear();
|
||
}
|
||
|
||
|
||
}
|