private void OnGUI_CreateAsset() { PopupItem("程序集", ref m_AssemblyName, m_AssemblyNames, ref m_AssemblyNameFilter); EditorGUILayout.Space(); if (string.IsNullOrEmpty(m_AssemblyName)) { return; } Assembly assembly = Assembly.Load(m_AssemblyName); if (assembly == null) { return; } Type[] types = assembly.GetTypes(); m_ClassNames = new List <string>(); for (int iType = 0; iType < types.Length; iType++) { bool isObjectType = string.IsNullOrEmpty(m_ClassNameBaseTypeFilter); Type tp = types[iType]; while (!isObjectType && tp.BaseType != null) { tp = tp.BaseType; if (tp.FullName == m_ClassNameBaseTypeFilter) { isObjectType = true; } } if (isObjectType) { m_ClassNames.Add(types[iType].FullName); } } if (m_ClassNames.Count < 1) { return; } m_ClassNameBaseTypeFilter.Set(EditorGUILayout.TextField("父类", m_ClassNameBaseTypeFilter)); PopupItem("类", ref m_ClassName, m_ClassNames.ToArray(), ref m_ClassNameFilter); EditorGUILayout.Space(); EditorGUILayout.Space(); if (string.IsNullOrEmpty(m_ClassName)) { return; } EditorGUILayout.BeginHorizontal(); m_AssetDirection.Set(EditorGUILayout.TextField("asset路径", m_AssetDirection)); if (GUILayout.Button("选择", GUILayout.Width(120))) { m_AssetDirection.Set(EditorUtility.OpenFolderPanel("asset路径", m_AssetDirection, "")); } EditorGUILayout.EndHorizontal(); if (string.IsNullOrEmpty(m_AssetDirection)) { return; } if (m_AssetDirection.Get().Contains("Assets")) { m_AssetDirection.Set(m_AssetDirection.Get().Substring(m_AssetDirection.Get().IndexOf("Assets"))); } EditorGUILayout.BeginHorizontal(); m_AssetFile.Set(EditorGUILayout.TextField("asset文件", m_AssetFile)); m_AssetCover.Set(EditorGUILayout.Toggle("覆盖文件", m_AssetCover)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if (!string.IsNullOrEmpty(m_AssetDirection) && !string.IsNullOrEmpty(m_AssetFile) && m_AssetDirection.Get().Substring(0, 6) == "Assets") { bool canCreate = m_AssetCover; string assetFile = m_AssetDirection + "/" + m_AssetFile + ".asset"; if (!canCreate) { canCreate = !File.Exists(Application.dataPath.Remove(Application.dataPath.Length - 6) + assetFile); } if (canCreate && GUILayout.Button("创建")) { ScriptableObject obj = CreateInstance(m_ClassName); AssetDatabase.CreateAsset(obj, assetFile); Selection.activeObject = obj; } } }
void Save_SDF_FontAsset(string filePath) { filePath = filePath.Substring(0, filePath.Length - 6); // Trim file extension from filePath. string dataPath = Application.dataPath; if (filePath.IndexOf(dataPath) == -1) { Debug.LogError("You're saving the font asset in a directory outside of this project folder. This is not supported. Please select a directory under \"" + dataPath + "\""); return; } string relativeAssetPath = filePath.Substring(dataPath.Length - 6); string tex_DirName = Path.GetDirectoryName(relativeAssetPath); string tex_FileName = Path.GetFileNameWithoutExtension(relativeAssetPath); string tex_Path_NoExt = tex_DirName + "/" + tex_FileName; // Check if TextMeshPro font asset already exists. If not, create a new one. Otherwise update the existing one. TextMeshProFont font_asset = AssetDatabase.LoadAssetAtPath(tex_Path_NoExt + ".asset", typeof(TextMeshProFont)) as TextMeshProFont; if (font_asset == null) { //Debug.Log("Creating TextMeshPro font asset!"); font_asset = ScriptableObject.CreateInstance <TextMeshProFont>(); // Create new TextMeshPro Font Asset. AssetDatabase.CreateAsset(font_asset, tex_Path_NoExt + ".asset"); //Set Font Asset Type font_asset.fontAssetType = TextMeshProFont.FontAssetTypes.SDF; if (m_destination_Atlas != null) { m_font_Atlas = m_destination_Atlas; } // If using the C# SDF creation mode, we need the scale down factor. int scaleDownFactor = font_renderMode >= RenderModes.DistanceField16 ? 1 : font_scaledownFactor; // Add FaceInfo to Font Asset FaceInfo face = GetFaceInfo(m_font_faceInfo, scaleDownFactor); font_asset.AddFaceInfo(face); // Add GlyphInfo[] to Font Asset GlyphInfo[] glyphs = GetGlyphInfo(m_font_glyphInfo, scaleDownFactor); font_asset.AddGlyphInfo(glyphs); // Get and Add Kerning Pairs to Font Asset if (includeKerningPairs) { string fontFilePath = AssetDatabase.GetAssetPath(font_TTF); KerningTable kerningTable = GetKerningTable(fontFilePath, (int)face.PointSize); font_asset.AddKerningInfo(kerningTable); } // Add Line Breaking Rules //LineBreakingTable lineBreakingTable = new LineBreakingTable(); // // Add Font Atlas as Sub-Asset font_asset.atlas = m_font_Atlas; m_font_Atlas.name = tex_FileName + " Atlas"; m_font_Atlas.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(m_font_Atlas, font_asset); // Create new Material and Add it as Sub-Asset Shader default_Shader = Shader.Find("TMPro/Distance Field"); Material tmp_material = new Material(default_Shader); //tmp_material.shaderKeywords = new string[] { "BEVEL_OFF", "GLOW_OFF", "UNDERLAY_OFF" }; tmp_material.name = tex_FileName + " Material"; tmp_material.SetTexture(ShaderUtilities.ID_MainTex, m_font_Atlas); tmp_material.SetFloat(ShaderUtilities.ID_TextureWidth, m_font_Atlas.width); tmp_material.SetFloat(ShaderUtilities.ID_TextureHeight, m_font_Atlas.height); tmp_material.SetFloat(ShaderUtilities.ID_WeightNormal, font_asset.NormalStyle); tmp_material.SetFloat(ShaderUtilities.ID_WeightBold, font_asset.BoldStyle); int spread = font_renderMode >= RenderModes.DistanceField16 ? font_padding + 1 : font_spread; tmp_material.SetFloat(ShaderUtilities.ID_GradientScale, spread); // Spread = Padding for Brute Force SDF. font_asset.material = tmp_material; tmp_material.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(tmp_material, font_asset); } else { // Find all Materials referencing this font atlas. Material[] material_references = TMPro_EditorUtility.FindMaterialReferences(font_asset.material); // Destroy Assets that will be replaced. DestroyImmediate(font_asset.atlas, true); //Set Font Asset Type font_asset.fontAssetType = TextMeshProFont.FontAssetTypes.SDF; int scaleDownFactor = font_renderMode >= RenderModes.DistanceField16 ? 1 : font_scaledownFactor; // Add FaceInfo to Font Asset FaceInfo face = GetFaceInfo(m_font_faceInfo, scaleDownFactor); font_asset.AddFaceInfo(face); // Add GlyphInfo[] to Font Asset GlyphInfo[] glyphs = GetGlyphInfo(m_font_glyphInfo, scaleDownFactor); font_asset.AddGlyphInfo(glyphs); // Get and Add Kerning Pairs to Font Asset if (includeKerningPairs) { string fontFilePath = AssetDatabase.GetAssetPath(font_TTF); KerningTable kerningTable = GetKerningTable(fontFilePath, (int)face.PointSize); font_asset.AddKerningInfo(kerningTable); } // Add Font Atlas as Sub-Asset font_asset.atlas = m_font_Atlas; m_font_Atlas.name = tex_FileName + " Atlas"; m_font_Atlas.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(m_font_Atlas, font_asset); // Update the Texture reference on the Material for (int i = 0; i < material_references.Length; i++) { material_references[i].SetTexture(ShaderUtilities.ID_MainTex, font_asset.atlas); material_references[i].SetFloat(ShaderUtilities.ID_TextureWidth, m_font_Atlas.width); material_references[i].SetFloat(ShaderUtilities.ID_TextureHeight, m_font_Atlas.height); material_references[i].SetFloat(ShaderUtilities.ID_WeightNormal, font_asset.NormalStyle); material_references[i].SetFloat(ShaderUtilities.ID_WeightBold, font_asset.BoldStyle); int spread = font_renderMode >= RenderModes.DistanceField16 ? font_padding + 1 : font_spread; material_references[i].SetFloat(ShaderUtilities.ID_GradientScale, spread); // Spread = Padding for Brute Force SDF. } } m_font_Atlas = null; // Saving File for Debug //var pngData = destination_Atlas.EncodeToPNG(); //File.WriteAllBytes("Assets/Textures/Debug Distance Field.png", pngData); //font_asset.fontCreationSettings = SaveFontCreationSettings(); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(font_asset)); // Re-import font asset to get the new updated version. font_asset.ReadFontDefinition(); AssetDatabase.Refresh(); // NEED TO GENERATE AN EVENT TO FORCE A REDRAW OF ANY TEXTMESHPRO INSTANCES THAT MIGHT BE USING THIS FONT ASSET TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, font_asset); }
public MotionData Create(string path, string currentDirectory) { Name = path.Substring(path.LastIndexOf("/") + 1); if (AssetDatabase.LoadAssetAtPath(currentDirectory + Name + ".asset", typeof(MotionData)) == null) { AssetDatabase.CreateAsset(this, currentDirectory + Name + ".asset"); } else { int i = 1; while (AssetDatabase.LoadAssetAtPath(currentDirectory + Name + Name + " (" + i + ").asset", typeof(MotionData)) != null) { i += 1; } AssetDatabase.CreateAsset(this, currentDirectory + Name + Name + " (" + i + ").asset"); } string[] lines = File.ReadAllLines(path); char[] whitespace = new char[] { ' ' }; int index = 0; //Read BVH Source = new BVHData(); string name = string.Empty; string parent = string.Empty; Vector3 offset = Vector3.zero; int[] channels = null; for (index = 0; index < lines.Length; index++) { if (lines[index] == "MOTION") { break; } string[] entries = lines[index].Split(whitespace); for (int entry = 0; entry < entries.Length; entry++) { if (entries[entry].Contains("ROOT")) { parent = "None"; name = entries[entry + 1]; break; } else if (entries[entry].Contains("JOINT")) { parent = name; name = entries[entry + 1]; break; } else if (entries[entry].Contains("End")) { parent = name; name = name + entries[entry + 1]; string[] subEntries = lines[index + 2].Split(whitespace); for (int subEntry = 0; subEntry < subEntries.Length; subEntry++) { if (subEntries[subEntry].Contains("OFFSET")) { offset.x = Utility.ReadFloat(subEntries[subEntry + 1]); offset.y = Utility.ReadFloat(subEntries[subEntry + 2]); offset.z = Utility.ReadFloat(subEntries[subEntry + 3]); break; } } Source.AddBone(name, parent, offset, new int[0]); index += 2; break; } else if (entries[entry].Contains("OFFSET")) { offset.x = Utility.ReadFloat(entries[entry + 1]); offset.y = Utility.ReadFloat(entries[entry + 2]); offset.z = Utility.ReadFloat(entries[entry + 3]); break; } else if (entries[entry].Contains("CHANNELS")) { channels = new int[Utility.ReadInt(entries[entry + 1])]; for (int i = 0; i < channels.Length; i++) { if (entries[entry + 2 + i] == "Xposition") { channels[i] = 1; } else if (entries[entry + 2 + i] == "Yposition") { channels[i] = 2; } else if (entries[entry + 2 + i] == "Zposition") { channels[i] = 3; } else if (entries[entry + 2 + i] == "Xrotation") { channels[i] = 4; } else if (entries[entry + 2 + i] == "Yrotation") { channels[i] = 5; } else if (entries[entry + 2 + i] == "Zrotation") { channels[i] = 6; } } Source.AddBone(name, parent, offset, channels); break; } else if (entries[entry].Contains("}")) { name = parent; parent = name == "None" ? "None" : Source.FindBone(name).Parent; break; } } } //Read frame count index += 1; while (lines[index].Length == 0) { index += 1; } ArrayExtensions.Resize(ref Frames, Utility.ReadInt(lines[index].Substring(8))); //Read frame time index += 1; Framerate = Mathf.RoundToInt(1f / Utility.ReadFloat(lines[index].Substring(12))); //Read motions index += 1; for (int i = index; i < lines.Length; i++) { Source.AddMotion(Utility.ReadArray(lines[i])); } //Detect settings DetectHeightMapSensor(); DetectDepthMapSensor(); DetectSymmetry(); DetectCorrections(); //Create frames for (int i = 0; i < GetTotalFrames(); i++) { Frames[i] = new Frame(this, i + 1, (float)i / Framerate); } //Generate ComputePostures(); ComputeStyles(); AddSequence(); //Finish return(this); }
public static void CreateAsset(string path, ImportingAsset importingAsset) { // modify if(importingAsset.CustomData1Count > 0) importingAsset.CustomData1Count = Math.Max(2, importingAsset.CustomData1Count); if(importingAsset.CustomData2Count > 0) importingAsset.CustomData2Count = Math.Max(2, importingAsset.CustomData2Count); // modifiy importing asset to avoid invalid name foreach(var texture in importingAsset.Textures) { if(texture.Name == string.Empty) { texture.Name = texture.UniformName; } // Escape texture.Name = EscapePropertyName(texture.Name); } string assetPath = Path.ChangeExtension(path, ".asset"); var asset = AssetDatabase.LoadAssetAtPath<EffekseerMaterialAsset>(assetPath); if (asset != null) { } string assetDir = assetPath.Substring(0, assetPath.LastIndexOf('/')); bool isNewAsset = false; if (asset == null) { asset = CreateInstance<EffekseerMaterialAsset>(); isNewAsset = true; } if(importingAsset.IsCacheFile) { asset.cachedMaterialBuffers = importingAsset.Data; } else { asset.materialBuffers = importingAsset.Data; asset.uniforms = importingAsset.Uniforms.ToArray(); asset.textures = importingAsset.Textures.ToArray(); asset.CustomData1Count = importingAsset.CustomData1Count; asset.CustomData2Count = importingAsset.CustomData2Count; asset.HasRefraction = importingAsset.HasRefraction; asset.shader = CreateShader(Path.ChangeExtension(path, ".shader"), importingAsset); } if(isNewAsset) { AssetDatabase.CreateAsset(asset, assetPath); } else { EditorUtility.SetDirty(asset); } AssetDatabase.Refresh(); }
public static void CreateInputMapAsset() { var actionMap = ScriptableObject.CreateInstance <ActionMap>(); actionMap.controlSchemes = new List <ControlScheme> { new ControlScheme("KeyboardMouse", actionMap), new ControlScheme("Gamepad", actionMap), new ControlScheme("VirtualJoystick", actionMap) }; var gamepad = new Gamepad(); var virtualJoystick = new VirtualJoystick(); CreateControl(actionMap, "MoveX", InputControlType.RelativeAxis, CreateButtonAxisBinding(typeof(Keyboard), (int)KeyCode.A, (int)KeyCode.D, (int)KeyCode.LeftArrow, (int)KeyCode.RightArrow), CreateBinding(typeof(Gamepad), gamepad.leftStickX.index), CreateBinding(typeof(VirtualJoystick), virtualJoystick.leftStickX.index) ); CreateControl(actionMap, "MoveY", InputControlType.RelativeAxis, CreateButtonAxisBinding(typeof(Keyboard), (int)KeyCode.S, (int)KeyCode.W, (int)KeyCode.DownArrow, (int)KeyCode.UpArrow), CreateBinding(typeof(Gamepad), gamepad.leftStickY.index), CreateBinding(typeof(VirtualJoystick), virtualJoystick.leftStickY.index) ); CreateControlComposite(actionMap, "Move", InputControlType.Vector2, new[] { 0, 1 }); CreateControl(actionMap, "LookX", InputControlType.RelativeAxis, CreateBinding(typeof(Pointer), (int)PointerControl.LockedDeltaX), CreateBinding(typeof(Gamepad), gamepad.rightStickX.index), CreateBinding(typeof(VirtualJoystick), virtualJoystick.rightStickX.index) ); CreateControl(actionMap, "LookY", InputControlType.RelativeAxis, CreateBinding(typeof(Pointer), (int)PointerControl.LockedDeltaY), CreateBinding(typeof(Gamepad), gamepad.rightStickY.index), CreateBinding(typeof(VirtualJoystick), virtualJoystick.rightStickY.index) ); CreateControlComposite(actionMap, "Look", InputControlType.Vector2, new[] { 3, 4 }); CreateControl(actionMap, "Fire", InputControlType.Button, CreateBinding(typeof(Pointer), (int)PointerControl.LeftButton), CreateBinding(typeof(Gamepad), gamepad.rightTrigger.index), CreateBinding(typeof(VirtualJoystick), virtualJoystick.action1.index) ); CreateControl(actionMap, "Menu", InputControlType.Button, CreateBinding(typeof(Keyboard), (int)KeyCode.Space), CreateBinding(typeof(Gamepad), gamepad.start.index), CreateBinding(typeof(VirtualJoystick), virtualJoystick.menu.index) ); CreateControl(actionMap, "LockCursor", InputControlType.Button, CreateBinding(typeof(Pointer), (int)PointerControl.LeftButton) ); CreateControl(actionMap, "UnlockCursor", InputControlType.Button, CreateBinding(typeof(Keyboard), (int)KeyCode.Escape) ); CreateControl(actionMap, "Reconfigure", InputControlType.Button, CreateBinding(typeof(Keyboard), (int)KeyCode.R) ); const string path = "Assets/Demo/Assets/FirstPersonControls.asset"; AssetDatabase.CreateAsset(actionMap, path); }
IEnumerator Simplify(WorkingMesh inputMesh, WorkingMesh outputMesh, float quality) { Renderer renderer = null; UnityCloudJob job = null; string jobName = null; var assembly = typeof(SharedData).Assembly; var cloudJobType = assembly.GetType("Simplygon.Cloud.Yoda.IntegrationClient.CloudJob"); var jobNameField = cloudJobType.GetField("name", BindingFlags.NonPublic | BindingFlags.Instance); MonoBehaviourHelper.ExecuteOnMainThread(() => { var go = EditorUtility.CreateGameObjectWithHideFlags("Temp", HideFlags.HideAndDontSave, typeof(MeshRenderer), typeof(MeshFilter)); var mf = go.GetComponent <MeshFilter>(); var mesh = new Mesh(); inputMesh.ApplyToMesh(mesh); mf.sharedMesh = mesh; renderer = go.GetComponent <MeshRenderer>(); var sharedMaterials = new Material[mesh.subMeshCount]; if (Directory.Exists(materialPath) == false) { Directory.CreateDirectory(materialPath); } //For submesh, we should create material asset. //otherwise, simplygon will be combine uv of submesh. for (int i = 0; i < mesh.subMeshCount; i++) { var material = new Material(Shader.Find("Standard")); material.name = "Material " + i.ToString(); AssetDatabase.CreateAsset(material, materialPath + "/" + material.name); sharedMaterials[i] = material; } renderer.sharedMaterials = sharedMaterials; renderer.enabled = false; EditorWindow.GetWindow <Window>(); // Must be visible for background processing SharedData.Instance.Settings.SetDownloadAssetsAutomatically(true); var lodChainProperty = typeof(SharedData).GetProperty("LODChain"); var lodChainList = lodChainProperty.GetValue(SharedData.Instance, null) as IList; var lodChain = lodChainList[0]; var processNodeType = assembly.GetType("Simplygon.SPL.v80.Node.ProcessNode"); var processorProperty = processNodeType.GetProperty("Processor"); var processor = processorProperty.GetValue(lodChain, null); var reductionProcessorType = assembly.GetType("Simplygon.SPL.v80.Processor.ReductionProcessor"); var reductionSettingsProperty = reductionProcessorType.GetProperty("ReductionSettings"); var reductionSettingsType = assembly.GetType("Simplygon.SPL.v80.Settings.ReductionSettings"); var reductionSettings = reductionSettingsProperty.GetValue(processor, null); var triangleRatioProperty = reductionSettingsType.GetProperty("TriangleRatio"); triangleRatioProperty.SetValue(reductionSettings, quality, null); jobName = Path.GetRandomFileName().Replace(".", string.Empty); var prefabList = PrefabUtilityEx.GetPrefabsForSelection(new List <GameObject>() { go }); var generalManager = SharedData.Instance.GeneralManager; generalManager.CreateJob(jobName, "myPriority", prefabList, () => { foreach (var j in generalManager.JobManager.Jobs) { var name = (string)jobNameField.GetValue(j.CloudJob); if (name == jobName) { job = j; } } }); }); while (job == null) { yield return(null); } while (string.IsNullOrEmpty(job.AssetDirectory)) { yield return(null); } MonoBehaviourHelper.ExecuteOnMainThread(() => { var customDataType = assembly.GetType("Simplygon.Cloud.Yoda.IntegrationClient.CloudJob+CustomData"); var pendingFolderNameProperty = customDataType.GetProperty("UnityPendingLODFolderName"); var jobCustomDataProperty = cloudJobType.GetProperty("JobCustomData"); var jobCustomData = jobCustomDataProperty.GetValue(job.CloudJob, null); var jobFolderName = pendingFolderNameProperty.GetValue(jobCustomData, null) as string; var lodAssetDir = lodPath + job.AssetDirectory; var mesh = AssetDatabase.LoadAssetAtPath <Mesh>(string.Format("{0}/{1}_LOD1.prefab", lodAssetDir, jobName)); mesh.ApplyToWorkingMesh(outputMesh); //job.CloudJob.StateHandler.RequestJobDeletion(); AssetDatabaseEx.DeletePendingLODFolder(jobFolderName); AssetDatabase.DeleteAsset(lodAssetDir); AssetDatabase.DeleteAsset(materialPath); UnityObject.DestroyImmediate(renderer.gameObject); }); }
public static async void OnImportGltfAsset(AssetImportContext context) { var importedObject = await GltfUtility.ImportGltfObjectFromPathAsync(context.assetPath); if (importedObject == null || importedObject.GameObjectReference == null) { Debug.LogError("Failed to import glTF object"); return; } var gltfAsset = (GltfAsset)ScriptableObject.CreateInstance(typeof(GltfAsset)); gltfAsset.GltfObject = importedObject; gltfAsset.name = $"{gltfAsset.GltfObject.Name}{Path.GetExtension(context.assetPath)}"; gltfAsset.Model = importedObject.GameObjectReference; context.AddObjectToAsset("main", gltfAsset.Model); context.SetMainObject(importedObject.GameObjectReference); context.AddObjectToAsset("glTF data", gltfAsset); bool reImport = false; for (var i = 0; i < gltfAsset.GltfObject.textures?.Length; i++) { GltfTexture gltfTexture = gltfAsset.GltfObject.textures[i]; if (gltfTexture == null) { continue; } var path = AssetDatabase.GetAssetPath(gltfTexture.Texture); if (string.IsNullOrWhiteSpace(path)) { var textureName = gltfTexture.name; if (string.IsNullOrWhiteSpace(textureName)) { textureName = $"Texture_{i}"; gltfTexture.Texture.name = textureName; } context.AddObjectToAsset(textureName, gltfTexture.Texture); } else { if (!gltfTexture.Texture.isReadable) { var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; if (textureImporter != null) { textureImporter.isReadable = true; textureImporter.SetPlatformTextureSettings(new TextureImporterPlatformSettings { format = TextureImporterFormat.RGBA32 }); textureImporter.SaveAndReimport(); reImport = true; } } } } if (reImport) { var importer = AssetImporter.GetAtPath(context.assetPath); importer.SaveAndReimport(); return; } for (var i = 0; i < gltfAsset.GltfObject.meshes?.Length; i++) { GltfMesh gltfMesh = gltfAsset.GltfObject.meshes[i]; string meshName = string.IsNullOrWhiteSpace(gltfMesh.name) ? $"Mesh_{i}" : gltfMesh.name; gltfMesh.Mesh.name = meshName; context.AddObjectToAsset($"{meshName}", gltfMesh.Mesh); } if (gltfAsset.GltfObject.materials != null) { foreach (GltfMaterial gltfMaterial in gltfAsset.GltfObject.materials) { if (context.assetPath.EndsWith(".glb")) { context.AddObjectToAsset(gltfMaterial.name, gltfMaterial.Material); } else { var relativePath = Path.GetFullPath(Path.GetDirectoryName(context.assetPath)).Replace(Path.GetFullPath(Application.dataPath), "Assets"); relativePath = Path.Combine(relativePath, $"{gltfMaterial.name}.mat"); AssetDatabase.CreateAsset(gltfMaterial.Material, relativePath); gltfMaterial.Material = AssetDatabase.LoadAssetAtPath <Material>(relativePath); } } } }
protected void OnGUI() { if (!SteamAPI.IsSteamRunning()) { EditorGUILayout.HelpBox("Steam is not running. Please start Steam to continue.", MessageType.Error); } else if (ModConfigs.Instance == null || string.IsNullOrEmpty(ModConfigs.ID)) { EditorGUILayout.HelpBox("You must configure your ModConfig using \"Keep Talking Mod Kit -> Configure Mod\".", MessageType.Error); } else if (!isInitialized) { EditorGUILayout.HelpBox("You must log in to Steam to continue.", MessageType.Error); } else { if (currentWorkshopItem == null) { string workshopItemAssetPath = "Assets/Editor/Resources/"; currentWorkshopItem = ModConfigs.WorkshopConfig; if (currentWorkshopItem == null) { currentWorkshopItem = ScriptableObject.CreateInstance <WorkshopItem>(); if (ModConfigs.Instance != null) { currentWorkshopItem.Title = ModConfigs.Title; } ModConfigs.WorkshopConfig = currentWorkshopItem; AssetDatabase.CreateAsset(currentWorkshopItem, workshopItemAssetPath + ModConfigs.ID + "WorshopItem.asset"); } if (workshopItemEditor != null && workshopItemEditor.target != currentWorkshopItem) { DestroyImmediate(workshopItemEditor); workshopItemEditor = null; } if (workshopItemEditor == null) { workshopItemEditor = (WorkshopItemEditor)Editor.CreateEditor(currentWorkshopItem, typeof(WorkshopItemEditor)); } } workshopItemEditor.OnInspectorGUI(); //Publishing Tools EditorGUILayout.Separator(); Color oldBGColor = GUI.backgroundColor; GUI.backgroundColor = new Color(0.1f, 0.1f, 0.5f, 0.7f); EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUI.backgroundColor = oldBGColor; EditorGUILayout.LabelField("Publishing Tools", EditorStyles.largeLabel); EditorGUILayout.Separator(); EditorGUILayout.LabelField("User:"******"Content Folder:", GetContentPath()); DirectoryInfo dir = new DirectoryInfo(GetContentPath()); if (dir.Exists) { FileInfo[] files = dir.GetFiles("*.*", SearchOption.AllDirectories); long totalSize = 0; foreach (var file in files) { totalSize += file.Length; } EditorGUILayout.LabelField("File Count:", files.Length.ToString()); EditorGUILayout.LabelField("Total Size:", FormatFileSize(totalSize)); } else { EditorGUILayout.HelpBox("Content folder not found", MessageType.Error); } string[] tags = GetTags(); if (tags == null) { EditorGUILayout.LabelField("Tags [0]: (none set)"); } else { EditorGUILayout.LabelField(string.Format("Tags [{0}]: {1}", tags == null ? "0" : tags.Length.ToString(), string.Join(", ", tags))); } //Change Notes EditorGUILayout.PrefixLabel("Change Notes:"); changeNotes = EditorGUILayout.TextArea(changeNotes, GUILayout.MinHeight(64)); if (string.IsNullOrEmpty(changeNotes)) { EditorGUILayout.HelpBox("Change notes must be entered before publishing to Workshop", MessageType.Warning); } //Publishing changes if (currentWorkshopItem.WorkshopPublishedFileID == 0) { //Create and Publish GUI.enabled = (onCreateItemCallResultHandler != null && !onCreateItemCallResultHandler.IsActive() && !string.IsNullOrEmpty(changeNotes)); if (GUILayout.Button("Create New Workshop Item and Publish to Steam")) { Debug.Log("CreateItem"); var createItemCall = SteamUGC.CreateItem(KTANE_APP_ID, EWorkshopFileType.k_EWorkshopFileTypeCommunity); onCreateItemCallResultHandler.Set(createItemCall); } GUI.enabled = true; } else { //Publish to Existing Item GUI.enabled = (onItemUpdateCallResultHandler != null && !onItemUpdateCallResultHandler.IsActive() && !string.IsNullOrEmpty(changeNotes)); if (GUILayout.Button("Publish Changes to Steam")) { PublishWorkshopChanges(); } if (!string.IsNullOrEmpty(ugcUpdateStatus)) { EditorGUILayout.LabelField(ugcUpdateStatus); } GUI.enabled = true; } EditorGUILayout.EndVertical(); } }
/// <summary> /// Creates a new <see cref="ResourceMap" /> asset. /// </summary> public static ResourceMap CreateResourceMap() { Directory.CreateDirectory(Path.GetDirectoryName(ResourceMapPath)); AssetDatabase.CreateAsset(ScriptableObject.CreateInstance <ResourceMap>(), ResourceMapPath); return(FindResourceMap()); }
public AnimationClip CreateClip(Object obj, string clipName, int startFrame, int endFrame, float frameRate, float timeBetween, bool pingPong) { //Get the path to the object string path = AssetDatabase.GetAssetPath(obj); //Extract the sprites at the path Object[] sprites = AssetDatabase.LoadAllAssetsAtPath(path); //Determine how many frames and the length of each frame int frameCount = endFrame - startFrame + 1; float frameLength = 1f / timeBetween; //create the new empty animation clip AnimationClip clip = new AnimationClip(); //set the framerate of the clip clip.frameRate = frameRate; //create the new empty curve binding EditorCurveBinding curveBinding = new EditorCurveBinding(); //assign it to change the sprite renderer curveBinding.type = typeof(SpriteRenderer); //assign it to alter the sprite of the sprite renderer curveBinding.propertyName = "m_Sprite"; //Create a container for all the keyframes ObjectReferenceKeyframe[] keyFrames; //Determine how many frames there will be if we are or are not pingponging if (!pingPong) { keyFrames = new ObjectReferenceKeyframe[frameCount + 1]; } else { keyFrames = new ObjectReferenceKeyframe[frameCount * 2 + 1]; } //track what frame number we are on int frameNumber = 0; //loop from start to end, incrementing frameNumber as we go for (int i = startFrame; i < endFrame + 1; i++, frameNumber++) { //create an empty keyframe ObjectReferenceKeyframe tempKeyFrame = new ObjectReferenceKeyframe(); //Assign i a time to appear in the animation tempKeyFrame.time = frameNumber * frameLength; //assign it a sprite tempKeyFrame.value = sprites[i]; //Place it into the container fro all the keyframes keyFrames[frameNumber] = tempKeyFrame; } if (pingPong) { //create the keyframes starting at the end and going backwards //continue to keep track of the frame number for (int i = endFrame; i >= startFrame; i--, frameNumber++) { ObjectReferenceKeyframe tempkeyframe = new ObjectReferenceKeyframe(); tempkeyframe.time = frameNumber * frameLength; tempkeyframe.value = sprites[i]; keyFrames[frameNumber] = tempkeyframe; } } //Create the last sprite to stop it from switching to the first frame from the last immediately ObjectReferenceKeyframe lastSprite = new ObjectReferenceKeyframe(); lastSprite.time = frameNumber * frameLength; lastSprite.value = sprites[startFrame]; keyFrames[frameNumber] = lastSprite; //assign the name to the clip clip.name = clipName; //apply the curve AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames); //create the clip AssetDatabase.CreateAsset(clip, ("Assets/" + clipName + ".anim")); //return the clip return(clip); }
public override void Action(int instanceId, string pathName, string resourceFile) { //Create asset AssetDatabase.CreateAsset(Create(CreateRendererAsset(pathName, RendererType.ForwardRenderer)), pathName); }
//表情动画生成 static void FaceAnimationGenerate() { AnimatorStateMachine stateMachine = productController.layers[1].stateMachine; AnimatorState idle_state = stateMachine.AddState("Idle", new Vector2(0, 300)); Vector2 position = new Vector2(400, 0); SkinnedMeshRenderer face_renderer = null; GameObject obj = AssetDatabase.LoadAssetAtPath <GameObject>(prefab_path); SkinnedMeshRenderer[] renderers = obj.GetComponentsInChildren <SkinnedMeshRenderer>(); foreach (var item in renderers) { if (item.name.Contains("face") || item.name.Contains("Face")) { face_renderer = item; break; } } Mesh sharedMesh = face_renderer.sharedMesh; string idle_path = AnimatorClipPrefix + characterName + "/Set" + cur_set + AnimatorClipInfix + characterName + cur_set + "_Poster_Common_Idle.anim"; AnimationClip idle_clip = AssetDatabase.LoadAssetAtPath <AnimationClip>(idle_path); bool is_idle_clip_exist = idle_clip != null; if (!is_idle_clip_exist) { idle_clip = new AnimationClip(); } for (int j = 0; j < sharedMesh.blendShapeCount; j++) { string name = sharedMesh.GetBlendShapeName(j); string propertyName = "blendShape." + name; idle_clip.SetCurve(face_renderer.name, typeof(SkinnedMeshRenderer), propertyName, other_curve); } if (is_idle_clip_exist) { EditorUtility.SetDirty(idle_clip); } else { AssetDatabase.CreateAsset(idle_clip, idle_path); } idle_state.motion = idle_clip; for (int i = 0; i < expression_list.Length; i++) { string clip_Path = AnimatorClipPrefix + characterName + "/Set" + cur_set + AnimatorClipInfix + characterName + cur_set + "_Poster_" + expression_list[i] + ".anim"; AnimationClip clip = AssetDatabase.LoadAssetAtPath <AnimationClip>(clip_Path); bool is_clip_exist = clip != null; if (!is_clip_exist) { clip = new AnimationClip(); } string expression = "R_" + characterName + cur_set + "_" + expression_list[i]; for (int j = 0; j < sharedMesh.blendShapeCount; j++) { string name = sharedMesh.GetBlendShapeName(j); string propertyName = "blendShape." + name; if (name.Equals(expression)) { clip.SetCurve(face_renderer.name, typeof(SkinnedMeshRenderer), propertyName, target_curve); } else if (Array.IndexOf(mouse_list, name) == -1) { clip.SetCurve(face_renderer.name, typeof(SkinnedMeshRenderer), propertyName, other_curve); } } if (is_clip_exist) { EditorUtility.SetDirty(clip); } else { AssetDatabase.CreateAsset(clip, clip_Path); } position.y = 130 * i; AnimatorState state_1 = stateMachine.AddState(clip.name, position); state_1.motion = clip; AnimatorStateTransition transition_1 = idle_state.AddTransition(state_1); transition_1.AddCondition(AnimatorConditionMode.If, 0, expression_list[i]); AnimatorStateTransition transition_2 = state_1.AddTransition(idle_state); transition_2.AddCondition(AnimatorConditionMode.If, 0, expression_list[i] + "_reverse"); position.y = 130 * i + 60; AnimatorState state_2 = stateMachine.AddState(clip.name + "_reverse", position); state_2.motion = clip; state_2.speed = -1; } EditorUtility.SetDirty(productController); // AssetDatabase.Refresh(); }
private static List <Vector2> offsets; //used for tiling of the textures. //objToCombine should be correctly assembled,meaning has MeshRenderer,filter and shares the same type of shader across materials //combines the number of materials in the mesh renderer, not the submesh count. public static GameObject CombineMaterials(GameObject objToCombine, string shaderUsed, bool usesSkinnedMeshRenderer) { List <string> shaderDefines = ShaderManager.Instance.GetShaderTexturesDefines(shaderUsed); Material[] materialsToCombine = usesSkinnedMeshRenderer ? objToCombine.GetComponent <SkinnedMeshRenderer>().sharedMaterials : objToCombine.GetComponent <MeshRenderer>().sharedMaterials; GetTexturesScalesAndOffsetsForShaderDefine(materialsToCombine, shaderDefines[0]); int objToCombineID = objToCombine.GetInstanceID(); int atlasSize = CalculateAproxAtlasSizeForMaterials(materialsToCombine, shaderUsed); Atlasser atlas = new Atlasser(atlasSize, atlasSize, false /*dont force the atlas to be power of 2 as we are combining a material*/); string atlasName = "Atlas"; // generate atlas for the initial textures int resizeTimes = 1; for (int i = 0; i < texturesToAtlas.Count; i++) { Node resultNode = atlas.Insert(texturesToAtlas[i].width, texturesToAtlas[i].height); string texturePath = AssetDatabase.GetAssetPath(texturesToAtlas[i]).Replace(Path.DirectorySeparatorChar, '-'); if (texturePath == "") //means we have a colored material, lets just peek at the color and get a hash { texturePath = Utils.CalculateMD5Hash(texturesToAtlas[i].GetPixel(0, 0).ToString()).ToString(); } atlasName += texturePath; if (resultNode == null) { int resizedAtlasSize = atlasSize + Mathf.RoundToInt((float)atlasSize * Constants.AtlasResizeFactor * resizeTimes); atlas = new Atlasser(resizedAtlasSize, resizedAtlasSize, false /*dont force the atlas to be power of 2 as we are combining a material*/); atlasName = "Atlas"; i = -1;//at the end of the loop 1 will be added and it will start in 0 resizeTimes++; } } atlasName = "Tex" + Utils.CalculateMD5Hash(atlasName).ToString();//Remove the MD5 for debuging purposes to know where each tex comes from //with the generated atlas, save the textures and load them and add them to the combinedMaterial string pathToCombinedMaterials = CreateFolderForCombinedObjects(); string atlasTexturePath = pathToCombinedMaterials + Path.DirectorySeparatorChar; //create material and fill with the combined to be textures in the material string shaderMaterialName = shaderUsed; if (Utils.IsShaderStandard(shaderMaterialName)) { shaderMaterialName = Utils.ExtractStandardShaderOriginalName(shaderMaterialName); } Material combinedMaterial = new Material(Shader.Find(shaderMaterialName)); string materialPathAndName = atlasTexturePath + "Mat" + objToCombineID + ".mat"; AssetDatabase.CreateAsset(combinedMaterial, materialPathAndName); AssetDatabase.ImportAsset(materialPathAndName); combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(materialPathAndName, typeof(Material)); for (int i = 0; i < shaderDefines.Count; i++) { string scaleOffsetsID = GetTexturesScalesAndOffsetsForShaderDefine(materialsToCombine, shaderDefines[i]); string atlasTexturePathAndName = atlasTexturePath + atlasName + i.ToString() + scaleOffsetsID + ".png"; if (!File.Exists(atlasTexturePathAndName)) { atlas.SaveAtlasToFile(atlasTexturePathAndName, texturesToAtlas, scales, offsets); } AssetDatabase.ImportAsset(atlasTexturePathAndName); Texture2D savedAtlasTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(atlasTexturePathAndName, typeof(Texture2D)); combinedMaterial.SetTexture(shaderDefines[i], savedAtlasTexture); } Mesh masterMesh = usesSkinnedMeshRenderer ? objToCombine.GetComponent <SkinnedMeshRenderer>().sharedMesh : objToCombine.GetComponent <MeshFilter>().sharedMesh; Mesh[] subMeshes = new Mesh[materialsToCombine.Length]; for (int i = 0; i < subMeshes.Length; i++) { //Debug.Log("Number of Meshes: " + subMeshes.Length + " i: " + i); subMeshes[i] = ExtractMesh(masterMesh, i); Vector2[] remappedUVs = subMeshes[i].uv; bool generatedTexture = (materialsToCombine[i].mainTexture == null); for (int j = 0; j < remappedUVs.Length; j++) { remappedUVs[j] = Utils.ReMapUV(remappedUVs[j], atlas.AtlasWidth, atlas.AtlasHeight, atlas.TexturePositions[i], objToCombine.name, generatedTexture); } subMeshes[i].uv = remappedUVs; } GameObject combinedObj = GameObject.Instantiate(objToCombine, objToCombine.transform.position, objToCombine.transform.rotation) as GameObject; if (usesSkinnedMeshRenderer) { combinedObj.GetComponent <SkinnedMeshRenderer>().sharedMaterials = new Material[] { combinedMaterial }; combinedObj.GetComponent <SkinnedMeshRenderer>().sharedMesh = Utils.CombineMeshes(subMeshes); combinedObj.GetComponent <SkinnedMeshRenderer>().sharedMesh.boneWeights = objToCombine.GetComponent <SkinnedMeshRenderer>().sharedMesh.boneWeights; combinedObj.GetComponent <SkinnedMeshRenderer>().sharedMesh.bindposes = objToCombine.GetComponent <SkinnedMeshRenderer>().sharedMesh.bindposes; } else { combinedObj.GetComponent <MeshRenderer>().sharedMaterials = new Material[] { combinedMaterial }; combinedObj.GetComponent <MeshFilter>().sharedMesh = Utils.CombineMeshes(subMeshes); } combinedObj.transform.parent = objToCombine.transform.parent; combinedObj.transform.localScale = objToCombine.transform.localScale; combinedObj.name = objToCombine.name; return(combinedObj); }
public static void SaveRule(BaseRule pRule) { AssetDatabase.CreateAsset(pRule, RuleManager.AssetsSavedPath + pRule.RuleName + ".asset"); AssetDatabase.Refresh(); ResourceFormatWindow.Reload = true; }
public static void Create(Object asset, string path) { #if UNITY_EDITOR AssetDatabase.CreateAsset(asset, path); #endif }
public override void Action(int instanceId, string pathName, string resourceFile) { AssetDatabase.CreateAsset(Create(), pathName); }
void OnGUI() { AssetPreview.SetPreviewTextureCacheSize(256); if (GUILayout.Button("Recreate Icon For Every Item")) { var snapshotCamera = SnapshotCamera.MakeSnapshotCamera(5, "Snapshot Camera"); var guids = AssetDatabase.FindAssets("t:GameObject"); foreach(var guid in guids) { var path = AssetDatabase.GUIDToAssetPath(guid); var obj = AssetDatabase.LoadAssetAtPath<GameObject>(path); var item = obj.GetComponent<Item>(); if(item != null && item.type != Item.ItemType.Rod) { var texture = snapshotCamera.TakePrefabSnapshot(obj, 512, 512); string savePath = mainPath; switch (item.type) { case Item.ItemType.Fish: { savePath += "Fishes/"; } break; case Item.ItemType.Hat: { savePath += "Hats/"; } break; case Item.ItemType.Shoe: { savePath += "Shoes/"; } break; case Item.ItemType.Tshirt: { savePath += "Tshirts/"; } break; case Item.ItemType.Pants: { savePath += "Pants/"; } break; } AssetDatabase.CreateAsset(texture, savePath + item.name + "_iconTexture.asset"); var loadedTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(savePath + item.name + "_iconTexture.asset"); var icon = Sprite.Create(loadedTexture, new Rect(0f, 0f, loadedTexture.width, loadedTexture.height), new Vector2(0.5f, 0.5f)); AssetDatabase.CreateAsset(icon, savePath + item.name + "_icon.asset"); var loadedIcon = AssetDatabase.LoadAssetAtPath<Sprite>(savePath + item.name + "_icon.asset"); item.SetIcon(loadedIcon); } EditorUtility.SetDirty(obj); } AssetDatabase.Refresh(); DestroyImmediate(snapshotCamera); } }
//[MenuItem("Assets/Create/Rendering/Lightweight Pipeline Editor Resources", priority = CoreUtils.assetCreateMenuPriority1)] static void CreateLightweightPipelineEditorResources() { var instance = CreateInstance <LightweightRenderPipelineEditorResources>(); AssetDatabase.CreateAsset(instance, string.Format("Assets/{0}.asset", typeof(LightweightRenderPipelineEditorResources).Name)); }
public override void OnInspectorGUI() { if (GUILayout.Button("Export Mesh")) { var path = EditorUtility.SaveFilePanelInProject("Save New Mesh", target.name + ".asset", "asset", "Save new asset to file"); if (path.Length > 0) { AssetDatabase.CreateAsset(Instantiate(brush.filter.sharedMesh), path); AssetDatabase.Refresh(); } } serializedObject.Update(); if (brush.type == Brush.Type.Box || brush.type == Brush.Type.Slant) { DrawPropertiesExcluding(serializedObject, "complexity", "smooth", "mesh", "stepSeparation", "stepHeight", "addBottomStep"); } else if (brush.type == Brush.Type.Cyllinder) { DrawPropertiesExcluding(serializedObject, "stepSeparation", "stepHeight", "addBottomStep", "mesh"); } else if (brush.type == Brush.Type.BlockStair || brush.type == Brush.Type.SlantStair) { DrawPropertiesExcluding(serializedObject, "complexity", "smooth", "mesh", "stepHeight"); } else if (brush.type == Brush.Type.SeparateStair) { DrawPropertiesExcluding(serializedObject, "complexity", "smooth", "mesh"); } else { DrawPropertiesExcluding(serializedObject, "separateMaterials", "size", "textureWorldScale", "textureLocalScale", "complexity", "smooth", "stepSeparation", "stepHeight", "addBottomStep", "mesh"); } serializedObject.ApplyModifiedProperties(); if (brush.type != Brush.Type.Freeform) { selectedFaces.Clear(); selectedVertices.Clear(); selectedEdges.Clear(); } if (selectedFaces.Count > 0 || selectedVertices.Count > 0 || selectedEdges.Count > 0) { selectedFaces.RemoveWhere(i => i < 0 || i >= brush.mesh.faces.Count); selectedVertices.RemoveWhere(i => i < 0 || i >= brush.mesh.vertices.Count); selectedEdges.RemoveWhere(e => e.t1 < 0 || e.t1 >= brush.mesh.vertices.Count || e.t2 < 0 || e.t2 >= brush.mesh.vertices.Count); HashSet <int> vertices; if (selectedFaces.Count > 0) { vertices = brush.mesh.GetUniqueVertexList(selectedFaces); } else if (selectedVertices.Count > 0) { vertices = selectedVertices; } else { vertices = brush.mesh.GetUniqueVertexList(selectedEdges); } Vector3 vertexCenter = brush.mesh.GetVerticesCenter(vertices); if (selectedFaces.Count > 0) { EditorGUILayout.LabelField("Selected Faces", EditorStyles.boldLabel); } else if (selectedEdges.Count > 0) { EditorGUILayout.LabelField("Selected Edges", EditorStyles.boldLabel); } else { EditorGUILayout.LabelField("Selected Vertices", EditorStyles.boldLabel); } GUILayout.BeginHorizontal(); if (selectedFaces.Count > 0) { GUILayout.BeginVertical(); if (GUILayout.Button("Extrude")) { Extrude(); } if (GUILayout.Button("Delete")) { DeleteFaces(); } GUILayout.EndVertical(); } else if (selectedEdges.Count > 0) { GUILayout.BeginVertical(); if (GUILayout.Button("Delete")) { DeleteEdges(); } if (GUILayout.Button("Create Face")) { CreateFace(); } if (GUILayout.Button("Loop Cut")) { LoopCut(); } GUILayout.EndVertical(); } else if (selectedVertices.Count > 0) { if (GUILayout.Button("Weld")) { Weld(); } } GUILayout.Label("Align: "); GUILayout.BeginHorizontal(); if (selectedFaces.Count > 0 && GUILayout.Button("Normal")) { AlignVertices(vertices, brush.mesh.GetFacesNormal(selectedFaces)); } if (GUILayout.Button("X")) { AlignVertices(vertices, Vector3.right); } if (GUILayout.Button("Y")) { AlignVertices(vertices, Vector3.up); } if (GUILayout.Button("Z")) { AlignVertices(vertices, Vector3.forward); } GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); GUILayout.Space(10); Vector3 newPos = EditorGUILayout.Vector3Field("Center", vertexCenter); if (vertexCenter != newPos) { brush.undone = true; Undo.RecordObject(brush, "Brush Edit"); Vector3 off = newPos - vertexCenter; foreach (int v in vertices) { brush.mesh.vertices[v].position += off; } brush.undone = false; brush.dirty = true; brush.Update(); } GUILayout.Space(10); } if (!brushMode) { EditorGUILayout.LabelField("Brush mode is disabled! (press tab to re-enable)", EditorStyles.boldLabel); } showCommands = EditorGUILayout.Foldout(showCommands, "Keyboard Commands", true); if (showCommands) { GUILayout.Label("Toggle Brush Editor: Tab"); GUILayout.Label("Extrude Faces: G"); GUILayout.Label("Delete Edges/Faces: Delete"); GUILayout.Label("Weld Vertices: Y"); GUILayout.Label("Create Face: B"); GUILayout.Label("Loop Cut: C"); GUILayout.Label("Select: Left Click"); GUILayout.Label("Select Multiple: Ctrl + Click"); GUILayout.Label("Select Edge Loop: Double Click"); } }
/// <summary> /// Draw the UI for this tool. /// </summary> void OnGUI() { if (mLastAtlas != NGUISettings.atlas) { mLastAtlas = NGUISettings.atlas; atlasName = (NGUISettings.atlas != null) ? NGUISettings.atlas.name : "New Atlas"; } bool create = false; bool update = false; bool replace = false; string prefabPath = ""; string matPath = ""; // If we have an atlas to work with, see if we can figure out the path for it and its material if (NGUISettings.atlas != null && NGUISettings.atlas.name == atlasName) { prefabPath = AssetDatabase.GetAssetPath(NGUISettings.atlas.gameObject.GetInstanceID()); if (NGUISettings.atlas.spriteMaterial != null) { matPath = AssetDatabase.GetAssetPath(NGUISettings.atlas.spriteMaterial.GetInstanceID()); } } // Assume default values if needed if (string.IsNullOrEmpty(atlasName)) { atlasName = "New Atlas"; } if (string.IsNullOrEmpty(prefabPath)) { prefabPath = NGUIEditorTools.GetSelectionFolder() + atlasName + ".prefab"; } if (string.IsNullOrEmpty(matPath)) { matPath = NGUIEditorTools.GetSelectionFolder() + atlasName + ".mat"; } // Try to load the prefab GameObject go = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject; if (NGUISettings.atlas == null && go != null) { NGUISettings.atlas = go.GetComponent <UIAtlas>(); } NGUIEditorTools.SetLabelWidth(80f); GUILayout.Space(6f); GUILayout.BeginHorizontal(); if (go == null) { GUI.backgroundColor = Color.green; create = GUILayout.Button("Create", GUILayout.Width(76f)); } else { GUI.backgroundColor = Color.red; create = GUILayout.Button("Replace", GUILayout.Width(76f)); } GUI.backgroundColor = Color.white; atlasName = GUILayout.TextField(atlasName); GUILayout.EndHorizontal(); if (create) { // If the prefab already exists, confirm that we want to overwrite it if (go == null || EditorUtility.DisplayDialog("Are you sure?", "Are you sure you want to replace the contents of the " + atlasName + " atlas with the textures currently selected in the Project View? All other sprites will be deleted.", "Yes", "No")) { replace = true; // Try to load the material Material mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material; // If the material doesn't exist, create it if (mat == null) { Shader shader = Shader.Find(NGUISettings.atlasPMA ? "Unlit/Premultiplied Colored" : "Unlit/Transparent Colored"); mat = new Material(shader); // Save the material AssetDatabase.CreateAsset(mat, matPath); AssetDatabase.Refresh(); // Load the material so it's usable mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material; } if (NGUISettings.atlas == null || NGUISettings.atlas.name != atlasName) { // Create a new prefab for the atlas Object prefab = (go != null) ? go : PrefabUtility.CreateEmptyPrefab(prefabPath); // Create a new game object for the atlas go = new GameObject(atlasName); go.AddComponent <UIAtlas>().spriteMaterial = mat; // Update the prefab PrefabUtility.ReplacePrefab(go, prefab); DestroyImmediate(go); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); // Select the atlas go = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) as GameObject; NGUISettings.atlas = go.GetComponent <UIAtlas>(); } } } ComponentSelector.Draw <UIAtlas>("Select", NGUISettings.atlas, OnSelectAtlas, true); List <Texture> textures = GetSelectedTextures(); if (NGUISettings.atlas != null && NGUISettings.atlas.name == atlasName) { Material mat = NGUISettings.atlas.spriteMaterial; Texture tex = NGUISettings.atlas.texture; // Material information GUILayout.BeginHorizontal(); { if (mat != null) { if (GUILayout.Button("Material", GUILayout.Width(76f))) { Selection.activeObject = mat; } GUILayout.Label(" " + mat.name); } else { GUI.color = Color.grey; GUILayout.Button("Material", GUILayout.Width(76f)); GUI.color = Color.white; GUILayout.Label(" N/A"); } } GUILayout.EndHorizontal(); // Texture atlas information GUILayout.BeginHorizontal(); { if (tex != null) { if (GUILayout.Button("Texture", GUILayout.Width(76f))) { Selection.activeObject = tex; } GUILayout.Label(" " + tex.width + "x" + tex.height); } else { GUI.color = Color.grey; GUILayout.Button("Texture", GUILayout.Width(76f)); GUI.color = Color.white; GUILayout.Label(" N/A"); } } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); NGUISettings.atlasPadding = Mathf.Clamp(EditorGUILayout.IntField("Padding", NGUISettings.atlasPadding, GUILayout.Width(100f)), 0, 8); GUILayout.Label((NGUISettings.atlasPadding == 1 ? "pixel" : "pixels") + " in-between of sprites"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); NGUISettings.atlasTrimming = EditorGUILayout.Toggle("Trim Alpha", NGUISettings.atlasTrimming, GUILayout.Width(100f)); GUILayout.Label("Remove empty space"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); NGUISettings.atlasPMA = EditorGUILayout.Toggle("PMA Shader", NGUISettings.atlasPMA, GUILayout.Width(100f)); GUILayout.Label("Pre-multiply color by alpha"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); NGUISettings.unityPacking = EditorGUILayout.Toggle("Unity Packer", NGUISettings.unityPacking, GUILayout.Width(100f)); GUILayout.Label("if off, use a custom packer"); GUILayout.EndHorizontal(); if (!NGUISettings.unityPacking) { GUILayout.BeginHorizontal(); NGUISettings.forceSquareAtlas = EditorGUILayout.Toggle("Force Square", NGUISettings.forceSquareAtlas, GUILayout.Width(100f)); GUILayout.Label("if on, forces a square atlas texture"); GUILayout.EndHorizontal(); } #if UNITY_IPHONE || UNITY_ANDROID GUILayout.BeginHorizontal(); NGUISettings.allow4096 = EditorGUILayout.Toggle("4096x4096", NGUISettings.allow4096, GUILayout.Width(100f)); GUILayout.Label("if off, limit atlases to 2048x2048"); GUILayout.EndHorizontal(); #endif if (NGUISettings.atlas != null && NGUISettings.atlas.name == atlasName) { if (textures.Count > 0) { GUI.backgroundColor = Color.green; update = GUILayout.Button("Add/Update All"); GUI.backgroundColor = Color.white; } else { if (GUILayout.Button("View Sprites")) { SpriteSelector.ShowSelected(); } EditorGUILayout.HelpBox("You can reveal more options by selecting one or more textures in the Project View window.", MessageType.Info); } } else { EditorGUILayout.HelpBox("You can create a new atlas by selecting one or more textures in the Project View window, then clicking \"Create\".", MessageType.Info); } string selection = null; Dictionary <string, int> spriteList = GetSpriteList(textures); if (spriteList.Count > 0) { NGUIEditorTools.DrawHeader("Sprites", true); { GUILayout.BeginHorizontal(); GUILayout.Space(3f); GUILayout.BeginVertical(); mScroll = GUILayout.BeginScrollView(mScroll); bool delete = false; int index = 0; foreach (KeyValuePair <string, int> iter in spriteList) { ++index; GUILayout.Space(-1f); bool highlight = (UIAtlasInspector.instance != null) && (NGUISettings.selectedSprite == iter.Key); GUI.backgroundColor = highlight ? Color.white : new Color(0.8f, 0.8f, 0.8f); GUILayout.BeginHorizontal("AS TextArea", GUILayout.MinHeight(20f)); GUI.backgroundColor = Color.white; GUILayout.Label(index.ToString(), GUILayout.Width(24f)); if (GUILayout.Button(iter.Key, "OL TextField", GUILayout.Height(20f))) { selection = iter.Key; } if (iter.Value == 2) { GUI.color = Color.green; GUILayout.Label("Add", GUILayout.Width(27f)); GUI.color = Color.white; } else if (iter.Value == 1) { GUI.color = Color.cyan; GUILayout.Label("Update", GUILayout.Width(45f)); GUI.color = Color.white; } else { if (mDelNames.Contains(iter.Key)) { GUI.backgroundColor = Color.red; if (GUILayout.Button("Delete", GUILayout.Width(60f))) { delete = true; } GUI.backgroundColor = Color.green; if (GUILayout.Button("X", GUILayout.Width(22f))) { mDelNames.Remove(iter.Key); delete = false; } GUI.backgroundColor = Color.white; } else { // If we have not yet selected a sprite for deletion, show a small "X" button if (GUILayout.Button("X", GUILayout.Width(22f))) { mDelNames.Add(iter.Key); } } } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.Space(3f); GUILayout.EndHorizontal(); // If this sprite was marked for deletion, remove it from the atlas if (delete) { List <SpriteEntry> sprites = new List <SpriteEntry>(); ExtractSprites(NGUISettings.atlas, sprites); for (int i = sprites.Count; i > 0;) { SpriteEntry ent = sprites[--i]; if (mDelNames.Contains(ent.name)) { sprites.RemoveAt(i); } } UpdateAtlas(NGUISettings.atlas, sprites); mDelNames.Clear(); NGUIEditorTools.RepaintSprites(); } else if (update) { UpdateAtlas(textures, true); } else if (replace) { UpdateAtlas(textures, false); } if (NGUISettings.atlas != null && !string.IsNullOrEmpty(selection)) { NGUIEditorTools.SelectSprite(selection); } else if (update || replace) { NGUIEditorTools.UpgradeTexturesToSprites(NGUISettings.atlas); NGUIEditorTools.RepaintSprites(); } } } // Uncomment this line if you want to be able to force-sort the atlas //if (NGUISettings.atlas != null && GUILayout.Button("Sort Alphabetically")) NGUISettings.atlas.SortAlphabetically(); }
private void GenerateAtlas() { TrueTypeFontImporter fontImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(FontToConvert)) as TrueTypeFontImporter; if (fontImporter == null) { Debug.LogError("Could not import mesh asset! Builtin Unity fonts like Arial don't work unless you put them in the project directory!"); } fontImporter.characterSpacing = 4; fontImporter.characterPadding = 2; fontImporter.SaveAndReimport(); // Hacky method to get the generated font texture so that we can figure out where to put pixels Texture2D fontTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(AssetDatabase.GetAssetPath(FontToConvert)); Dictionary <CharacterInfo, Texture2D> characterGlyphMap = new Dictionary <CharacterInfo, Texture2D>(); CharacterInfo[] characterInfos = FontToConvert.characterInfo; Texture2D newAtlas = new Texture2D(fontTexture.width, fontTexture.height, TextureFormat.ARGB32, false, true); for (int x = 0; x < newAtlas.width; ++x) { for (int y = 0; y < newAtlas.height; ++y) { newAtlas.SetPixel(x, y, Color.black); } } int charCount = 0; foreach (CharacterInfo info in characterInfos) { charCount++; EditorUtility.DisplayProgressBar("Generating MSDF Atlas...", string.Format("Glyph {0}/{1}", charCount, characterInfos.Length), charCount / (float)characterInfos.Length); Texture2D currentGlyphTex = GenerateGlyphTexture(info.index, info.glyphWidth, info.glyphHeight); if (currentGlyphTex == null) { continue; } for (int x = 0; x < currentGlyphTex.width; ++x) { for (int y = 0; y < currentGlyphTex.height; ++y) { float progressX = (x) / (float)(currentGlyphTex.width); float progressY = (y) / (float)(currentGlyphTex.height); float uvProgressX = Mathf.Lerp(info.uvTopLeft.x, info.uvTopRight.x, progressX) * fontTexture.width; float uvProgressY = Mathf.Lerp(info.uvBottomLeft.y, info.uvTopLeft.y, progressY) * fontTexture.height; // flipped iS dEpRiCaTeD uSiNg ThE Uv WiLl bE CoNSiStEnT. It's not consistent in my limited experience. // Maybe I'm doing something wrong, but I don't want to try fighting with Unity trying to fix an issue that may be on their end.. I've wasted enough time on trusting Unity to do things correctly. #pragma warning disable 0618 if (info.flipped) #pragma warning restore 0618 { uvProgressY = Mathf.Lerp(info.uvTopLeft.y, info.uvTopRight.y, progressX) * fontTexture.height; uvProgressX = Mathf.Lerp(info.uvBottomLeft.x, info.uvTopLeft.x, progressY) * fontTexture.width; } int targetX = Mathf.RoundToInt(uvProgressX); int targetY = Mathf.RoundToInt(uvProgressY) - 1; Color glyphCol = currentGlyphTex.GetPixel(x, y); newAtlas.SetPixel(targetX, targetY, glyphCol); } } } newAtlas.Apply(false); if (UseTextureCompression) { EditorUtility.DisplayProgressBar("Generating MSDF Atlas...", "Compressing Atlas...", 1f); EditorUtility.CompressTexture(newAtlas, TextureFormat.BC7, TextureCompressionQuality.Best); } EditorUtility.ClearProgressBar(); string fontPath = AssetDatabase.GetAssetPath(FontToConvert); string savePath = Path.Combine(Path.GetDirectoryName(fontPath), Path.GetFileNameWithoutExtension(fontPath) + "_msdfAtlas.asset"); AssetDatabase.CreateAsset(newAtlas, savePath); EditorGUIUtility.PingObject(newAtlas); }
private void BuildTexture3D() { int sizeX = m_sizes[m_selectedSizeX]; int sizeY = m_sizes[m_selectedSizeY]; Texture3D texture3D = new Texture3D(sizeX, sizeY, m_allTextures.Count, m_selectedFormatEnum, m_mipMaps); texture3D.wrapMode = m_wrapMode; texture3D.filterMode = m_filterMode; texture3D.anisoLevel = m_anisoLevel; //texture3D.Apply( false ); RenderTexture cache = RenderTexture.active; RenderTexture rt = new RenderTexture(sizeX, sizeY, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default); rt.Create(); List <Texture2D> textures = new List <Texture2D>(m_allTextures.Count); for (int i = 0; i < m_allTextures.Count; i++) { // build report int widthChanges = m_allTextures[i].width <sizeX ? -1 : m_allTextures[i].width> sizeX ? 1 : 0; int heightChanges = m_allTextures[i].height <sizeY ? -1 : m_allTextures[i].height> sizeY ? 1 : 0; if ((widthChanges < 0 && heightChanges <= 0) || (widthChanges <= 0 && heightChanges < 0)) { m_message += m_allTextures[i].name + " was upscaled\n"; } else if ((widthChanges > 0 && heightChanges >= 0) || (widthChanges >= 0 && heightChanges > 0)) { m_message += m_allTextures[i].name + " was downscaled\n"; } else if ((widthChanges > 0 && heightChanges < 0) || (widthChanges < 0 && heightChanges > 0)) { m_message += m_allTextures[i].name + " changed dimensions\n"; } // blit image to upscale or downscale the image to any size RenderTexture.active = rt; bool cachedsrgb = GL.sRGBWrite; GL.sRGBWrite = !m_linearMode; Graphics.Blit(m_allTextures[i], rt); GL.sRGBWrite = cachedsrgb; textures.Add(new Texture2D(sizeX, sizeY, TextureFormat.ARGB32, m_mipMaps, m_linearMode)); textures[i].ReadPixels(new Rect(0, 0, sizeX, sizeY), 0, 0, m_mipMaps); RenderTexture.active = null; bool isCompressed = UncompressedFormats.FindIndex(x => x.Equals(m_selectedFormatEnum)) < 0; if (isCompressed) { EditorUtility.CompressTexture(textures[i], m_selectedFormatEnum, m_quality); // t2d.Apply( false ); } textures[i].Apply(false); } rt.Release(); RenderTexture.active = cache; if (m_message.Length > 0) { m_message = m_message.Substring(0, m_message.Length - 1); } int sizeZ = textures.Count; Color[] colors = new Color[sizeX * sizeY * sizeZ]; int idx = 0; for (int z = 0; z < sizeZ; z++) { for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX; x++, idx++) { colors[idx] = textures[z].GetPixel(x, y); } } } texture3D.SetPixels(colors); texture3D.Apply(); string path = m_folderPath + m_fileName + ".asset"; Texture3D outfile = AssetDatabase.LoadMainAssetAtPath(path) as Texture3D; if (outfile != null) { EditorUtility.CopySerialized(texture3D, outfile); AssetDatabase.SaveAssets(); EditorGUIUtility.PingObject(outfile); m_lastSaved = outfile; } else { AssetDatabase.CreateAsset(texture3D, path); EditorGUIUtility.PingObject(texture3D); m_lastSaved = texture3D; } }
static void CreateFontAsset() { var instance = CreateInstance <CFXR_ParticleTextFontAsset>(); AssetDatabase.CreateAsset(instance, "Assets/Font.asset"); }
private void BuildArray() { int sizeX = m_sizes[m_selectedSizeX]; int sizeY = m_sizes[m_selectedSizeY]; Texture2DArray textureArray = new Texture2DArray(sizeX, sizeY, m_allTextures.Count, m_selectedFormatEnum, m_mipMaps, m_linearMode); textureArray.wrapMode = m_wrapMode; textureArray.filterMode = m_filterMode; textureArray.anisoLevel = m_anisoLevel; textureArray.Apply(false); RenderTexture cache = RenderTexture.active; RenderTexture rt = new RenderTexture(sizeX, sizeY, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default); rt.Create(); for (int i = 0; i < m_allTextures.Count; i++) { // build report int widthChanges = m_allTextures[i].width <sizeX ? -1 : m_allTextures[i].width> sizeX ? 1 : 0; int heightChanges = m_allTextures[i].height <sizeY ? -1 : m_allTextures[i].height> sizeY ? 1 : 0; if ((widthChanges < 0 && heightChanges <= 0) || (widthChanges <= 0 && heightChanges < 0)) { m_message += m_allTextures[i].name + " was upscaled\n"; } else if ((widthChanges > 0 && heightChanges >= 0) || (widthChanges >= 0 && heightChanges > 0)) { m_message += m_allTextures[i].name + " was downscaled\n"; } else if ((widthChanges > 0 && heightChanges < 0) || (widthChanges < 0 && heightChanges > 0)) { m_message += m_allTextures[i].name + " changed dimensions\n"; } // blit image to upscale or downscale the image to any size RenderTexture.active = rt; bool cachedsrgb = GL.sRGBWrite; GL.sRGBWrite = !m_linearMode; Graphics.Blit(m_allTextures[i], rt); GL.sRGBWrite = cachedsrgb; Texture2D t2d = new Texture2D(sizeX, sizeY, m_selectedFormatEnum, m_mipMaps, m_linearMode); t2d.ReadPixels(new Rect(0, 0, sizeX, sizeY), 0, 0, m_mipMaps); RenderTexture.active = null; bool isCompressed = UncompressedFormats.FindIndex(x => x.Equals(m_selectedFormatEnum)) < 0; if (isCompressed) { EditorUtility.CompressTexture(t2d, m_selectedFormatEnum, m_quality); t2d.Apply(false); } if (m_mipMaps) { int maxSize = Mathf.Max(sizeX, sizeY); for (int mip = 0; mip < MipCount[maxSize]; mip++) { CopyToArray(ref t2d, ref textureArray, i, mip, isCompressed); } } else { CopyToArray(ref t2d, ref textureArray, i, 0, isCompressed); } } rt.Release(); RenderTexture.active = cache; if (m_message.Length > 0) { m_message = m_message.Substring(0, m_message.Length - 1); } string path = m_folderPath + m_fileName + ".asset"; Texture2DArray outfile = AssetDatabase.LoadMainAssetAtPath(path) as Texture2DArray; if (outfile != null) { EditorUtility.CopySerialized(textureArray, outfile); AssetDatabase.SaveAssets(); EditorGUIUtility.PingObject(outfile); m_lastSaved = outfile; } else { AssetDatabase.CreateAsset(textureArray, path); EditorGUIUtility.PingObject(textureArray); m_lastSaved = textureArray; } }
void Save_Normal_FontAsset(string filePath) { filePath = filePath.Substring(0, filePath.Length - 6); // Trim file extension from filePath. string dataPath = Application.dataPath; if (filePath.IndexOf(dataPath) == -1) { Debug.LogError("You're saving the font asset in a directory outside of this project folder. This is not supported. Please select a directory under \"" + dataPath + "\""); return; } string relativeAssetPath = filePath.Substring(dataPath.Length - 6); string tex_DirName = Path.GetDirectoryName(relativeAssetPath); string tex_FileName = Path.GetFileNameWithoutExtension(relativeAssetPath); string tex_Path_NoExt = tex_DirName + "/" + tex_FileName; // Check if TextMeshPro font asset already exists. If not, create a new one. Otherwise update the existing one. TextMeshProFont font_asset = AssetDatabase.LoadAssetAtPath(tex_Path_NoExt + ".asset", typeof(TextMeshProFont)) as TextMeshProFont; if (font_asset == null) { //Debug.Log("Creating TextMeshPro font asset!"); font_asset = ScriptableObject.CreateInstance <TextMeshProFont>(); // Create new TextMeshPro Font Asset. AssetDatabase.CreateAsset(font_asset, tex_Path_NoExt + ".asset"); //Set Font Asset Type font_asset.fontAssetType = TextMeshProFont.FontAssetTypes.Bitmap; // Add FaceInfo to Font Asset FaceInfo face = GetFaceInfo(m_font_faceInfo, 1); font_asset.AddFaceInfo(face); // Add GlyphInfo[] to Font Asset GlyphInfo[] glyphs = GetGlyphInfo(m_font_glyphInfo, 1); font_asset.AddGlyphInfo(glyphs); // Get and Add Kerning Pairs to Font Asset if (includeKerningPairs) { string fontFilePath = AssetDatabase.GetAssetPath(font_TTF); KerningTable kerningTable = GetKerningTable(fontFilePath, (int)face.PointSize); font_asset.AddKerningInfo(kerningTable); } // Add Font Atlas as Sub-Asset font_asset.atlas = m_font_Atlas; m_font_Atlas.name = tex_FileName + " Atlas"; m_font_Atlas.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(m_font_Atlas, font_asset); // Create new Material and Add it as Sub-Asset Shader default_Shader = Shader.Find("TMPro/Bitmap"); Material tmp_material = new Material(default_Shader); tmp_material.name = tex_FileName + " Material"; tmp_material.SetTexture(ShaderUtilities.ID_MainTex, m_font_Atlas); font_asset.material = tmp_material; tmp_material.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(tmp_material, font_asset); } else { // Find all Materials referencing this font atlas. Material[] material_references = TMPro_EditorUtility.FindMaterialReferences(font_asset.material); // Destroy Assets that will be replaced. DestroyImmediate(font_asset.atlas, true); //Set Font Asset Type font_asset.fontAssetType = TextMeshProFont.FontAssetTypes.Bitmap; // Add FaceInfo to Font Asset FaceInfo face = GetFaceInfo(m_font_faceInfo, 1); font_asset.AddFaceInfo(face); // Add GlyphInfo[] to Font Asset GlyphInfo[] glyphs = GetGlyphInfo(m_font_glyphInfo, 1); font_asset.AddGlyphInfo(glyphs); // Get and Add Kerning Pairs to Font Asset if (includeKerningPairs) { string fontFilePath = AssetDatabase.GetAssetPath(font_TTF); KerningTable kerningTable = GetKerningTable(fontFilePath, (int)face.PointSize); font_asset.AddKerningInfo(kerningTable); } // Add Font Atlas as Sub-Asset font_asset.atlas = m_font_Atlas; m_font_Atlas.name = tex_FileName + " Atlas"; m_font_Atlas.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(m_font_Atlas, font_asset); // Update the Texture reference on the Material for (int i = 0; i < material_references.Length; i++) { material_references[i].SetTexture(ShaderUtilities.ID_MainTex, font_asset.atlas); } } m_font_Atlas = null; AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(font_asset)); // Re-import font asset to get the new updated version. //EditorUtility.SetDirty(font_asset); font_asset.ReadFontDefinition(); AssetDatabase.Refresh(); // NEED TO GENERATE AN EVENT TO FORCE A REDRAW OF ANY TEXTMESHPRO INSTANCES THAT MIGHT BE USING THIS FONT ASSET TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, font_asset); }
void CombineNode(MeshRenderer[] renderers, Int32 x, Int32 z) { var bounds = CalculateBounds(x, z); var groups = new Dictionary <MaterialsDescriptor, List <MeshRenderer> >(); for (int i = 0; i < renderers.Length; ++i) { if (bounds.Contains(renderers[i].transform.position)) { var descriptor = new MaterialsDescriptor(renderers[i]); var group = default(List <MeshRenderer>); if (groups.TryGetValue(descriptor, out group) == false) { groups.Add(descriptor, group = new List <MeshRenderer>()); } group.Add(renderers[i]); } } if (groups.Count > 0) { Debug.LogFormat("[MeshCombiner] Found {0} material groups in node ({1}, {2})", groups.Count, x, z); var node_go = new GameObject(string.Format("[MeshCombiner]_Node_{0}_{1}", x, z)); node_go.transform.position = bounds.center; node_go.transform.rotation = Quaternion.identity; node_go.transform.localScale = Vector3.one; node_go.isStatic = true; var groups_array = groups.ToArray(); for (int i = 0; i < groups_array.Length; ++i) { var desc = groups_array[i].Key; var group = groups_array[i].Value; if (group.Count > 0) { Debug.LogFormat("[MeshCombiner] Generating mesh for material group {0} in node ({1}, {2}) (mesh count: {3})", i, x, z, group.Count); var group_go = new GameObject(string.Format("Group_{0}", i)); group_go.transform.parent = node_go.transform; group_go.transform.rotation = Quaternion.identity; group_go.transform.localScale = Vector3.one; group_go.transform.localPosition = Vector3.zero; group_go.isStatic = true; // generate all sub mesh combines var group_sm_combine = Utils.InitArray(desc.Ids.Length, _ => new List <CombineInstance>()); // fore each renderer in the group for (int k = 0; k < group.Count; ++k) { var mf = group[k].GetComponent <MeshFilter>(); // generate a combine instance for each submesh of the mesh it's rendering for (int n = 0; n < desc.Ids.Length; ++n) { var mi = new CombineInstance(); // assign mesh mi.mesh = mf.sharedMesh; // grab submesh index mi.subMeshIndex = n; // use only l2w transform here mi.transform = mf.transform.localToWorldMatrix; group_sm_combine[n].Add(mi); } } // generate all sub-meshes (intermediate step) var group_sm = new Mesh[group_sm_combine.Length]; for (int k = 0; k < group_sm.Length; ++k) { group_sm[k] = new Mesh(); group_sm[k].CombineMeshes(group_sm_combine[k].ToArray(), true, true); } // generate main mesh var group_m_combine = new CombineInstance[group_sm.Length]; for (int k = 0; k < group_sm.Length; ++k) { group_m_combine[k] = new CombineInstance(); group_m_combine[k].mesh = group_sm[k]; group_m_combine[k].subMeshIndex = 0; group_m_combine[k].transform = group_go.transform.worldToLocalMatrix; } var group_m = new Mesh(); group_m.name = node_go.name + "_" + group_go.name; group_m.CombineMeshes(group_m_combine, false, true); // add filter + renderer var group_mf = group_go.AddComponent <MeshFilter>(); var group_mr = group_go.AddComponent <MeshRenderer>(); // setup asset paths var scene_path = Path.GetDirectoryName(SceneManager.GetActiveScene().path); var meshes_folder = SceneManager.GetActiveScene().name + "_Meshes"; var meshes_path = scene_path + "/" + meshes_folder; var asset_path = meshes_path + "/" + group_m.name + ".asset"; // make sure folder exists if (AssetDatabase.IsValidFolder(meshes_path) == false) { AssetDatabase.CreateFolder(scene_path, meshes_folder); } // generate UV2s Unwrapping.GenerateSecondaryUVSet(group_m); // create asset AssetDatabase.CreateAsset(group_m, asset_path); // store on mesh group_mf.sharedMesh = AssetDatabase.LoadAssetAtPath <Mesh>(asset_path); group_mr.sharedMaterials = Utils.Map(desc.Ids, k => EditorUtility.InstanceIDToObject(k)).OfType <Material>().ToArray(); } } MeshCombinerNode node; node = node_go.AddComponent <MeshCombinerNode>(); node.Bounds = new Bounds(node_go.transform.position, new Vector3(1, 1, 1)); foreach (var mf in node.GetComponentsInChildren <MeshFilter>()) { var vs = mf.sharedMesh.vertices; for (int i = 0; i < vs.Length; ++i) { node.Bounds.Encapsulate(node.transform.TransformPoint(vs[i])); } } node.Bounds.Expand(NodeExpand); Vector3 center; center = node.Bounds.center; center.y = node.Bounds.size.y * 0.5f; node.Bounds.center = center; Nodes.Add(node); node_go.transform.parent = transform; } }
static void Combine() { GameObject obj = Selection.activeGameObject; if (obj.GetComponent <MeshRenderer>() == null) { obj.AddComponent <MeshRenderer>(); } if (obj.GetComponent <MeshFilter>() == null) { obj.AddComponent <MeshFilter>(); } List <Material> material = new List <Material>(); Matrix4x4 matrix = obj.transform.worldToLocalMatrix; MeshFilter[] filters = obj.GetComponentsInChildren <MeshFilter>(); int filterLength = filters.Length; CombineInstance[] combine = new CombineInstance[filterLength]; for (int i = 0; i < filterLength; i++) { MeshFilter filter = filters[i]; MeshRenderer render = filter.GetComponent <MeshRenderer>(); if (render == null) { continue; } if (render.sharedMaterial != null && !material.Contains(render.sharedMaterial)) { material.Add(render.sharedMaterial); } combine[i].mesh = filter.sharedMesh; //对坐标系施加变换的方法是 当前对象和子对象在世界空间中的矩阵 左乘 当前对象从世界空间转换为本地空间的变换矩阵 //得到当前对象和子对象在本地空间的矩阵。 combine[i].transform = matrix * filter.transform.localToWorldMatrix; render.enabled = false; } MeshFilter meshFilter = obj.GetComponent <MeshFilter>(); Mesh mesh = new Mesh(); mesh.name = "Combine"; //合并Mesh mesh.CombineMeshes(combine); meshFilter.sharedMesh = mesh; //合并第二套UV Unwrapping.GenerateSecondaryUVSet(meshFilter.sharedMesh); MeshRenderer renderer = obj.GetComponent <MeshRenderer>(); renderer.sharedMaterials = material.ToArray(); renderer.enabled = true; MeshCollider collider = new MeshCollider(); if (collider != null) { collider.sharedMesh = mesh; } string tempPath = MESH_PATH + obj.name + "_mesh.asset"; AssetDatabase.CreateAsset(meshFilter.sharedMesh, tempPath); //PrefabUtility.DisconnectPrefabInstance(obj); }
public static void Combine() { var transform = Selection.activeGameObject.transform; var meshFilters = transform.GetComponentsInChildren <MeshFilter>(); Debug.Log(meshFilters.Length); if (meshFilters.Length < 2) { if (meshFilters.Length == 0) { EditorUtility.DisplayDialog("Combine Mesh", "The " + transform.name + " Don't have a Mesh Filter\nPlease put the gameobjects child in " + transform.name + " to combine all", "OK"); } if (meshFilters.Length > 0) { EditorUtility.DisplayDialog("Combine Mesh", "The " + transform.name + " have just one Mesh Filter\nPlease put the gameobjects child in " + transform.name + " to combine all", "OK"); } return; } if (!EditorUtility.DisplayDialog("Combine Mesh", "Are you sure if want to combine meshs?", "YES", "NO")) { return; } var position = transform.position; var rotation = transform.rotation; var scale = transform.localScale; transform.position = Vector3.zero; transform.rotation = Quaternion.identity; transform.localScale = Vector3.one; Dictionary <int, List <CombineInstance> > combinedMeshs = new Dictionary <int, List <CombineInstance> >(); List <Material> combinedMaterials = new List <Material>(); List <string> names = new List <string>(); foreach (MeshFilter msF in meshFilters) { int indexMaterial = 0; if (!names.Contains(msF.GetComponent <MeshRenderer>().sharedMaterial.name)) { names.Add(msF.GetComponent <Renderer>().sharedMaterial.name); combinedMaterials.Add(msF.GetComponent <Renderer>().sharedMaterial); indexMaterial = names.IndexOf(msF.GetComponent <Renderer>().sharedMaterial.name); combinedMeshs.Add(indexMaterial, new List <CombineInstance>()); } Debug.Log(indexMaterial); indexMaterial = names.IndexOf(msF.GetComponent <Renderer>().sharedMaterial.name); CombineInstance msCombine = new CombineInstance(); msCombine.transform = msF.transform.localToWorldMatrix; msCombine.subMeshIndex = 0; msCombine.mesh = msF.sharedMesh; combinedMeshs[indexMaterial].Add(msCombine); } List <CombineInstance> combineInstance = new List <CombineInstance>(); foreach (int index in combinedMeshs.Keys) { Mesh mesh = new Mesh(); mesh.Clear(); mesh.CombineMeshes(combinedMeshs[index].ToArray(), true, true); CombineInstance msCombine = new CombineInstance(); msCombine.mesh = mesh; msCombine.subMeshIndex = 0; Debug.Log(index); combineInstance.Add(msCombine); } if (transform.GetComponent <MeshFilter>() == null) { transform.gameObject.AddComponent <MeshFilter>(); } transform.GetComponent <MeshFilter>().sharedMesh = new Mesh(); transform.GetComponent <MeshFilter>().sharedMesh.CombineMeshes(combineInstance.ToArray(), false, false); transform.GetComponent <MeshFilter>().sharedMesh.Optimize(); transform.GetComponent <MeshFilter>().sharedMesh.RecalculateBounds(); MeshRenderer meshRendererCombine = transform.GetComponent <MeshRenderer>(); if (!meshRendererCombine) { meshRendererCombine = transform.gameObject.AddComponent <MeshRenderer>(); } meshRendererCombine.materials = combinedMaterials.ToArray(); transform.position = position; transform.rotation = rotation; transform.localScale = scale; if (EditorUtility.DisplayDialog("Combine Mesh", "Destroy old meshs?", "YES", "NO")) { foreach (MeshFilter msF in meshFilters) { if (msF.gameObject != Selection.activeGameObject) { DestroyImmediate(msF.gameObject); } } } string filePath = Application.dataPath + "/MasterCube/CombinedMeshs"; if (!System.IO.Directory.Exists(filePath)) { System.IO.Directory.CreateDirectory(filePath); } var info = new System.IO.DirectoryInfo(filePath); var fileInfo = info.GetFiles(); int nameCount = 0; foreach (FileInfo file in fileInfo) { if (file.Name.Contains(transform.name)) { nameCount++; } } Mesh _mesh = new Mesh(); string path = "Assets/MasterCube/CombinedMeshs/" + transform.name + (nameCount + 1).ToString("00") + ".asset"; AssetDatabase.CreateAsset(transform.GetComponent <MeshFilter>().sharedMesh, path); _mesh = (Mesh)AssetDatabase.LoadAssetAtPath(path, typeof(Mesh)); transform.GetComponent <MeshFilter>().sharedMesh = _mesh; Selection.activeObject = transform.gameObject; }
public void ExportSettings(string path) { AssetDatabase.DeleteAsset(path); AssetDatabase.CreateAsset(Instantiate(m_settings), path); }
public void SaveMaterial(Material material, string AssetPath) { AssetDatabase.CreateAsset(material, AssetPath + ".mat"); }