private static Vector2[] GetUVs(int lt, int rt, int rb, int lb, CSceneTexture tx, CSceneGroudTemplate tem, bool bCanRot) { int iCode2 = lt * CommonFunctions.IntPow(3, 0) + rt * CommonFunctions.IntPow(3, 1) + rb * CommonFunctions.IntPow(3, 2) + lb * CommonFunctions.IntPow(3, 3); CSceneTextureElement txelement = tx[iCode2]; if (null == txelement) { CRuntimeLogger.LogError("贴图配置文件有问题"); return(null); } string sTxName = string.Format("T{0}_{1}", txelement.m_iTemplate, Random.Range(0, txelement.m_iTextureCount) + 1); Rect uv = CommonFunctions.V42Rect(tem[sTxName].m_vUV); int iRot = txelement.m_iRotNumber; bool bRot = lt == rt && lt == rb && lt == lb; if (bRot && bCanRot) { iRot += Random.Range(0, 4); } Vector2[] ret = { new Vector2(uv.xMin, uv.yMin + uv.height), new Vector2(uv.xMin + uv.width, uv.yMin + uv.height), new Vector2(uv.xMin + uv.width, uv.yMin), new Vector2(uv.xMin, uv.yMin) }; for (int i = 0; i < iRot; ++i) { Vector2 last = ret[0]; ret[0] = ret[1]; ret[1] = ret[2]; ret[2] = ret[3]; ret[3] = last; //Vector2 last = ret[3]; //ret[3] = ret[2]; //ret[2] = ret[1]; //ret[1] = ret[0]; //ret[0] = last; } return(ret); }
protected void BuildDesc(GameObject pEditing, bool bMerge) { CHumanoidDesc newDesc = new CHumanoidDesc(); CHumanoidDesc oldDesc = null; if (bMerge) { oldDesc = new CHumanoidDesc(); oldDesc.Load(); } foreach (MeshRenderer mesh in pEditing.GetComponentsInChildren <MeshRenderer>()) { CHumanoidDescElement element = newDesc.CreateElement(); if (!newDesc.ChangeName(element.m_sElementName, mesh.gameObject.name)) { CRuntimeLogger.LogError("名称重复了:" + mesh.gameObject.name); return; } element.m_sObjectPath = CommonFunctions.FindFullName(pEditing.gameObject, mesh.gameObject); element.m_sObjectPath = element.m_sObjectPath.Replace(pEditing.gameObject.name + "/", ""); if (null != oldDesc && null != oldDesc[element.m_sElementName]) { element.m_sTags = oldDesc[element.m_sElementName].m_sTags; element.m_iWeight = oldDesc[element.m_sElementName].m_iWeight; element.m_ePos = oldDesc[element.m_sElementName].m_ePos; element.m_eHumanSide = oldDesc[element.m_sElementName].m_eHumanSide; element.m_eHumanType = oldDesc[element.m_sElementName].m_eHumanType; element.m_eHumanWeapon = oldDesc[element.m_sElementName].m_eHumanWeapon; } else { element.m_iWeight = 1; #region Tags By Names #region Body if (element.m_sElementName.Contains("Body_F")) { element.m_ePos = EHumanoidComponentPos.ECP_Body; element.m_eHumanType = EHumanoidType.EHT_Female; element.m_sTags = new[] { "Body", "Female" }; } if (element.m_sElementName.Contains("Body_M")) { element.m_ePos = EHumanoidComponentPos.ECP_Body; element.m_eHumanType = EHumanoidType.EHT_Male; element.m_sTags = new[] { "Body", "Male" }; } #endregion #region Head if (element.m_sElementName.Contains("Head_F")) { element.m_ePos = EHumanoidComponentPos.ECP_Head; element.m_eHumanType = EHumanoidType.EHT_Female; element.m_sTags = new[] { "Head", "Female" }; if (!element.m_sElementName.Contains("Hat") && !element.m_sElementName.Contains("Glass")) { element.m_iWeight = 30; } else if (element.m_sElementName.Contains("Hat") && !element.m_sElementName.Contains("Glass")) { element.m_iWeight = 3; } else if (!element.m_sElementName.Contains("Hat") && element.m_sElementName.Contains("Glass")) { element.m_iWeight = 2; } else if (element.m_sElementName.Contains("Hat") && element.m_sElementName.Contains("Glass")) { element.m_iWeight = 1; } } if (element.m_sElementName.Contains("Head_M")) { element.m_ePos = EHumanoidComponentPos.ECP_Head; element.m_eHumanType = EHumanoidType.EHT_Male; element.m_sTags = new[] { "Head", "Male" }; } #endregion #region back, hand, foot, wing if (element.m_sElementName.Contains("_Back")) { element.m_ePos = EHumanoidComponentPos.ECP_Back; element.m_sTags = new[] { "Back", "Female", "Male" }; } if (element.m_sElementName.Contains("HandL")) { element.m_ePos = EHumanoidComponentPos.ECP_Hand; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_sTags = new[] { "Hand", "Female", "Male" }; } if (element.m_sElementName.Contains("HandR")) { element.m_ePos = EHumanoidComponentPos.ECP_Hand; element.m_eHumanSide = EHumanoidSide.EHT_Right; element.m_sTags = new[] { "Hand", "Female", "Male", "Right" }; } if (element.m_sElementName.Contains("HandL")) { element.m_ePos = EHumanoidComponentPos.ECP_Hand; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_sTags = new[] { "Hand", "Female", "Male", "Left" }; } if (element.m_sElementName.Contains("Feet_F") && element.m_sElementName.Contains("L")) { element.m_ePos = EHumanoidComponentPos.ECP_Feet; element.m_eHumanType = EHumanoidType.EHT_Female; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_sTags = new[] { "Foot", "Female", "Left" }; } if (element.m_sElementName.Contains("Feet_F") && element.m_sElementName.Contains("R")) { element.m_ePos = EHumanoidComponentPos.ECP_Feet; element.m_eHumanType = EHumanoidType.EHT_Female; element.m_eHumanSide = EHumanoidSide.EHT_Right; element.m_sTags = new[] { "Foot", "Female", "Right" }; } if (element.m_sElementName.Contains("Feet_M") && element.m_sElementName.Contains("L")) { element.m_ePos = EHumanoidComponentPos.ECP_Feet; element.m_eHumanType = EHumanoidType.EHT_Male; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_sTags = new[] { "Foot", "Male", "Left" }; } if (element.m_sElementName.Contains("Feet_M") && element.m_sElementName.Contains("R")) { element.m_ePos = EHumanoidComponentPos.ECP_Feet; element.m_eHumanType = EHumanoidType.EHT_Male; element.m_eHumanSide = EHumanoidSide.EHT_Right; element.m_sTags = new[] { "Foot", "Male", "Right" }; } if (element.m_sElementName.Contains("LWing")) { element.m_ePos = EHumanoidComponentPos.ECP_Wing; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_sTags = new[] { "Wing", "Female", "Male", "Left" }; } if (element.m_sElementName.Contains("RWing")) { element.m_ePos = EHumanoidComponentPos.ECP_Wing; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Right; element.m_sTags = new[] { "Wing", "Female", "Male", "Right" }; } #endregion #region Weapon //===================================================== //weapon if (element.m_sElementName.Contains("SHandWeapon_R")) { element.m_ePos = EHumanoidComponentPos.ECP_Weapon; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Right; element.m_eHumanWeapon = EHumanoidWeapon.EHT_SingleHand_Fight; if (element.m_sElementName.Contains("SHandWeapon_R_W")) { element.m_sTags = new[] { "Weapon", "SHand", "Wizard", "Female", "Male", "Right" }; } else { element.m_sTags = new[] { "Weapon", "SHand", "Fight", "Female", "Male", "Right" }; } } if (element.m_sElementName.Contains("Shoot_R")) { element.m_ePos = EHumanoidComponentPos.ECP_Weapon; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Right; element.m_eHumanWeapon = EHumanoidWeapon.EHT_Shoot; element.m_sTags = new[] { "Weapon", "Shoot", "Female", "Male", "Right" }; } if (element.m_sElementName.Contains("DHandWeapon_Sword")) { element.m_ePos = EHumanoidComponentPos.ECP_Weapon; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Right; element.m_eHumanWeapon = EHumanoidWeapon.EHT_DoubleHand_Fight; element.m_sTags = new[] { "Weapon", "DHand", "Fight", "Female", "Male", "Right" }; } if (element.m_sElementName.Contains("DHandWeapon_Stick")) { element.m_ePos = EHumanoidComponentPos.ECP_Weapon; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Right; element.m_eHumanWeapon = EHumanoidWeapon.EHT_DoubleHand_Wizard; element.m_sTags = new[] { "Weapon", "DHand", "Wizard", "Female", "Male", "Right" }; } if (element.m_sElementName.Contains("SHandWeapon_Shield")) { element.m_ePos = EHumanoidComponentPos.ECP_Weapon; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_eHumanWeapon = EHumanoidWeapon.EHT_SingleHand_Fight; element.m_sTags = new[] { "Weapon", "SHand", "Fight", "Wizard", "Female", "Male", "Left" }; } if (element.m_sElementName.Contains("SHandWeapon_L")) { element.m_ePos = EHumanoidComponentPos.ECP_Weapon; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_eHumanWeapon = EHumanoidWeapon.EHT_SingleHand_Fight; element.m_sTags = new[] { "Weapon", "SHand", "Fight", "Female", "Male", "Left" }; } if (element.m_sElementName.Contains("Weapon_Shoot_L")) { element.m_ePos = EHumanoidComponentPos.ECP_Weapon; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_eHumanWeapon = EHumanoidWeapon.EHT_Shoot; element.m_sTags = new[] { "Weapon", "Shoot", "Female", "Male", "Left" }; } #endregion #region etc if (element.m_sElementName.Contains("Shadow")) { element.m_ePos = EHumanoidComponentPos.ECP_Shadow; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_sTags = new[] { "Shadow" }; } if (element.m_sElementName.Contains("BloodLineFront")) { element.m_ePos = EHumanoidComponentPos.ECP_BloodLineFront; element.m_eHumanType = EHumanoidType.EHT_Both; element.m_eHumanSide = EHumanoidSide.EHT_Left; element.m_sTags = new[] { "BloodLineFront" }; } #endregion #endregion } } newDesc.Save(); m_pEditingData = newDesc; RefreshData(); }
/// <summary> /// Using the input gridsState to find a path, not using any H-functions. Should only use in Editor. /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="gridsState"></param> /// <param name="length">length of the path, -1 if path not exist</param> /// <returns>path</returns> static public S2DPoint[] StrictAStar(S2DPoint start, S2DPoint end, byte[] gridsState, out float length) { if (start == end) { length = 0.0f; return(new[] { start }); } if (m_byWalkable != gridsState[start]) { length = -1.0f; //CRuntimeLogger.LogWarning("Start is not a walkable"); return(null); } ++m_iAStarIndex; _tmpOpList[start] = m_iAStarIndex; _tmpParentList[start] = 0; _tmpFVList[start] = 0.0f; _tmpDistToParentList[start] = 0.0f; m_opList.Clear(); m_opList.Add(start); int iOpenListStart = 0; int iProtect = m_iAstarProtect; while (m_opList.Count > iOpenListStart && iProtect > 0) { --iProtect; if (iProtect < 0) { CRuntimeLogger.LogError("No Way!"); length = -1.0f; return(null); } //find lowest f in open list //lowest f is always the first one S2DPoint pLowestF = m_opList[iOpenListStart]; //If in close list, skip it if (m_iAStarIndex == _tmpClsList[pLowestF]) { ++iOpenListStart; continue; } if (m_byWalkable != gridsState[pLowestF]) { CRuntimeLogger.LogError("No Way!"); length = -1.0f; return(null); } //Add to close list _tmpClsList[pLowestF] = m_iAStarIndex; if (pLowestF == end) { break; } //Open List is sorted, just add one index for next loop ++iOpenListStart; m_tmpNewAddNode.Clear(); #region Connect Points //check connected points for (short i = -1; i < 2; ++i) { for (short j = -1; j < 2; ++j) { if (i != 0 || j != 0) { S2DPoint connect = (i + pLowestF.m_iX) * SceneConstant.m_iSceneSize + (j + pLowestF.m_iY); if (connect.m_bValid && m_byWalkable == gridsState[connect] && _tmpClsList[connect] != m_iAStarIndex) { if (_tmpOpList[connect] != m_iAStarIndex) { _tmpParentList[connect] = pLowestF + 1; _tmpOpList[connect] = m_iAStarIndex; float fDist = (connect.m_iX == pLowestF.m_iX || connect.m_iY == pLowestF.m_iY) ? m_fStraightDist : m_fDiagDist; _tmpDistToParentList[connect] = fDist; _tmpFVList[connect] = _tmpFVList[pLowestF] + fDist; m_tmpNewAddNode.Add(connect); } else { float fNewDist = (connect.m_iX == pLowestF.m_iX || connect.m_iY == pLowestF.m_iY) ? m_fStraightDist : m_fDiagDist; float newF = _tmpFVList[pLowestF] + fNewDist; //Check F Value if (newF < _tmpFVList[connect]) { _tmpFVList[connect] = newF; _tmpDistToParentList[connect] = fNewDist; _tmpParentList[connect] = pLowestF + 1; m_tmpNewAddNode.Add(connect); } } } } } } #endregion #region New Lowest F, Resort Order for (int i = 0; i < m_tmpNewAddNode.Count; ++i) { int iInsertPos = -1; for (int j = iOpenListStart; j < m_opList.Count; ++j) { if (_tmpFVList[m_tmpNewAddNode[i]] < _tmpFVList[m_opList[j]]) { iInsertPos = j; break; } } // the connect point may be add into an open list twice (or even more) // however it dose not harm, because the first place is the lowestF // after lowest F, it is in close list, and will be skipped anywhere if (-1 == iInsertPos) { m_opList.Add(m_tmpNewAddNode[i]); } else { m_opList.Insert(iInsertPos, m_tmpNewAddNode[i]); } } #endregion } if (_tmpParentList[end] > 0) { m_res.Clear(); m_res.Add(end); length = 0.0f; S2DPoint pLastParent = end; int iProtected2 = m_iAstarProtect; while (_tmpParentList[pLastParent] > 0 && iProtected2 > 0) { --iProtected2; if (iProtected2 < 0) { length = -1.0f; CRuntimeLogger.LogError("what?"); return(null); } S2DPoint parent = _tmpParentList[pLastParent] - 1; m_res.Insert(0, parent); length += _tmpDistToParentList[pLastParent];; pLastParent = parent; } return(m_res.ToArray()); } length = -1.0f; //CRuntimeLogger.LogWarning(string.Format("End does not have a parent. protect: {0}, oplist: {1}, opstart: {2}", iProtect, m_opList.Count, iOpenListStart)); return(null); }
void OnWizardCreate() { #region Step1: Check files if (string.IsNullOrEmpty(TemplateName)) { CRuntimeLogger.LogError("必须有个模板名称"); return; } Texture2D heighttx = (Texture2D)EditorCommonFunctions.GetReadWritable(HeightMap); if (null == heighttx || SceneConstant.m_iHightmapSize != heighttx.width || SceneConstant.m_iHightmapSize != heighttx.height) { CRuntimeLogger.LogError(string.Format("必须是{0}x{0}的高度贴图,如果你的图片正确,可以检查下导入设置是否是Editor/GUI", SceneConstant.m_iHightmapSize)); return; } Texture2D groundtx = (Texture2D)EditorCommonFunctions.GetReadWritable(GroundMap); if (null == groundtx || SceneConstant.m_iHightmapSize != groundtx.width || SceneConstant.m_iHightmapSize != groundtx.height) { CRuntimeLogger.LogError(string.Format("必须是{0}x{0}的地皮贴图,如果你的图片正确,可以检查下导入设置是否是Editor/GUI", SceneConstant.m_iHightmapSize)); return; } Texture2D doctx = (Texture2D)EditorCommonFunctions.GetReadWritable(DocMap); if (null == doctx || SceneConstant.m_iDecoratemapSize != doctx.width || SceneConstant.m_iDecoratemapSize != doctx.height) { CRuntimeLogger.LogError(string.Format("必须是{0}x{0}的装饰贴图", SceneConstant.m_iDecoratemapSize)); return; } #endregion #region Step2: Create string sGroundFileName = SceneConstant.m_sArtworkPath + "Templates/" + string.Format("T{0}X{0}", SceneConstant.m_iHightmapSize) + "/GenerateMesh/" + TemplateName + ".asset"; Texture2D wmap, nmap; SceneEditorUtility.CreateGround(heighttx, groundtx, doctx, sGroundFileName, GroundType, false, out wmap, out nmap); CSceneTexture sceneTx = new CSceneTexture { m_sSceneType = GroundType }; if (!sceneTx.Load() || 81 != sceneTx.m_pElement.Count) { CRuntimeLogger.LogError(GroundType + "贴图配置文件有问题"); return; } CSceneGroudTemplate groundTemplate = new CSceneGroudTemplate { m_sSceneType = GroundType }; if (!groundTemplate.Load()) { CRuntimeLogger.LogError(GroundType + "贴图配置文件有问题"); return; } CSceneType type = new CSceneType(); type.Load(); if (null == type[GroundType]) { CRuntimeLogger.LogError(GroundType + "的配置找不到?"); return; } #endregion #region Step3: Make Record CSceneTemplate templates = new CSceneTemplate(); templates.Load(); CSceneTemplateElement element = templates[TemplateName]; if (null == element) { element = templates.CreateElement(TemplateName); } element.m_sDecoratePath = AssetDatabase.GetAssetPath(DocMap); element.m_sGroundPath = AssetDatabase.GetAssetPath(GroundMap); element.m_sHeightPath = AssetDatabase.GetAssetPath(HeightMap); templates.Save(); #endregion }
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 void CreateGround(Texture2D heighttx, Texture2D groundtx, Texture2D doctx, string sGroundFileName, string sGroundType, bool bCreatePathmap, out Texture2D wmap, out Texture2D nmap) { #region Step1: Check files wmap = null; nmap = null; CSceneTexture sceneTx = new CSceneTexture { m_sSceneType = sGroundType }; if (!sceneTx.Load() || 81 != sceneTx.m_pElement.Count) { CRuntimeLogger.LogError(sGroundType + "贴图配置文件有问题"); return; } CSceneGroudTemplate groundTemplate = new CSceneGroudTemplate { m_sSceneType = sGroundType }; if (!groundTemplate.Load()) { CRuntimeLogger.LogError(sGroundType + "贴图配置文件有问题"); return; } CSceneType type = new CSceneType(); type.Load(); if (null == type[sGroundType]) { CRuntimeLogger.LogError(sGroundType + "的配置找不到?"); return; } #endregion #region Step2: Read colors and make cliff ground type replace, 4096 x 4 int iProgressOne = heighttx.width * heighttx.height; int iProgressTotal = iProgressOne * 10; int iProgressNow = 0; if (bCreatePathmap) { wmap = new Texture2D(heighttx.width - 1, heighttx.height - 1, TextureFormat.RGB24, false); nmap = new Texture2D(heighttx.width - 1, heighttx.height - 1, TextureFormat.RGB24, false); } Vector3[,] verts = new Vector3[heighttx.width, heighttx.height]; int[,] gtypes = new int[heighttx.width, heighttx.height]; for (int i = 0; i < heighttx.width; ++i) { for (int j = 0; j < heighttx.height; ++j) { ++iProgressNow; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "读高度图数据", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); Color h = heighttx.GetPixel(i, j); Color g = groundtx.GetPixel(i, j); verts[i, j] = new Vector3( i - (heighttx.width - 1) / 2, (h.r - 0.5f) * 2.0f * SceneConstant.m_fHighgroundHeight, j - (heighttx.height - 1) / 2); gtypes[i, j] = CompareRGB(g.r, g.g, g.b); } } iProgressNow = iProgressOne; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "读高度图数据", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); //Make Clifs for (int i = 0; i < heighttx.width - 1; ++i) { for (int j = 0; j < heighttx.height - 1; ++j) { if (Mathf.Max(verts[i, j].y, verts[i + 1, j].y, verts[i + 1, j + 1].y, verts[i, j + 1].y) - Mathf.Min(verts[i, j].y, verts[i + 1, j].y, verts[i + 1, j + 1].y, verts[i, j + 1].y) > SceneConstant.m_fCliffRate * SceneConstant.m_fHighgroundHeight) { gtypes[i, j] = type[sGroundType].m_iCliffType; gtypes[i + 1, j] = type[sGroundType].m_iCliffType; gtypes[i + 1, j + 1] = type[sGroundType].m_iCliffType; gtypes[i, j + 1] = type[sGroundType].m_iCliffType; } ++iProgressNow; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "改写悬崖", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); } } iProgressNow = iProgressOne * 2; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "改写悬崖", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); if (type[sGroundType].m_bHasGroundOffset) { for (int i = 0; i < heighttx.width; ++i) { for (int j = 0; j < heighttx.height; ++j) { verts[i, j] += Vector3.up * gtypes[i, j] * 0.05f * SceneConstant.m_fHighgroundHeight; ++iProgressNow; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "改写地皮高度", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); } } } iProgressNow = iProgressOne * 3; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "改写地皮高度", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); if (bCreatePathmap) { for (int i = 0; i < heighttx.width - 1; ++i) { for (int j = 0; j < heighttx.height - 1; ++j) { float fR, fG, fB; Vector3 vNormal = Vector3.Cross(verts[i, j + 1] - verts[i + 1, j], verts[i + 1, j + 1] - verts[i, j]); vNormal = vNormal.normalized * 0.5f + new Vector3(0.5f, 0.5f, 0.5f); float fHeight = (verts[i, j].y + verts[i + 1, j].y + verts[i + 1, j + 1].y + verts[i, j + 1].y) * 0.25f; fR = fHeight / (SceneConstant.m_fHighgroundHeight * 4.0f) + 0.5f; bool bHasCutOff = verts[i, j].y < SceneConstant.m_fHighgroundHeight * SceneConstant.m_fCutOffHeightRate || verts[i + 1, j].y < SceneConstant.m_fHighgroundHeight * SceneConstant.m_fCutOffHeightRate || verts[i + 1, j + 1].y < SceneConstant.m_fHighgroundHeight * SceneConstant.m_fCutOffHeightRate || verts[i, j + 1].y < SceneConstant.m_fHighgroundHeight * SceneConstant.m_fCutOffHeightRate; if (Mathf.Max(verts[i, j].y, verts[i + 1, j].y, verts[i + 1, j + 1].y, verts[i, j + 1].y) - Mathf.Min(verts[i, j].y, verts[i + 1, j].y, verts[i + 1, j + 1].y, verts[i, j + 1].y) > SceneConstant.m_fCliffRate * SceneConstant.m_fHighgroundHeight) { bHasCutOff = true; } fB = bHasCutOff ? 1.0f : 0.0f; fG = bHasCutOff ? 0.0f : 1.0f; wmap.SetPixel(i, j, new Color(fR, fG, fB, 1.0f)); nmap.SetPixel(i, j, new Color(vNormal.x, vNormal.y, vNormal.z, 1.0f)); ++iProgressNow; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "创建寻路地图", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); } } wmap.Apply(); //apply for farther read } iProgressNow = iProgressOne * 4; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "创建寻路地图", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); #endregion #region Step3: Build the ground, 4096 List <Vector3> poses = new List <Vector3>(); List <Vector2> theuvs = new List <Vector2>(); List <int> trangles = new List <int>(); //Create Mesh for (int i = 0; i < (heighttx.width - 1); ++i) { for (int j = 0; j < (heighttx.height - 1); ++j) { ++iProgressNow; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "创建地面", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); Vector2[] uvs = GetUVs(gtypes[i, j], gtypes[i + 1, j], gtypes[i + 1, j + 1], gtypes[i, j + 1], sceneTx, groundTemplate, type[sGroundType].m_bCanRot); Vector3[] vs = { verts[i, j], verts[i + 1, j], verts[i + 1, j + 1], verts[i, j + 1] }; //Check Vanish if (vs[0].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[1].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[2].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[3].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight) { //No trangles } else if (vs[0].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[1].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[2].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight) { //Hide 0-1-2, add 0-2-3 int iIndexNow = poses.Count; poses.Add(vs[0]); poses.Add(vs[2]); poses.Add(vs[3]); theuvs.Add(uvs[0]); theuvs.Add(uvs[2]); theuvs.Add(uvs[3]); trangles.Add(iIndexNow + 0); trangles.Add(iIndexNow + 2); trangles.Add(iIndexNow + 1); } else if (vs[1].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[2].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[3].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight) { //Hide 1-2-3, add 0-1-3 int iIndexNow = poses.Count; poses.Add(vs[0]); poses.Add(vs[1]); poses.Add(vs[3]); theuvs.Add(uvs[0]); theuvs.Add(uvs[1]); theuvs.Add(uvs[3]); trangles.Add(iIndexNow + 0); trangles.Add(iIndexNow + 2); trangles.Add(iIndexNow + 1); } else if (vs[0].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[2].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[3].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight) { //Hide 0-2-3, add 0-1-2 int iIndexNow = poses.Count; poses.Add(vs[0]); poses.Add(vs[1]); poses.Add(vs[2]); theuvs.Add(uvs[0]); theuvs.Add(uvs[1]); theuvs.Add(uvs[2]); trangles.Add(iIndexNow + 0); trangles.Add(iIndexNow + 2); trangles.Add(iIndexNow + 1); } else if (vs[0].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[1].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight && vs[3].y < SceneConstant.m_fCutOffHeightRate * SceneConstant.m_fHighgroundHeight) { //Hide 0-1-3, add 1-2-3 int iIndexNow = poses.Count; poses.Add(vs[1]); poses.Add(vs[2]); poses.Add(vs[3]); theuvs.Add(uvs[1]); theuvs.Add(uvs[2]); theuvs.Add(uvs[3]); trangles.Add(iIndexNow + 0); trangles.Add(iIndexNow + 2); trangles.Add(iIndexNow + 1); } else { //Add all int iIndexNow = poses.Count; poses.Add(vs[0]); poses.Add(vs[1]); poses.Add(vs[2]); poses.Add(vs[3]); theuvs.Add(uvs[0]); theuvs.Add(uvs[1]); theuvs.Add(uvs[2]); theuvs.Add(uvs[3]); trangles.Add(iIndexNow + 0); trangles.Add(iIndexNow + 3); trangles.Add(iIndexNow + 1); trangles.Add(iIndexNow + 1); trangles.Add(iIndexNow + 3); trangles.Add(iIndexNow + 2); } } } iProgressNow = iProgressOne * 5; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "保存地面(需要等一下)...", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); Mesh theMesh = new Mesh { vertices = poses.ToArray(), uv = theuvs.ToArray(), triangles = trangles.ToArray() }; theMesh.RecalculateNormals(); Unwrapping.GenerateSecondaryUVSet(theMesh); ; AssetDatabase.CreateAsset(theMesh, "Assets/" + sGroundFileName); AssetDatabase.Refresh(); GameObject newGround = new GameObject(); newGround.transform.position = Vector3.zero; newGround.AddComponent <MeshRenderer>().sharedMaterial = AssetDatabase.LoadAssetAtPath <Material>("Assets/" + SceneConstant.m_sArtworkPath + sGroundType + SceneConstant.m_sSceneTexturesPath + ".mat"); newGround.AddComponent <MeshFilter>().sharedMesh = AssetDatabase.LoadAssetAtPath <Mesh>("Assets/" + sGroundFileName); newGround.name = "Ground"; #endregion #region Step4: Put Decorates 4096 x 5 CSceneDecorate doc = new CSceneDecorate { m_sSceneType = sGroundType }; doc.Load(); bool[, ,] chs = new bool[3, doctx.width, doctx.height]; for (int i = 0; i < doctx.width; ++i) { for (int j = 0; j < doctx.height; ++j) { Color h = doctx.GetPixel(i, j); chs[0, i, j] = h.r > 0.5f; chs[1, i, j] = h.g > 0.5f; chs[2, i, j] = h.b > 0.5f; ++iProgressNow; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "读障碍物分布图", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); } } iProgressNow = iProgressOne * 6; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "读障碍物分布图", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); List <CDecorateInfo> addDocs = new List <CDecorateInfo>(); for (int i = 0; i < doctx.width; ++i) { for (int j = 0; j < doctx.height; ++j) { for (int k = 0; k < 3; ++k) { ++iProgressNow; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "放置障碍物", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); if (null != doc[k]) { if (chs[k, i, j]) { if (bCreatePathmap && doc[k].m_bBlockPathfinding) { Color colorNow = wmap.GetPixel(i, j); wmap.SetPixel(i, j, new Color(colorNow.r, 0.0f, 1.0f)); } if (2 == doc[k].m_iDecrateSize && i < (doctx.width - 1) && j < (doctx.height - 1) && chs[k, i + 1, j] && chs[k, i, j + 1] && chs[k, i + 1, j + 1]) { addDocs.Add(new CDecorateInfo { m_iCh = k, m_vMid = new Vector3( i - (doctx.width / 2 - 1), verts[i + 1, j + 1].y, j - (doctx.height / 2 - 1)), m_iSize = 2 }); chs[k, i + 1, j] = false; chs[k, i, j + 1] = false; chs[k, i + 1, j + 1] = false; if (bCreatePathmap && doc[k].m_bBlockPathfinding) { Color colorNow1 = wmap.GetPixel(i + 1, j); wmap.SetPixel(i + 1, j, new Color(colorNow1.r, 0.0f, 1.0f)); Color colorNow2 = wmap.GetPixel(i, j + 1); wmap.SetPixel(i, j + 1, new Color(colorNow2.r, 0.0f, 1.0f)); Color colorNow3 = wmap.GetPixel(i + 1, j + 1); wmap.SetPixel(i + 1, j + 1, new Color(colorNow3.r, 0.0f, 1.0f)); } } else { addDocs.Add(new CDecorateInfo { m_iCh = k, m_vMid = new Vector3( i - (doctx.width / 2 - 1) - 0.5f, 0.25f * (verts[i, j].y + verts[i + 1, j].y + verts[i, j + 1].y + verts[i + 1, j + 1].y), j - (doctx.height / 2 - 1) - 0.5f), m_iSize = 1 }); } } } } } } iProgressNow = iProgressOne * 9; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "放置障碍物", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); int iDecIndex = 0; foreach (CDecorateInfo dc in addDocs) { ++iProgressNow; EditorUtility.DisplayProgressBar("创建中", string.Format("{0}...{1}/{2}", "创建障碍物", iProgressNow, iProgressTotal), iProgressNow / (float)iProgressTotal); GameObject newDec = new GameObject(); newDec.transform.position = dc.m_vMid + new Vector3( Random.Range(-0.2f, 0.2f), doc[dc.m_iCh].m_bOnlyRotateY ? 0.0f : Random.Range(-0.2f, 0.2f), Random.Range(-0.2f, 0.2f)); newDec.transform.eulerAngles = doc[dc.m_iCh].m_bOnlyRotateY ? new Vector3(0.0f, Random.Range(-360.0f, 360.0f), 0.0f) : new Vector3(Random.Range(-360.0f, 360.0f), Random.Range(-360.0f, 360.0f), Random.Range(-360.0f, 360.0f)); if (2 == dc.m_iSize) { if (!doc[dc.m_iCh].m_bOnlyRotateY) { newDec.transform.localScale = new Vector3( Random.Range(1.6f, 2.4f), Random.Range(1.6f, 2.4f), Random.Range(1.6f, 2.4f) ); } else { newDec.transform.localScale = new Vector3( Random.Range(1.6f, 2.4f), Random.Range(0.8f, 1.2f), Random.Range(1.6f, 2.4f) ); } } else { newDec.transform.localScale = new Vector3( Random.Range(0.8f, 1.2f), Random.Range(0.8f, 1.2f), Random.Range(0.8f, 1.2f) ); } string sMeshName = doc[dc.m_iCh].m_sElementName + "_" + Random.Range(1, doc[dc.m_iCh].m_iDecrateRepeat); newDec.AddComponent <MeshRenderer>().sharedMaterial = AssetDatabase.LoadAssetAtPath <Material>("Assets/" + SceneConstant.m_sArtworkPath + sGroundType + SceneConstant.m_sSceneTexturesPath + ".mat"); newDec.AddComponent <MeshFilter>().sharedMesh = AssetDatabase.LoadAssetAtPath <Mesh>("Assets/" + SceneConstant.m_sArtworkPath + sGroundType + SceneConstant.m_sDecoratesPath + "/Generate/" + sMeshName + ".asset"); newDec.name = "Dec" + iDecIndex; newDec.transform.parent = newGround.transform; ++iDecIndex; } #endregion EditorUtility.ClearProgressBar(); if (bCreatePathmap) { wmap.Apply(); nmap.Apply(); } }
public void EditorFix() { #region Find All List <GameObject> allGos = new List <GameObject>(); foreach (MeshRenderer renderers in GetComponentsInChildren <MeshRenderer>(true)) { allGos.Add(renderers.gameObject); } m_pAllComponents = allGos.ToArray(); if (m_pAllComponents.Length >= m_iMaxCount) { CRuntimeLogger.LogError("零件数量超出上限1000个!"); return; } #endregion m_pDesc = new CHumanoidDesc(); m_pDesc.Load(); #region Find hand, feet, wings, body, back, head m_pHands = FindPartWithTags(true, new[] { "Hand", "Left" }); m_pFemaleFeet = FindPartWithTags(true, new[] { "Foot", "Female", "Left" }); m_pMaleFeet = FindPartWithTags(true, new[] { "Foot", "Male", "Left" }); m_pWings = FindPartWithTags(true, new[] { "Wing", "Left" }); m_pFemaleBody = FindPartWithTags(false, new[] { "Body", "Female" }); m_pMaleBody = FindPartWithTags(false, new[] { "Body", "Male" }); m_pBacks = FindPartWithTags(false, new[] { "Back" }); m_pFemaleHead = FindPartWithTags(false, new[] { "Head", "Female" }); m_pMaleHead = FindPartWithTags(false, new[] { "Head", "Male" }); #endregion #region Find Weapons CHumanoidDescElement[] sHandFightRight = m_pDesc[new[] { "SHand", "Fight", "Right" }]; CHumanoidDescElement[] sHandWizardRight = m_pDesc[new[] { "SHand", "Wizard", "Right" }]; CHumanoidDescElement[] sHandFightLeft = m_pDesc[new[] { "SHand", "Fight", "Left" }]; CHumanoidDescElement[] sHandWizardLeft = m_pDesc[new[] { "SHand", "Wizard", "Left" }]; m_pAllPosibleSHandCombineFight = new int[sHandFightRight.Length + sHandFightRight.Length * sHandFightLeft.Length]; //Single Hand Fight for (int i = 0; i < sHandFightRight.Length; ++i) { m_pAllPosibleSHandCombineFight[i] = FindIndex(sHandFightRight[i].m_sObjectPath) + 1; } //Single Hand Fight 2 hands for (int i = 0; i < sHandFightRight.Length; ++i) { for (int j = 0; j < sHandFightLeft.Length; ++j) { m_pAllPosibleSHandCombineFight[sHandFightRight.Length + i * sHandFightLeft.Length + j] = FindIndex(sHandFightRight[i].m_sObjectPath) + 1 + m_iMaxCount * (FindIndex(sHandFightLeft[j].m_sObjectPath) + 1); } } m_pAllPosibleSHandCombineWizard = new int[sHandWizardRight.Length + sHandWizardRight.Length * sHandWizardLeft.Length]; //Single Hand Wizard for (int i = 0; i < sHandWizardRight.Length; ++i) { m_pAllPosibleSHandCombineWizard[i] = FindIndex(sHandWizardRight[i].m_sObjectPath) + 1; } //Single Hand Wizard 2 hands for (int i = 0; i < sHandWizardRight.Length; ++i) { for (int j = 0; j < sHandWizardLeft.Length; ++j) { m_pAllPosibleSHandCombineWizard[sHandWizardRight.Length + i * sHandWizardLeft.Length + j] = FindIndex(sHandWizardRight[i].m_sObjectPath) + 1 + m_iMaxCount * (FindIndex(sHandWizardLeft[j].m_sObjectPath) + 1); } } //Single Shoot CHumanoidDescElement[] sShoot = m_pDesc[new[] { "Shoot" }]; m_pAllPosibleShoot = new int[sShoot.Length]; for (int i = 0; i < sShoot.Length; ++i) { m_pAllPosibleShoot[i] = FindIndex(sShoot[i].m_sObjectPath) + 1; } //Single DHand Fight CHumanoidDescElement[] sDHandFight = m_pDesc[new[] { "DHand", "Fight" }]; m_pAllPosibleDHandCombineFight = new int[sDHandFight.Length]; for (int i = 0; i < sDHandFight.Length; ++i) { m_pAllPosibleDHandCombineFight[i] = FindIndex(sDHandFight[i].m_sObjectPath) + 1; } //Single DHand Wizard CHumanoidDescElement[] sDHandWizard = m_pDesc[new[] { "DHand", "Wizard" }]; m_pAllPosibleDHandCombineWizard = new int[sDHandWizard.Length]; for (int i = 0; i < sDHandWizard.Length; ++i) { m_pAllPosibleDHandCombineWizard[i] = FindIndex(sDHandWizard[i].m_sObjectPath) + 1; } #endregion #region Others m_pBoltPos = new GameObject[(int)EHumanoidWeapon.EHT_Max]; m_pBoltPos[(int)EHumanoidWeapon.EHW_BareHand] = CommonFunctions.FindChildrenByName(gameObject, "BHandBoltPos", true); m_pBoltPos[(int)EHumanoidWeapon.EHT_SingleHand_Fight] = CommonFunctions.FindChildrenByName(gameObject, "SHandBoltPos"); m_pBoltPos[(int)EHumanoidWeapon.EHT_SingleHand_Wizard] = CommonFunctions.FindChildrenByName(gameObject, "SHandBoltPos"); m_pBoltPos[(int)EHumanoidWeapon.EHT_Shoot] = CommonFunctions.FindChildrenByName(gameObject, "ShootBoltPos"); m_pBoltPos[(int)EHumanoidWeapon.EHT_DoubleHand_Fight] = CommonFunctions.FindChildrenByName(gameObject, "DHandBoltPos"); m_pBoltPos[(int)EHumanoidWeapon.EHT_DoubleHand_Wizard] = CommonFunctions.FindChildrenByName(gameObject, "DHandBoltPos"); m_pShadow = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/Shadow"); m_pBloodLineShell = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell").transform; m_pBloodLineFront = new GameObject[8]; m_pBloodLineFront[0] = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell/BloodLineFront1"); m_pBloodLineFront[1] = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell/BloodLineFront2"); m_pBloodLineFront[2] = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell/BloodLineFront3"); m_pBloodLineFront[3] = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell/BloodLineFront4"); m_pBloodLineFront[4] = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell/BloodLineFront5"); m_pBloodLineFront[5] = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell/BloodLineFront6"); m_pBloodLineFront[6] = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell/BloodLineFront7"); m_pBloodLineFront[7] = CommonFunctions.FindChildrenByName(gameObject, "Humanoid/BloodLineShell/BloodLineFront8"); m_pOwner = gameObject.transform.parent.gameObject.GetComponent <ACharactor>(); m_pOwner.m_pModel = this; m_pAnim = GetComponent <ACharactorAnimation>(); m_pOwner.m_pAnim = m_pAnim; m_pAnim.m_pOwner = m_pOwner; m_pAnim.m_pModel = this; m_pAnim.m_pAnim = GetComponent <Animation>(); #endregion }
public static void MakeAtlasReplaceWithCloth(GameObject pObj, string sParentFolder) { #region Step0: Count Progress int iMC = (int)ECharactorMainColor.ECMC_Max; int iSC = (int)ECharactorSubColor.ECSC_Max + 1; List <string[]> combineList = GetHumanoidCombineList(); int iProgressCount = pObj.GetComponentsInChildren <MeshRenderer>(true).Length + combineList.Count; int iProgressFull = iProgressCount * (2 + 3 * iMC * iSC); int iProgressNow = 0; #endregion #region Step1: make gameobject table and make dirs (1x) CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Textures/?"); for (int i = 0; i < iMC; ++i) { for (int j = 0; j < iSC; ++j) { CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Resources/CharMesh/" + string.Format("M{0}S{1}/?", i, j)); } } List <SCharRendererFullInfo> info = new List <SCharRendererFullInfo>(); Dictionary <string, Texture2D[]> contextureCombine = new Dictionary <string, Texture2D[]>(); Dictionary <string, int> infoIndex = new Dictionary <string, int>(); foreach (MeshRenderer renderer in pObj.GetComponentsInChildren <MeshRenderer>(true)) { ++iProgressNow; EditorUtility.DisplayProgressBar("正在收集Renderer信息", string.Format("{0}/{1}", iProgressNow, iProgressFull), iProgressNow / (float)iProgressFull); Texture2D mainTex = renderer.sharedMaterial.GetTexture("_MainTex") as Texture2D; Texture2D colorTex = renderer.sharedMaterial.GetTexture("_ColorTex") as Texture2D; Texture2D shaTex = renderer.sharedMaterial.GetTexture("_ShadowTex") as Texture2D; if (null == mainTex || null == colorTex || null == shaTex) { CRuntimeLogger.LogError("有的材质没有贴图: " + CommonFunctions.FindFullName(pObj, renderer.gameObject)); EditorUtility.ClearProgressBar(); return; } string sTextureName = CommonFunctions.BuildStringOrder(new[] { mainTex.name, colorTex.name, shaTex.name }); Mesh mesh = renderer.gameObject.GetComponent <MeshFilter>().sharedMesh; info.Add(new SCharRendererFullInfo { m_sFullTexName = sTextureName, m_pMesh = mesh, m_sMeshFilterName = AssetDatabase.GetAssetPath(mesh), m_sMeshName = mesh.name, m_pObj = renderer.gameObject, m_sObjectPath = CommonFunctions.FindFullName(pObj, renderer.gameObject), m_pMainTexture = mainTex, m_pColorTexture = colorTex, m_pShaTexture = shaTex, m_pCombinedMesh = new Mesh[0], m_bDiscard = false, m_pCombinedMeshObj = null, m_bCombine = false, }); infoIndex.Add(CommonFunctions.FindFullName(pObj, renderer.gameObject), info.Count - 1); if (!contextureCombine.ContainsKey(sTextureName)) { contextureCombine.Add(sTextureName, new[] { mainTex, colorTex, shaTex }); } } iProgressNow = iProgressCount; #endregion #region Step2: make colored textures (20x) CCharactorColor colors = new CCharactorColor(); colors.Load(); Dictionary <string, Texture2D> outTexture = new Dictionary <string, Texture2D>(); for (int i = 0; i < iMC; ++i) { for (int j = 0; j < iSC; ++j) { Color mainC = colors[string.Format("M{0}", i + 1)].m_cColor; Color subC = Color.white * 0.7f; if (j < (int)ECharactorSubColor.ECSC_Max) { subC = colors[string.Format("S{0}", j + 1)].m_cColor; } foreach (KeyValuePair <string, Texture2D[]> kvp in contextureCombine) { ++iProgressNow; EditorUtility.DisplayProgressBar("正在阵营着色", string.Format("{0}/{1}", iProgressNow, iProgressFull), iProgressNow / (float)iProgressFull); Texture2D outPutT = GetTexture2DWithColor(kvp.Value[0], kvp.Value[1], kvp.Value[2], mainC, subC, j == (int)ECharactorSubColor.ECSC_Max); outTexture.Add(string.Format("{0}_M{1}S{2}", kvp.Key, i, j), outPutT); } iProgressNow = (i * iSC + j + 2) * iProgressCount; } } Shader unlit = Shader.Find("Unlit/Texture"); string sPackTextureName = sParentFolder + "/Textures/" + unlit.name.Replace("/", "_").Replace(".", "_"); Dictionary <string, Rect> packed = EditorCommonFunctions.PackTexture(outTexture, sPackTextureName, unlit, EditorCommonFunctions.EPackColorFormat.ForcePng); #endregion #region Step3: Combine Batch (1x) List <string> sDisableList = new List <string>(); foreach (string[] combines in combineList) { ++iProgressNow; EditorUtility.DisplayProgressBar("正在收集合并Batch信息", string.Format("{0}/{1}", iProgressNow, iProgressFull), iProgressNow / (float)iProgressFull); GameObject parent = info[infoIndex[pObj.name + "/" + combines[0]]].m_pObj; SCharRendererFullInfo cmb = new SCharRendererFullInfo { m_sObjectPath = CommonFunctions.FindFullName(pObj, parent.transform.parent.gameObject) + "/", m_bDiscard = false, m_pObj = null, m_pTransfParentPath = pObj.name + "/" + combines[0], m_bCombine = true, }; string sMeshFilterName = ""; List <GameObject> cmbobjs = new List <GameObject>(); List <Mesh> cmbmeshes = new List <Mesh>(); List <string> cmbtextures = new List <string>(); foreach (string t in combines) { if (!sDisableList.Contains(pObj.name + "/" + t)) { sDisableList.Add(pObj.name + "/" + t); } GameObject theObj = info[infoIndex[pObj.name + "/" + t]].m_pObj; cmb.m_sObjectPath += theObj.name; sMeshFilterName += theObj.name; cmbobjs.Add(theObj); cmbmeshes.Add(info[infoIndex[pObj.name + "/" + t]].m_pMesh); cmbtextures.Add(info[infoIndex[pObj.name + "/" + t]].m_sFullTexName); } cmb.m_pCombinedMeshObj = cmbobjs.ToArray(); cmb.m_pCombinedMesh = cmbmeshes.ToArray(); cmb.m_sTextureNames = cmbtextures.ToArray(); cmb.m_sMeshFilterName = sMeshFilterName; info.Add(cmb); } foreach (string namecmbdisable in sDisableList) { info[infoIndex[namecmbdisable]].m_bDiscard = true; } iProgressNow = (2 + iMC * iSC) * iProgressCount; #endregion #region Step4: Create Meshes (20x) Dictionary <string, string> meshDic = CreateMeshes(info.ToArray(), packed, sParentFolder + "/Resources/CharMesh/", iProgressNow, iProgressFull, iMC, iSC); AssetDatabase.Refresh(); iProgressNow = (2 + iMC * iSC * 2) * iProgressCount; #endregion #region Step5: Assemble Game Objects (20x) //Create the matrix for (int i = 0; i < iMC; ++i) { for (int j = 0; j < iSC; ++j) { CreateObj(i, j, info, meshDic, "Assets/" + sPackTextureName + ".mat", pObj, iProgressNow, iProgressFull); iProgressNow = ((2 + iMC * iSC * 2) + ((i * iSC) + j + 1)) * iProgressCount; } } #endregion EditorUtility.ClearProgressBar(); }
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 void MakeAtlasReplace(GameObject pObj, string sParentFolder, bool bForceTransparent = false) { int iProgressFull = pObj.GetComponentsInChildren <MeshRenderer>(true).Length; iProgressFull = iProgressFull * 3; int iProgressNow = 0; //======================================== //Step 1, find all renderes need to atlas Dictionary <Shader, List <SRendererInfo> > typedRenderers = new Dictionary <Shader, List <SRendererInfo> >(); foreach (MeshRenderer renderer in pObj.GetComponentsInChildren <MeshRenderer>(true)) { ++iProgressNow; EditorUtility.DisplayProgressBar("正在收集Renderer信息", string.Format("{0}/{1}", iProgressNow, iProgressFull), iProgressNow / (float)iProgressFull); if (!typedRenderers.ContainsKey(renderer.sharedMaterial.shader)) { typedRenderers.Add(renderer.sharedMaterial.shader, new List <SRendererInfo>()); } typedRenderers[renderer.sharedMaterial.shader].Add(new SRendererInfo { m_sTextureName = AssetDatabase.GetAssetPath(renderer.sharedMaterial.mainTexture), m_sMeshFilterName = AssetDatabase.GetAssetPath(renderer.gameObject.GetComponent <MeshFilter>().sharedMesh), m_pShader = renderer.sharedMaterial.shader, m_sObjectPath = CommonFunctions.FindFullName(pObj, renderer.gameObject), m_pTexture = (Texture2D)renderer.sharedMaterial.mainTexture, m_pMesh = renderer.gameObject.GetComponent <MeshFilter>().sharedMesh, m_pObj = renderer.gameObject, }); if (null == renderer.sharedMaterial.mainTexture) { CRuntimeLogger.LogError("有的材质没有贴图: " + CommonFunctions.FindFullName(pObj, renderer.gameObject)); EditorUtility.ClearProgressBar(); return; } } CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Textures/?"); CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Meshes/?"); GameObject copy = Object.Instantiate(pObj, pObj.transform.position + Vector3.left * 3.0f, pObj.transform.rotation) as GameObject; Debug.Assert(copy != null, "copy != null"); copy.name = pObj.name + "_Atlas"; foreach (KeyValuePair <Shader, List <SRendererInfo> > kvp in typedRenderers) { //======================================== //Create Texture and Material Dictionary <string, Texture2D> uniqueTextures = new Dictionary <string, Texture2D>(); foreach (SRendererInfo info in kvp.Value) { if (!uniqueTextures.ContainsKey(info.m_sTextureName)) { uniqueTextures.Add(info.m_sTextureName, info.m_pTexture); } } Texture2D[] allTextures = uniqueTextures.Values.ToArray(); string sTextureFileName = sParentFolder + "/Textures/" + kvp.Key.name.Replace("/", "_").Replace(".", "_"); Dictionary <string, Rect> textureDic = EditorCommonFunctions.PackTextureInDataBase(allTextures, sTextureFileName, kvp.Key, EditorCommonFunctions.EPackColorFormat.ForcePng); //======================================== //Create Mesh with new UV Dictionary <string, SRendererInfo> uniqueMeshes = new Dictionary <string, SRendererInfo>(); foreach (SRendererInfo info in kvp.Value) { string sName = "f_" + CommonFunctions.GetLastName(info.m_sMeshFilterName) + "_m_" + info.m_pMesh.name + "_t_" + info.m_pTexture.name; if (!uniqueMeshes.ContainsKey(sName)) { uniqueMeshes.Add(sName, info); } } Dictionary <string, string> oldNewMeshDic = CreateMeshes( uniqueMeshes.Values.ToArray(), textureDic, sParentFolder + "/Meshes/", iProgressNow, iProgressFull); iProgressNow += oldNewMeshDic.Count; //======================================== //Create a new gameobject and replace the material and mesh filter foreach (SRendererInfo info in kvp.Value) { ++iProgressNow; EditorUtility.DisplayProgressBar("正在组装", string.Format("{0}/{1}", iProgressNow, iProgressFull), iProgressNow / (float)iProgressFull); string sName = "f_" + CommonFunctions.GetLastName(info.m_sMeshFilterName) + "_m_" + info.m_pMesh.name + "_t_" + info.m_pTexture.name; string sPath = oldNewMeshDic[sName]; GameObject toReplace = GameObject.Find(info.m_sObjectPath.Replace(pObj.name, pObj.name + "_Atlas")); toReplace.GetComponent <Renderer>().sharedMaterial = AssetDatabase.LoadAssetAtPath("Assets/" + sTextureFileName + ".mat", typeof(Material)) as Material; toReplace.GetComponent <Renderer>().lightProbeUsage = LightProbeUsage.Off; toReplace.GetComponent <Renderer>().shadowCastingMode = ShadowCastingMode.Off; toReplace.GetComponent <Renderer>().receiveShadows = false; toReplace.GetComponent <Renderer>().reflectionProbeUsage = ReflectionProbeUsage.Off; toReplace.GetComponent <MeshFilter>().sharedMesh = AssetDatabase.LoadAssetAtPath(sPath, typeof(Mesh)) as Mesh; } iProgressNow += oldNewMeshDic.Count; } EditorUtility.ClearProgressBar(); }