private static List <string[]> GetHumanoidCombineList() { List <string[]> ret = new List <string[]>(); CHumanoidCombineTable table = new CHumanoidCombineTable(); table.Load(); foreach (CHumanoidCombineTableElement one in table.m_pElement) { bool bValid = true; foreach (string oneComp in one.m_sCombine) { if (string.IsNullOrEmpty(oneComp)) { CRuntimeLogger.LogWarning("Invalid element in Combine Table: ID = " + one.m_iID); bValid = false; break; } } if (bValid) { if (one.m_sCombine.Length < 2) { CRuntimeLogger.LogWarning("Invalid element in Combine Table: ID = " + one.m_iID); bValid = false; } } if (bValid) { ret.Add(one.m_sCombine); } } return(ret); }
public void OnWizardCreate() { if (string.IsNullOrEmpty(TypeName)) { CRuntimeLogger.LogWarning("你需要输入一个地形类型名称!"); return; } BuildTextureDataWithFolder(); }
/// <summary> /// after spawn, use this /// </summary> /// <param name="pData"></param> public void Initial(APahtData pData) { if (null == m_Task.m_pOwner) { m_Task.m_pOwner = this; } if (null == pData) { CRuntimeLogger.LogWarning("pNavMesh is null"); return; } if (null != m_pOwner) { //Initialed just reset m_Task.m_eProgress = EPathProgress.EPP_None; if (m_bBuilding) { m_Task.m_eProgress = EPathProgress.EPP_Building; } m_bAlive = true; return; } m_Task.m_eProgress = EPathProgress.EPP_None; if (m_bBuilding) { m_Task.m_eProgress = EPathProgress.EPP_Building; } m_bAlive = true; m_pOwner = pData; m_vGroundPos = m_pOwner.GetDefaultPos(); m_pOwner.RegisterAgent(this); }
public void PlayAnimation(EAnimationType eType, bool bRefresh = false) { if (null != m_pAnim && (EAnimationType.EAT_Born == eType || EAnimationType.EAT_Die == eType) && AnimationCullingType.AlwaysAnimate != m_pAnim.cullingType) { m_pAnim.cullingType = AnimationCullingType.AlwaysAnimate; } else if (null != m_pAnim && AnimationCullingType.BasedOnRenderers != m_pAnim.cullingType) { m_pAnim.cullingType = AnimationCullingType.BasedOnRenderers; } if (null == m_sAnimList || (int)EAnimationType.EAT_Max != m_sAnimList.Length) { return; } if ((eType != m_eAnimType || bRefresh) && null != m_pAnim) { // ReSharper disable ReplaceWithSingleAssignment.False bool bIgnore = false; // ReSharper disable once ConvertIfToOrExpression if ((EAnimationType.EAT_Idle == eType || EAnimationType.EAT_Run == eType || EAnimationType.EAT_Attack == eType) && ( EAnimationType.EAT_KnockDown == m_eAnimType || EAnimationType.EAT_Skill == m_eAnimType || EAnimationType.EAT_SkillHold == m_eAnimType || EAnimationType.EAT_Dash == m_eAnimType ) && m_fOnceAnimTime > 0.0f ) { bIgnore = true; } // ReSharper restore ReplaceWithSingleAssignment.False if (EAnimationType.EAT_Born == eType || EAnimationType.EAT_Die == eType ) { bIgnore = false; } EAnimationType eTypePlayed = eType; if (!bIgnore) { //CRuntimeLogger.Log(eType); switch (eType) { case EAnimationType.EAT_Idle: if (null == m_pAnim[m_sAnimList[(int)eType]]) { CRuntimeLogger.LogWarning("Animation list has animation not in Model:" + m_pOwner.gameObject.name + "@" + eType); return; } m_pAnim.CrossFade(m_sAnimList[(int)eType], 0.5f, PlayMode.StopAll); m_pAnim[m_sAnimList[(int)eType]].wrapMode = WrapMode.Loop; m_pAnim[m_sAnimList[(int)eType]].speed = Random.Range(0.85f, 1.15f) * m_fAnimSpeed[(int)eType]; break; case EAnimationType.EAT_Run: if (null == m_pAnim[m_sAnimList[(int)eType]]) { CRuntimeLogger.LogWarning("Animation list has animation not in Model:" + m_pOwner.gameObject.name + "@" + eType); return; } m_pAnim.CrossFade(m_sAnimList[(int)eType], 0.5f, PlayMode.StopAll); m_pAnim[m_sAnimList[(int)eType]].wrapMode = WrapMode.Loop; m_pAnim[m_sAnimList[(int)eType]].speed = Random.Range(0.85f, 1.15f) * m_fAnimSpeed[(int)eType]; break; case EAnimationType.EAT_Born: string sAnim = ""; if (null == m_pAnim[m_sAnimList[(int)eType]]) { sAnim = m_sAnimList[(int)EAnimationType.EAT_Idle]; } m_pAnim.CrossFade(sAnim, 0.01f, PlayMode.StopAll); m_pAnim[sAnim].normalizedTime = 0.0f; m_pAnim[sAnim].wrapMode = WrapMode.Clamp; m_pAnim[sAnim].speed = Random.Range(0.8f, 1.0f) * m_fAnimSpeed[(int)EAnimationType.EAT_Idle]; m_fOnceAnimTime = m_pAnim[m_sAnimList[(int)EAnimationType.EAT_Idle]].length * 0.99f / m_pAnim[m_sAnimList[(int)EAnimationType.EAT_Idle]].speed; m_pAnim.Sample(); break; case EAnimationType.EAT_Attack: case EAnimationType.EAT_Skill: //Only Avatar will enter this, for normal unit, will use PlayAttackAnimation function to play eTypePlayed = eType; if (null == m_pAnim[m_sAnimList[(int)eType]]) { eTypePlayed = EAnimationType.EAT_Attack; } if (null == m_pAnim[m_sAnimList[(int)eTypePlayed]]) { CRuntimeLogger.LogWarning("Animation list has animation not in Model:" + m_pOwner.gameObject.name + "@" + eTypePlayed); return; } m_pAnim.CrossFade(m_sAnimList[(int)eTypePlayed], 0.1f, PlayMode.StopAll); m_pAnim[m_sAnimList[(int)eTypePlayed]].normalizedTime = Random.Range(0.0f, 0.1f); m_pAnim[m_sAnimList[(int)eTypePlayed]].wrapMode = WrapMode.Once; m_pAnim[m_sAnimList[(int)eTypePlayed]].speed = Random.Range(0.9f, 1.1f) * m_fAnimSpeed[(int)eTypePlayed]; m_fOnceAnimTime = m_pAnim[m_sAnimList[(int)eTypePlayed]].length / m_pAnim[m_sAnimList[(int)eTypePlayed]].speed; break; case EAnimationType.EAT_Dash: case EAnimationType.EAT_SkillHold: //Only Avatar will enter this, for normal unit, will use PlayAttackAnimation function to play if (null == m_pAnim[m_sAnimList[(int)eType]]) { return; } m_pAnim.CrossFade(m_sAnimList[(int)eType], 0.1f, PlayMode.StopAll); m_pAnim[m_sAnimList[(int)eType]].normalizedTime = Random.Range(0.0f, 0.1f); m_pAnim[m_sAnimList[(int)eType]].wrapMode = WrapMode.Loop; m_pAnim[m_sAnimList[(int)eType]].speed = Random.Range(0.9f, 1.1f) * m_fAnimSpeed[(int)eType]; //TODO how to give a length for these? m_fOnceAnimTime = 1.0f; break; case EAnimationType.EAT_Die: if (null == m_pAnim[m_sAnimList[(int)eType]]) { CRuntimeLogger.LogWarning("Animation list has animation not in Model:" + m_pOwner.gameObject.name + "@" + eType); return; } m_pAnim.CrossFade(m_sAnimList[(int)eType], 0.1f, PlayMode.StopAll); m_pAnim[m_sAnimList[(int)eType]].normalizedTime = Random.Range(0.0f, 0.05f); m_pAnim[m_sAnimList[(int)eType]].wrapMode = WrapMode.Clamp; m_pAnim[m_sAnimList[(int)eType]].speed = Random.Range(0.85f, 1.15f) * m_fAnimSpeed[(int)eType]; m_fOnceAnimTime = m_pAnim[m_sAnimList[(int)eType]].length / m_pAnim[m_sAnimList[(int)eType]].speed; break; case EAnimationType.EAT_KnockDown: if (null == m_pAnim[m_sAnimList[(int)eType]]) { return; } m_pAnim.CrossFade(m_sAnimList[(int)eType], 0.1f, PlayMode.StopAll); m_pAnim[m_sAnimList[(int)eType]].normalizedTime = Random.Range(0.0f, 0.05f); m_pAnim[m_sAnimList[(int)eType]].wrapMode = WrapMode.Clamp; m_pAnim[m_sAnimList[(int)eType]].speed = Random.Range(0.85f, 1.15f) * m_fAnimSpeed[(int)eTypePlayed]; m_fOnceAnimTime = m_pAnim[m_sAnimList[(int)eType]].length / m_pAnim[m_sAnimList[(int)eType]].speed; break; } m_eAnimType = eType; } } }
protected void BuildTextureDataWithFolder() { #region Step1: Find all files string sFolderTx = Application.dataPath + "/" + SceneConstant.m_sArtworkPath + TypeName + SceneConstant.m_sSceneTexturesPath; string sFolderDoc = Application.dataPath + "/" + SceneConstant.m_sArtworkPath + TypeName + SceneConstant.m_sDecoratesPath; CRuntimeLogger.Log("将从" + sFolderTx + "和" + sFolderDoc + "收集信息"); DirectoryInfo dirtx = new DirectoryInfo(sFolderTx); DirectoryInfo dirdoc = new DirectoryInfo(sFolderDoc); if (!dirtx.Exists || !dirdoc.Exists) { CRuntimeLogger.LogWarning("你选择目录内容不太对吧!"); return; } List <FileInfo> allTextures = new List <FileInfo>(); allTextures.AddRange(dirtx.GetFiles("*.png", SearchOption.AllDirectories)); allTextures.AddRange(dirdoc.GetFiles("*.png", SearchOption.AllDirectories)); List <FileInfo> allModels = dirdoc.GetFiles("*.fbx", SearchOption.AllDirectories).ToList(); #endregion #region Step2: Create SceneType CSceneType scenetypes = new CSceneType(); scenetypes.Load(); if (null == scenetypes[TypeName]) { CSceneTypeElement newType = scenetypes.CreateElement(TypeName); newType.m_bCanRot = CanRotate; newType.m_eEdgeType = EdgeType; newType.m_iCliffType = CliffType; newType.m_bHasGroundOffset = HasGroundOffset; } else { scenetypes[TypeName].m_bCanRot = CanRotate; scenetypes[TypeName].m_eEdgeType = EdgeType; scenetypes[TypeName].m_iCliffType = CliffType; scenetypes[TypeName].m_bHasGroundOffset = HasGroundOffset; } scenetypes.Save(); #endregion #region Step3: Bake Texture Atlas Dictionary <int, int> codes = new Dictionary <int, int>(new IntEqualityComparer()); Dictionary <string, Texture2D> txDic = new Dictionary <string, Texture2D>(); foreach (FileInfo fileInfo in allTextures) { string sFileName = CommonFunctions.GetLastName(fileInfo.FullName); string[] twoparts = sFileName.Split('_'); string sAssetPath = "Assets" + fileInfo.FullName.Replace("\\", "/").Replace(Application.dataPath.Replace("\\", "/"), ""); Texture2D t1 = AssetDatabase.LoadAssetAtPath(sAssetPath, typeof(Texture2D)) as Texture2D; txDic.Add(sFileName, (Texture2D)EditorCommonFunctions.GetReadWritable(t1)); //Check whether is a template texture int iCode, iRepeat; if (2 == twoparts.Length && !string.IsNullOrEmpty(twoparts[0]) && int.TryParse(twoparts[0].Substring(1, twoparts[0].Length - 1), out iCode) && int.TryParse(twoparts[1], out iRepeat)) { if (codes.ContainsKey(iCode)) { if (codes[iCode] < iRepeat) { codes[iCode] = iRepeat; } } else { codes.Add(iCode, iRepeat); } } } Dictionary <string, Rect> textureDic = EditorCommonFunctions.PackTexture( txDic, SceneConstant.m_sArtworkPath + TypeName + SceneConstant.m_sSceneTexturesPath, Shader.Find("Mobile/Unlit (Supports Lightmap)"), EditorCommonFunctions.EPackColorFormat.ForcePng); #endregion #region Step4: Make template CSceneGroudTemplate tamplate = new CSceneGroudTemplate { m_sSceneType = TypeName }; foreach (KeyValuePair <string, Rect> kvp in textureDic) { CSceneGroudTemplateElement newGT = tamplate.CreateElement(); tamplate.ChangeName(newGT.m_sElementName, kvp.Key); newGT.m_vUV = CommonFunctions.Rect2V4(kvp.Value); } tamplate.Save(); #endregion #region Step5: Make Scene Texture CSceneTexture newT = new CSceneTexture { m_sSceneType = TypeName }; for (int lt = 0; lt < 3; ++lt) { for (int rt = 0; rt < 3; ++rt) { for (int rb = 0; rb < 3; ++rb) { for (int lb = 0; lb < 3; ++lb) { int iCode, iRots; bool bFlip; FindCodeAndRot(codes, lt, rt, rb, lb, out iCode, out iRots, out bFlip); if (iCode < 0) { CRuntimeLogger.LogError(string.Format("组合没有找到{0}-{1}-{2}-{3}", lt, rt, rb, lb)); return; } CSceneTextureElement newE = newT.CreateElement(); int iCode2 = lt * CommonFunctions.IntPow(3, 0) + rt * CommonFunctions.IntPow(3, 1) + rb * CommonFunctions.IntPow(3, 2) + lb * CommonFunctions.IntPow(3, 3); newT.ChangeName(newE.m_sElementName, "T" + iCode2); if (iCode2 != newE.m_iID) { newT.ChangeId(newE.m_iID, iCode2); } newE.m_iTemplate = iCode; newE.m_iRotNumber = iRots; newE.m_iTextureCount = codes[iCode]; newE.m_bReflect = bFlip; } } } } newT.Save(); #endregion #region Step6: Make Decorate Dictionary <int, string> modelTemplates = new Dictionary <int, string>(new IntEqualityComparer()); Dictionary <int, int> modelRepeates = new Dictionary <int, int>(new IntEqualityComparer()); foreach (FileInfo fileInfo in allModels) { string sFileName = CommonFunctions.GetLastName(fileInfo.FullName); string[] twoparts = sFileName.Split('_'); string sAssetPath = "Assets" + fileInfo.FullName.Replace("\\", "/").Replace(Application.dataPath.Replace("\\", "/"), ""); //Check whether is a template texture int iCode, iRepeat; if (3 == twoparts.Length && int.TryParse(twoparts[1], out iCode) && int.TryParse(twoparts[2], out iRepeat) && iCode < 3 && iCode >= 0) { //Make template data if (!modelTemplates.ContainsKey(iCode)) { modelTemplates.Add(iCode, twoparts[0] + "_" + iCode); } if (!modelRepeates.ContainsKey(iCode)) { modelRepeates.Add(iCode, iRepeat); } else if (modelRepeates[iCode] < iRepeat) { modelRepeates[iCode] = iRepeat; } //Make the mesh List <Vector3> verts = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <int> trangles = new List <int>(); GameObject go = AssetDatabase.LoadMainAssetAtPath(sAssetPath) as GameObject; if (null != go) { foreach (MeshFilter mf in go.GetComponentsInChildren <MeshFilter>(true)) { Mesh editablemesh = (Mesh)EditorCommonFunctions.GetReadWritable(mf.sharedMesh); int iVertCount = verts.Count; Rect rct; MeshRenderer mr = mf.gameObject.GetComponent <MeshRenderer>(); if (null != mr && null != mr.sharedMaterial && null != mr.sharedMaterial.mainTexture && textureDic.ContainsKey(mr.sharedMaterial.mainTexture.name)) { rct = textureDic[mr.sharedMaterial.mainTexture.name]; } else if (textureDic.ContainsKey(editablemesh.name)) { rct = textureDic[editablemesh.name]; } else { CRuntimeLogger.LogWarning("Mesh找不到贴图:" + sAssetPath); return; } if (mf.transform == go.transform) { verts.AddRange(editablemesh.vertices); } else { for (int i = 0; i < editablemesh.vertices.Length; ++i) { Vector3 worldPos = mf.transform.localToWorldMatrix.MultiplyVector(editablemesh.vertices[i]) + mf.transform.position; verts.Add(go.transform.worldToLocalMatrix.MultiplyVector(worldPos - go.transform.position)); } } for (int i = 0; i < editablemesh.uv.Length; ++i) { float fX = Mathf.Clamp01(editablemesh.uv[i].x); float fY = Mathf.Clamp01(editablemesh.uv[i].y); uvs.Add(new Vector2(rct.xMin + rct.width * fX, rct.yMin + rct.height * fY)); } for (int i = 0; i < editablemesh.triangles.Length; ++i) { trangles.Add(iVertCount + editablemesh.triangles[i]); } } } Mesh theMesh = new Mesh { vertices = verts.ToArray(), uv = uvs.ToArray(), triangles = trangles.ToArray() }; theMesh.RecalculateNormals(); Unwrapping.GenerateSecondaryUVSet(theMesh); ; AssetDatabase.CreateAsset(theMesh, "Assets/" + SceneConstant.m_sArtworkPath + TypeName + SceneConstant.m_sDecoratesPath + "/Generate/" + sFileName + ".asset"); } } CSceneDecorate doc = new CSceneDecorate { m_sSceneType = TypeName }; CSceneDecorate olddoc = new CSceneDecorate { m_sSceneType = TypeName }; olddoc.Load(); foreach (KeyValuePair <int, string> kvp in modelTemplates) { CSceneDecorateElement element = doc.CreateElement(kvp.Value); if (element.m_iID != kvp.Key) { doc.ChangeId(element.m_iID, kvp.Key); } element.m_iDecrateRepeat = modelRepeates[kvp.Key]; if (null != olddoc[kvp.Key]) { element.m_bBlockPathfinding = olddoc[kvp.Key].m_bBlockPathfinding; element.m_iDecrateSize = olddoc[kvp.Key].m_iDecrateSize; element.m_bOnlyRotateY = olddoc[kvp.Key].m_bOnlyRotateY; } } doc.Save(); AssetDatabase.Refresh(); #endregion }
public static Dictionary <string, string> CreateMeshes(SRendererInfo[] mesh, Dictionary <string, Rect> rectList, string sFileName, int iProgress, int iProgressFull) { Dictionary <string, string> ret = new Dictionary <string, string>(); //Load Mesh foreach (SRendererInfo info in mesh) { Mesh theMesh = EditorCommonFunctions.LoadMeshAtPathWithName(info.m_sMeshFilterName, info.m_pMesh.name); Mesh theMesh2 = new Mesh(); ++iProgress; EditorUtility.DisplayProgressBar("正在生成Atlas模型", string.Format("{0}/{1}", iProgress, iProgressFull), iProgress / (float)iProgressFull); List <Vector3> list1 = new List <Vector3>(); for (int i = 0; i < theMesh.vertices.Length; ++i) { list1.Add(theMesh.vertices[i]); } theMesh2.vertices = list1.ToArray(); List <int> list2 = new List <int>(); for (int i = 0; i < theMesh.triangles.Length; ++i) { list2.Add(theMesh.triangles[i]); } theMesh2.triangles = list2.ToArray(); List <Vector2> list3 = new List <Vector2>(); for (int i = 0; i < theMesh.uv.Length; ++i) { Vector2 vUV = theMesh.uv[i]; if (theMesh.uv[i].x <-0.01f || theMesh.uv[i].y <-0.01f || theMesh.uv[i].x> 1.01f || theMesh.uv[i].y> 1.01f) { CRuntimeLogger.LogWarning("UV is not in 0 - 1, clampled!: FBX:" + CommonFunctions.GetLastName(info.m_sMeshFilterName) + " Model:" + info.m_pMesh.name); vUV.x = Mathf.Repeat(theMesh.uv[i].x, 1.0f); vUV.y = Mathf.Repeat(theMesh.uv[i].y, 1.0f); } else { vUV.x = Mathf.Clamp01(theMesh.uv[i].x); vUV.y = Mathf.Clamp01(theMesh.uv[i].y); } Rect rect = rectList[info.m_sTextureName]; list3.Add(new Vector2(vUV.x * rect.width + rect.xMin, vUV.y * rect.height + rect.yMin)); } theMesh2.uv = list3.ToArray(); List <Vector2> list4 = new List <Vector2>(); for (int i = 0; i < theMesh.uv2.Length; ++i) { list4.Add(theMesh.uv2[i]); } theMesh2.uv2 = list4.ToArray(); List <Vector3> list5 = new List <Vector3>(); for (int i = 0; i < theMesh.normals.Length; ++i) { list5.Add(theMesh.normals[i]); } theMesh2.normals = list5.ToArray(); List <Color> list6 = new List <Color>(); for (int i = 0; i < theMesh.colors.Length; ++i) { list6.Add(theMesh.colors[i]); } theMesh2.colors = list6.ToArray(); List <Vector4> list7 = new List <Vector4>(); for (int i = 0; i < theMesh.tangents.Length; ++i) { list7.Add(theMesh.tangents[i]); } theMesh2.tangents = list7.ToArray(); ; //Create Mesh string sName = "f_" + CommonFunctions.GetLastName(info.m_sMeshFilterName) + "_m_" + info.m_pMesh.name + "_t_" + info.m_pTexture.name; string thePath = "Assets/" + sFileName + sName + ".asset"; AssetDatabase.CreateAsset(theMesh2, thePath); AssetDatabase.Refresh(); if (ret.ContainsKey(sName)) { CRuntimeLogger.LogError("有mesh的FBX文件重名!"); } else { ret.Add(sName, thePath); } } return(ret); }
public static Dictionary <string, string> CreateMeshes(SCharRendererFullInfo[] mesh, Dictionary <string, Rect> rectList, string sFileName, int iProgress, int iProgressFull, int iMc, int iSc) { Dictionary <string, string> ret = new Dictionary <string, string>(); //Load Mesh foreach (SCharRendererFullInfo info in mesh) { if (!info.m_bDiscard) { for (int i = 0; i < iMc; ++i) { for (int j = 0; j < iSc; ++j) { ++iProgress; EditorUtility.DisplayProgressBar("正在生成Atlas模型", string.Format("{0}/{1}", iProgress, iProgressFull), iProgress / (float)iProgressFull); if (!info.m_bCombine) { #region Not Combine string sTexture1 = string.Format("{0}_M{1}S{2}", info.m_sFullTexName, i, j); Mesh theMesh = (Mesh)EditorCommonFunctions.GetReadWritable(info.m_pMesh); Mesh theMesh1 = new Mesh(); theMesh1.SetVertices(theMesh.vertices.ToList()); theMesh1.SetTriangles(theMesh.triangles.ToList(), 0); List <Vector2> list1 = new List <Vector2>(); for (int k = 0; k < theMesh.uv.Length; ++k) { Vector2 vUV = theMesh.uv[k]; if (theMesh.uv[k].x <-0.01f || theMesh.uv[k].y <-0.01f || theMesh.uv[k].x> 1.01f || theMesh.uv[k].y> 1.01f) { CRuntimeLogger.LogWarning("UV is not in 0 - 1, clampled!: FBX:" + CommonFunctions.GetLastName(info.m_sMeshFilterName) + " Model:" + info.m_pMesh.name); } vUV.x = Mathf.Clamp01(theMesh.uv[k].x); vUV.y = Mathf.Clamp01(theMesh.uv[k].y); Rect rect1 = rectList[sTexture1]; list1.Add(new Vector2(vUV.x * rect1.width + rect1.xMin, vUV.y * rect1.height + rect1.yMin)); } theMesh1.uv = list1.ToArray(); theMesh1.uv2 = null; theMesh1.normals = null; theMesh1.colors = null; theMesh1.tangents = null; ; //Create Mesh string sName1 = string.Format("M{0}S{1}/", i, j) + CommonFunctions.GetLastName(info.m_sMeshFilterName) + "_" + info.m_pMesh.name + "_" + info.m_sFullTexName; AssetDatabase.CreateAsset(theMesh1, "Assets/" + sFileName + sName1 + ".asset"); if (ret.ContainsKey(sName1)) { CRuntimeLogger.LogWarning("有mesh的FBX文件重名!" + sName1); } else { ret.Add(sName1, "Assets/" + sFileName + sName1 + ".asset"); } #endregion } else { #region Combine List <Vector3> poses = new List <Vector3>(); List <int> indexes = new List <int>(); List <Vector2> uvs1 = new List <Vector2>(); for (int objIndex = 0; objIndex < info.m_pCombinedMeshObj.Length; ++objIndex) { string sTexture1 = string.Format("{0}_M{1}S{2}", info.m_sTextureNames[objIndex], i, j); Mesh theMesh = (Mesh)EditorCommonFunctions.GetReadWritable(info.m_pCombinedMesh[objIndex]); int iOldPosNum = poses.Count; if (0 == objIndex) { poses = theMesh.vertices.ToList(); } else { foreach (Vector3 vets in theMesh.vertices) { Vector3 worldPos = info.m_pCombinedMeshObj[objIndex].transform.localToWorldMatrix.MultiplyVector(vets) + info.m_pCombinedMeshObj[objIndex].transform.position; poses.Add(info.m_pCombinedMeshObj[0].transform.worldToLocalMatrix.MultiplyVector(worldPos - info.m_pCombinedMeshObj[0].transform.position)); } } if (0 == objIndex) { indexes = theMesh.triangles.ToList(); } else { foreach (int oneind in theMesh.triangles) { indexes.Add(oneind + iOldPosNum); } } for (int k = 0; k < theMesh.uv.Length; ++k) { Vector2 vUV = theMesh.uv[k]; vUV.x = Mathf.Clamp01(theMesh.uv[k].x); vUV.y = Mathf.Clamp01(theMesh.uv[k].y); Rect rect1 = rectList[sTexture1]; uvs1.Add(new Vector2(vUV.x * rect1.width + rect1.xMin, vUV.y * rect1.height + rect1.yMin)); } } Mesh theMesh1 = new Mesh(); theMesh1.SetVertices(poses); theMesh1.SetTriangles(indexes, 0); theMesh1.uv = uvs1.ToArray(); theMesh1.uv2 = null; theMesh1.normals = null; theMesh1.colors = null; theMesh1.tangents = null; ; //Create Mesh string sName1 = string.Format("M{0}S{1}/cmb_", i, j) + CommonFunctions.GetLastName(info.m_sMeshFilterName); AssetDatabase.CreateAsset(theMesh1, "Assets/" + sFileName + sName1 + ".asset"); if (ret.ContainsKey(sName1)) { CRuntimeLogger.LogWarning("有mesh的FBX文件重名!" + sName1); } else { ret.Add(sName1, "Assets/" + sFileName + sName1 + ".asset"); } #endregion } } } } } return(ret); }