private void CreateScreenShot() { string path = Util.FixPath(EditorUtility.SaveFilePanel("Select Export Path", "Assets", Util.GetNameWithoutExtension(VoxelFilePath) + "_screenShot", "png")); if (!string.IsNullOrEmpty(path)) { path = Util.FixedRelativePath(path); if (!string.IsNullOrEmpty(path)) { bool oldShow = ShowBackgroundBox; CubeTF.gameObject.SetActive(false); SetBoxBackgroundActive(false); var texture = Util.RenderTextureToTexture2D(Camera); if (texture) { texture = Util.TrimTexture(texture, 0.01f, 12); Util.ByteToFile(texture.EncodeToPNG(), path); VoxelPostprocessor.AddScreenshot(path); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorApplication.delayCall += VoxelPostprocessor.ClearAsset; } CubeTF.gameObject.SetActive(true); SetBoxBackgroundActive(oldShow); } else { Util.Dialog("Warning", "Export path must in Assets folder.", "OK"); } } }
private void CreateSprite(Core_Sprite.SpriteType type) { if (!Data) { return; } string path = Util.FixPath(EditorUtility.SaveFilePanel("Select Export Path", "Assets", Util.GetNameWithoutExtension(VoxelFilePath) + type.ToString(), "png")); if (!string.IsNullOrEmpty(path)) { path = Util.FixedRelativePath(path); if (!string.IsNullOrEmpty(path)) { bool oldShow = ShowBackgroundBox; CubeTF.gameObject.SetActive(false); SetBoxBackgroundActive(false); var result = Core_Sprite.CreateSprite( Data, CurrentModelIndex, type, GetSpriteNum(type), GetSpriteLight(type), GetSpritePivot(type), Camera, Sprite25DCameraScale ); CubeTF.gameObject.SetActive(true); SetBoxBackgroundActive(oldShow); if (result.Texture) { Util.ByteToFile(result.Texture.EncodeToPNG(), path); VoxelPostprocessor.AddSprite(path, new VoxelPostprocessor.SpriteConfig() { width = result.Width, height = result.Height, Pivots = result.Pivots, spriteRects = result.Rects, Names = result.NameFixes, }); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); EditorApplication.delayCall += VoxelPostprocessor.ClearAsset; } } else { Util.Dialog("Warning", "Export path must in Assets folder.", "OK"); } } }
private static bool BrowseExportPath() { string newPath = Util.FixPath(EditorUtility.OpenFolderPanel("Select Export Path", ExportPath, "")); if (!string.IsNullOrEmpty(newPath)) { newPath = Util.FixedRelativePath(newPath); if (!string.IsNullOrEmpty(newPath)) { ExportPath.Value = newPath; return(true); } else { Util.Dialog("Warning", "Export path must in Assets folder.", "OK"); } } return(false); }
// Data #endregion #region --- TSK --- private void CreateSprite(bool _8bit) { if (!Data) { return; } string path = Util.FixPath(EditorUtility.SaveFilePanel("Select Export Path", "Assets", Util.GetNameWithoutExtension(VoxelFilePath) + (_8bit ? "_8bit" : "_2D"), "png")); if (!string.IsNullOrEmpty(path)) { path = Util.FixedRelativePath(path); if (!string.IsNullOrEmpty(path)) { var result = _8bit ? EditorSpriteCore.Create8bitSprite(Data, CurrentModelIndex) : EditorSpriteCore.Create2DSprite(Data, CurrentModelIndex); if (result.Texture) { Util.ByteToFile(result.Texture.EncodeToPNG(), path); VoxelPostprocessor.AddSprite(path, new VoxelPostprocessor.SpriteConfig() { width = result.Width, height = result.Height, Pivots = result.Pivots, spriteRects = result.Rects, Names = result.NameFixes, }); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); EditorApplication.delayCall += VoxelPostprocessor.ClearAsset; } } else { Util.Dialog("Warning", "Export path must in Assets folder.", "OK"); } } }
private void CombinerGUI() { const int ITEM_SIZE = 72; const int ITEM_GAP = 4; const int CONTENT_WIDTH = 536; const int COUNT_X = (CONTENT_WIDTH - ITEM_GAP) / (ITEM_SIZE + ITEM_GAP); // Prefabs LayoutH(() => { // Content LayoutV(() => { Space(8); var style = new GUIStyle() { fixedWidth = ITEM_SIZE, }; int currentIndex = 0; while (currentIndex < CombineList.Count) { LayoutH(() => { Space(ITEM_GAP); for (int x = 0; x < COUNT_X && currentIndex < CombineList.Count; x++) { bool continueFlag = false; // Item LayoutV(() => { var prefab = CombineList[currentIndex]; if (prefab.Prefab) { // Preview var rect = GUIRect(ITEM_SIZE, ITEM_SIZE); var preview = prefab.Preview ?? (prefab.Preview = AssetPreview.GetAssetPreview(prefab.Prefab.gameObject)); GUI.DrawTexture(rect, preview ?? Texture2D.whiteTexture, ScaleMode.ScaleToFit); // Name GUI.Label(GUIRect(ITEM_SIZE, 18), prefab.Prefab.name); // Highlight if (currentIndex == SelectingPrefabIndex) { var oldColor = GUI.color; GUI.color = Color.green; GUI.Box(rect, GUIContent.none); GUI.color = oldColor; } // Click if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) { SelectingPrefabIndex = currentIndex; Event.current.Use(); } currentIndex++; } else { CombineList.RemoveAt(currentIndex); currentIndex--; continueFlag = true; } }, false, style); Space(ITEM_GAP); if (continueFlag) { continue; } } }); Space(ITEM_GAP); } if (CombineList.Count == 0) { Space(4); LayoutH(() => { GUIRect(12, 36); EditorGUI.HelpBox(GUIRect(420, 36), "No prefab in list.\nClick \"+ Prefab\" button or drag prefab into this window to add prefab.", MessageType.Info); }); Space(4); } Space(4); // Add Button var _rect = GUIRect(82, 24); _rect.x = 0; if (GUI.Button(_rect, "+ Prefab", EditorStyles.miniButtonRight)) { AddCombinePrefab( Util.FixedRelativePath(EditorUtility.OpenFilePanel("Pick Prefab", "Assets", "prefab")) ); } // Clear Button Space(2); _rect = GUIRect(82, 24); _rect.x = 0; if (GUI.Button(_rect, "Clear", EditorStyles.miniButtonRight)) { if (Util.Dialog("", "Remove all prefabs in the list?", "Remove All", "Cancel")) { ClearScene(); CombineList.Clear(); SelectingPrefabIndex = -1; Repaint(); } } Space(8); }, false, new GUIStyle() { fixedWidth = CONTENT_WIDTH, }); // Panel if (SelectingPrefabIndex >= 0 && SelectingPrefabIndex < CombineList.Count) { LayoutV(() => { var prefab = CombineList[SelectingPrefabIndex]; if (prefab.Prefab) { // Name GUI.Label(GUIRect(0, 18), SelectingPrefabIndex + ", " + prefab.Prefab.name); Space(6); // Transform LayoutH(() => { GUI.Label(GUIRect(67, 18), "Position"); prefab.Object.localPosition = EditorGUI.Vector3Field(GUIRect(0, 18), "", prefab.Object.localPosition); }); LayoutH(() => { GUI.Label(GUIRect(67, 18), "Rotation"); prefab.Rotation = EditorGUI.Vector3Field(GUIRect(0, 18), "", prefab.Rotation); prefab.Object.localRotation = Quaternion.Euler(prefab.Rotation); }); LayoutH(() => { GUI.Label(GUIRect(67, 18), "Scale"); prefab.Object.localScale = EditorGUI.Vector3Field(GUIRect(0, 18), "", prefab.Object.localScale); }); Space(8); // Delete Button LayoutH(() => { GUIRect(0, 1); if (GUI.Button(GUIRect(72, 18), "Remove") && Util.Dialog("", "Remove prefab" + prefab.Prefab.name + " from list?", "Remove", "Cancel")) { if (prefab.Object) { DestroyImmediate(prefab.Object.gameObject, false); } CombineList.RemoveAt(SelectingPrefabIndex); SelectingPrefabIndex = CombineList.Count == 0 ? -1 : Mathf.Clamp(SelectingPrefabIndex, 0, CombineList.Count - 1); Repaint(); } }); Space(8); } }, true); } else { LayoutV(() => { GUIRect(0, 1); }); } }); }
private void CombinePrefab(bool combineMesh) { if (!CombinerEditingRoot || CombinerEditingRoot.childCount == 0) { return; } var path = Util.FixedRelativePath(EditorUtility.SaveFilePanel("Save Combined Prefab", "Assets", "Combined Prefab", "prefab")); if (string.IsNullOrEmpty(path)) { return; } try { var result = Core_Combine.Combine( CombinerEditingRoot, combineMesh, (msg, progress) => { Util.ProgressBar("Combining", msg, progress); } ); if (result != null) { // Empty Prefab if (Util.FileExists(path)) { Object[] things = AssetDatabase.LoadAllAssetRepresentationsAtPath(path); foreach (Object o in things) { DestroyImmediate(o, true); } } else { var tempObject = new GameObject(); SavePrefab(tempObject, path, true); DestroyImmediate(tempObject, false); } // Add Sub Objects In AssetDatabase.AddObjectToAsset(result.Texture, path); for (int i = 0; i < result.Meshs.Count; i++) { AssetDatabase.AddObjectToAsset(result.Meshs[i], path); } for (int i = 0; i < result.Materials.Count; i++) { AssetDatabase.AddObjectToAsset(result.Materials[i], path); } // Override Prefab SavePrefab(result.Root.gameObject, path); DestroyImmediate(result.Root.gameObject, false); // Done AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); AssetDatabase.SaveAssets(); Resources.UnloadUnusedAssets(); } } catch (System.Exception ex) { Debug.LogError(ex.Message); } Util.ClearProgressBar(); }
public static void CreateFileForResult(List <Core_Voxel.Result> resultList, Shader[] shaders, string[] shaderKeywords, Vector2[] shaderRemaps, float scale, Vector3 pivot) { var diffuseShader = shaders[0]; for (int index = 0; index < resultList.Count; index++) { var result = resultList[index]; bool lod = result.VoxelModels.Length > 1; bool isRig = !lod && result.IsRigged; int realLodNum = result.IsRigged ? 1 : result.VoxelModels.Length; var root = new GameObject(result.FileName).transform; var meshs = new List <Mesh>(); var materialsMap = new Dictionary <Texture2D, Material[]>(); Transform[] lodRoots = new Transform[realLodNum]; for (int lodIndex = 0; lodIndex < realLodNum; lodIndex++) { var voxelModel = result.VoxelModels[lodIndex]; var model = CreateModelFrom(voxelModel.RootNode, voxelModel.Materials, root, pivot, ref meshs, ref materialsMap, isRig, result.WithAvatar, shaders, shaderKeywords, shaderRemaps, scale); model.name = string.Format("Root{0}", lod ? "_lod " + lodIndex.ToString() : ""); lodRoots[lodIndex] = model; // Rig if (isRig) { Vector3 halfModelSize = voxelModel.ModelSize[0] * 0.5f; halfModelSize.x = Mathf.Floor(halfModelSize.x); halfModelSize.y = Mathf.Floor(halfModelSize.y); halfModelSize.z = Mathf.Floor(halfModelSize.z); var skinMR = model.GetComponent <SkinnedMeshRenderer>(); if (skinMR) { Vector3 rootBoneOffset = halfModelSize * scale; var boneTFList = new List <Transform>(); if (voxelModel.RootBones != null) { for (int i = 0; i < voxelModel.RootBones.Length; i++) { var boneTF = CreateBoneTransform(voxelModel.RootBones[i], model, scale, ref boneTFList); if (boneTF) { boneTF.localPosition -= rootBoneOffset; } } } skinMR.bones = boneTFList.ToArray(); skinMR.rootBone = model; // Bind Poses var poses = new Matrix4x4[boneTFList.Count]; for (int i = 0; i < boneTFList.Count; i++) { poses[i] = boneTFList[i].worldToLocalMatrix * model.localToWorldMatrix; } skinMR.sharedMesh.bindposes = poses; } // Foot Fix model.localPosition = (halfModelSize - voxelModel.FootPoints[lodIndex]) * scale; } } // Lod if (lod) { LODGroup group = root.gameObject.AddComponent <LODGroup>(); LOD[] lods = new LOD[realLodNum]; for (int i = 0; i < realLodNum; i++) { lods[i] = new LOD( i == realLodNum - 1 ? 0.001f : GetLodRant(result.VoxelModels[i].MaxModelBounds, i), lodRoots[i].GetComponentsInChildren <MeshRenderer>(true) ); } #if UNITY_5_0 || UNITY_5_1 || UNITY_4 group.SetLODS(lods); group.RecalculateBounds(); #else group.SetLODs(lods); group.RecalculateBounds(); #endif } else if (!isRig && root.childCount > 0) { var newRoot = root.GetChild(0); newRoot.name = root.name; root = newRoot; } // File string path = Util.CombinePaths( result.ExportRoot, result.ExportSubRoot, result.FileName + result.Extension ); path = Util.FixPath(path); string parentPath = Util.GetParentPath(path); Util.CreateFolder(parentPath); if (result.Extension == ".prefab") { Object prefab; if (Util.FileExists(path)) { prefab = AssetDatabase.LoadAssetAtPath <Object>(path); if (prefab as GameObject) { var group = (prefab as GameObject).GetComponent <LODGroup>(); if (group) { Object.DestroyImmediate(group, true); } } Object[] things = AssetDatabase.LoadAllAssetRepresentationsAtPath(path); foreach (Object o in things) { Object.DestroyImmediate(o, true); } } else { #if UNITY_4 || UNITY_5 || UNITY_2017 || UNITY_2018_1 || UNITY_2018_2 prefab = PrefabUtility.CreateEmptyPrefab(path); #else // 2018.3+ var tempObject = new GameObject(); prefab = PrefabUtility.SaveAsPrefabAsset(tempObject, path); Object.DestroyImmediate(tempObject, false); #endif } if (prefab) { // Assets for (int i = 0; i < meshs.Count; i++) { meshs[i].name = GetIndexedName("Mesh", i, meshs.Count); AssetDatabase.AddObjectToAsset(meshs[i], path); } int currentIndex = 0; foreach (var textureMat in materialsMap) { textureMat.Key.name = GetIndexedName("Texture", currentIndex, materialsMap.Count); AssetDatabase.AddObjectToAsset(textureMat.Key, path); var mats = textureMat.Value; for (int i = 0; i < mats.Length; i++) { mats[i].name = GetIndexedName("Material", currentIndex, materialsMap.Count) + "_" + i.ToString(); AssetDatabase.AddObjectToAsset(mats[i], path); } currentIndex++; } // Avatar if (isRig && result.WithAvatar) { var avatar = GetVoxelAvatarInRoot(root); if (avatar) { avatar.name = result.FileName; AssetDatabase.AddObjectToAsset(avatar, path); // Animator var ani = root.GetComponent <Animator>(); if (!ani) { ani = root.gameObject.AddComponent <Animator>(); } ani.avatar = avatar; } else { Debug.LogWarning("[Voxel to Unity] Failed to get avatar from the prefab. Use \"+ Human Bones\" button in rig editor to create bones and don\'t change their names and layout."); } } // Prefab #if UNITY_4 || UNITY_5 || UNITY_2017 || UNITY_2018_1 || UNITY_2018_2 PrefabUtility.ReplacePrefab(root.gameObject, prefab, ReplacePrefabOptions.ReplaceNameBased); #else // 2018.3+ prefab = PrefabUtility.SaveAsPrefabAsset(root.gameObject, path); #endif } } else // Obj { string objFolderPath = Util.CombinePaths(parentPath, result.FileName); string textureFolderPath = Util.CombinePaths(objFolderPath, "Textures"); Util.CreateFolder(objFolderPath); VoxelPostprocessor.TheShader = diffuseShader; // Assets var model = result.VoxelModels[0]; for (int modelIndex = 0; modelIndex < model.Meshs.Length; modelIndex++) { string modelIndexedName = GetIndexedName(result.FileName, modelIndex, model.Meshs.Length); string modelPathRoot = Util.CombinePaths(objFolderPath, modelIndexedName); // Texture string texturePath = Util.CombinePaths(textureFolderPath, modelIndexedName + ".png"); texturePath = Util.FixPath(texturePath); var texture = model.Textures[modelIndex]; Util.ByteToFile(texture.EncodeToPNG(), texturePath); VoxelPostprocessor.AddTexture(texturePath); // Meshs var uMesh = model.Meshs[modelIndex]; for (int i = 0; i < uMesh.Count; i++) { uMesh[i].name = GetIndexedName("Mesh", i, uMesh.Count); string obj = Util.GetObj(uMesh[i]); string objPath = GetIndexedName(modelPathRoot, i, uMesh.Count) + ".obj"; bool hasObjBefore = Util.FileExists(objPath); Util.Write(obj, objPath); VoxelPostprocessor.AddObj(objPath, texturePath); if (hasObjBefore) { AssetDatabase.ImportAsset(Util.FixedRelativePath(objPath), ImportAssetOptions.ForceUpdate); } } } } // Delete Objects if (root.parent) { Object.DestroyImmediate(root.parent.gameObject, false); } else { Object.DestroyImmediate(root.gameObject, false); } } AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); AssetDatabase.SaveAssets(); Resources.UnloadUnusedAssets(); EditorApplication.delayCall += VoxelPostprocessor.ClearAsset; }
// LGC private void OnPreprocessModel() { string fullPath = Util.GetFullPath(assetImporter.assetPath); ModelImporter mi = assetImporter as ModelImporter; if (AssetMap.ContainsKey(fullPath)) { string texturePath = AssetMap[fullPath]; mi.materialSearch = ModelImporterMaterialSearch.Local; mi.materialName = ModelImporterMaterialName.BasedOnTextureName; mi.normalCalculationMode = ModelImporterNormalCalculationMode.Unweighted_Legacy; mi.importNormals = ModelImporterNormals.Import; mi.importMaterials = true; mi.importAnimation = false; mi.importBlendShapes = false; #if UNITY_2018 mi.materialLocation = ModelImporterMaterialLocation.InPrefab; EditorApplication.delayCall += () => { Material mat = null; Object[] things = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetImporter.assetPath); foreach (Object o in things) { if (o is Material) { mat = o as Material; mat.shader = TheShader; } } if (mat) { EditorApplication.delayCall += () => { mat.mainTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(Util.FixedRelativePath(texturePath)); }; } }; #endif } }
private static void RefreshSelection() { VoxNum = 0; QbNum = 0; FolderNum = 0; JsonNum = 0; // Fix Selection var fixedSelection = new List <KeyValuePair <Object, string> >(); for (int i = 0; i < Selection.objects.Length; i++) { fixedSelection.Add(new KeyValuePair <Object, string>( Selection.objects[i], AssetDatabase.GetAssetPath(Selection.objects[i])) ); } for (int i = 0; i < fixedSelection.Count; i++) { if (!fixedSelection[i].Key) { continue; } var pathI = fixedSelection[i].Value; for (int j = 0; j < fixedSelection.Count; j++) { if (i == j || !fixedSelection[j].Key) { continue; } var pathJ = fixedSelection[j].Value; if (Util.IsChildPathCompair(pathJ, pathI)) { fixedSelection[j] = new KeyValuePair <Object, string>(null, null); } } } // Get Task Map TaskMap.Clear(); for (int i = 0; i < fixedSelection.Count; i++) { if (!fixedSelection[i].Key) { continue; } var obj = fixedSelection[i].Key; var path = fixedSelection[i].Value; path = Util.FixPath(path); var ex = Util.GetExtension(path); if (AssetDatabase.IsValidFolder(path)) { FolderNum++; var files = Util.GetFilesIn(path, "*.vox", "*.qb", "*.json"); for (int j = 0; j < files.Length; j++) { var filePath = Util.FixedRelativePath(files[j].FullName); var fileEx = Util.GetExtension(filePath); if (fileEx == ".vox" || fileEx == ".qb" || fileEx == ".json") { var fileObj = AssetDatabase.LoadAssetAtPath <Object>(filePath); if (fileObj && !TaskMap.ContainsKey(fileObj)) { TaskMap.Add(fileObj, new PathData() { Path = filePath, Extension = fileEx, Root = Util.FixPath(filePath.Substring( path.Length, filePath.Length - path.Length - Util.GetNameWithExtension(filePath).Length )), }); if (fileEx == ".vox") { VoxNum++; FixVoxIcon(fileObj); } else if (fileEx == ".qb") { QbNum++; FixQbIcon(fileObj); } else if (fileEx == ".json") { JsonNum++; FixJsonIcon(fileObj); } } } } } else if (ex == ".vox" || ex == ".qb" || ex == ".json") { if (!TaskMap.ContainsKey(obj)) { TaskMap.Add(obj, new PathData() { Path = path, Extension = ex, Root = "", }); if (ex == ".vox") { VoxNum++; FixVoxIcon(obj); } else if (ex == ".qb") { QbNum++; FixQbIcon(obj); } else if (ex == ".json") { JsonNum++; FixJsonIcon(obj); } } } } ObjNum = Selection.objects.Length; }