public static Type Create <Type>(string path, bool createPath = true) where Type : ScriptableObject { if (path.IsNull()) { return(default(Type)); } var name = path.GetPathTerm(); var useName = typeof(Type).Name == "ScriptableObject"; var folder = Application.dataPath + Singleton.storagePath; path = folder.GetAssetPath() + path; if (createPath) { File.Create(folder); } ProxyEditor.ImportAsset(folder.GetAssetPath()); try{ ScriptableObject instance = useName ? ScriptableObject.CreateInstance(name) : ScriptableObject.CreateInstance <Type>(); ProxyEditor.CreateAsset(instance, path); ProxyEditor.RefreshAssets(); return(instance.As <Type>()); } catch { Log.Warning("[Utility] No scriptableObject exists named -- " + name + ".asset"); } return(null); }
public static void Dump() { var savePath = EditorUtility.SaveFilePanel("Dump GUISkin", Theme.storagePath, "Default", "guiSkin").GetAssetPath(); var skin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector); skin = ScriptableObject.CreateInstance <GUISkin>().Use(skin); ProxyEditor.CreateAsset(skin, savePath); }
public void Process() { if (this.goal == null) { Log.Warning("[MaterialMapper] : No goal shader selected."); return; } ProxyEditor.CreateAsset(new Material(this.goal), "Assets/Temporary.mat"); string goalHeader = File.Find("Temporary.mat").ReadText().Cut("%YAML", "m_SavedProperties"); string goalName = goalHeader.Parse("m_Name:", "\n"); ProxyEditor.DeleteAsset("Assets/Temporary.mat"); List <string> guids = new List <string>(); List <FileData> matching = new List <FileData>(); FileData[] allMaterials = File.FindAll("*.mat"); foreach (var shader in this.shaders) { if (shader == null) { continue; } var path = File.GetAssetPath(shader); guids.AddNew(ProxyEditor.GetGUID(path)); } ProxyEditor.StartAssetEditing(); foreach (FileData materialFile in allMaterials) { Material material = materialFile.GetAsset <Material>(); string text = materialFile.ReadText(); foreach (string guid in guids) { string idLine = "guid: " + guid; bool repair = material.shader.name.Contains("Hidden/InternalErrorShader"); if (repair || text.Contains(idLine)) { string header = text.Cut("%YAML", "m_SavedProperties"); string name = header.Parse("m_Name:", "\n"); foreach (ShaderInfo info in this.keywordMap) { if (!info.mapTo.ContainsAny("[Ignore]", "[No Matching]")) { text = text.Replace(" " + info.name, " " + info.mapTo); } } text = text.Replace(header, goalHeader); text = text.Replace(goalName, name); materialFile.Write(text); matching.AddNew(materialFile); break; } } } ProxyEditor.StopAssetEditing(); MaterialCleaner.Clean(matching.ToArray()); Log.Show("[MaterialMapper] : " + matching.Count + " materials modified."); }
public static void SplitAnimations(float forceTangent = -1) { foreach (Transform selection in Selection.transforms) { var animation = (Animation)selection.GetComponent("Animation"); if (animation != null) { AnimationClip[] clips = AnimationUtility.GetAnimationClips(selection.gameObject); AnimationClip[] newClips = new AnimationClip[clips.Length]; Log.Show("[HelperMenu] Converting " + clips.Length + " animations..."); int clipIndex = 0; foreach (AnimationClip clip in clips) { if (clip == null) { ++clipIndex; continue; } string clipPath = clip.name + ".anim"; string originalPath = File.GetAssetPath(clip); string savePath = originalPath.GetDirectory() + "/" + clipPath; var newClip = new AnimationClip(); if (originalPath.Contains(".anim")) { Log.Show("[HelperMenu] [" + clipIndex + "] " + clip.name + " skipped. Already separate .anim file."); newClip = clip; } else { newClip.wrapMode = clip.wrapMode; AnimationClipCurveData[] curves = AnimationUtility.GetAllCurves(clip); foreach (AnimationClipCurveData data in curves) { var newKeys = new List <Keyframe>(); foreach (Keyframe key in data.curve.keys) { var newKey = new Keyframe(key.time, key.value); newKey.inTangent = forceTangent != -1 ? forceTangent : key.inTangent; newKey.outTangent = forceTangent != -1 ? forceTangent : key.outTangent; newKeys.Add(newKey); } newClip.SetCurve(data.path, data.type, data.propertyName, new AnimationCurve(newKeys.ToArray())); } Log.Show("[HelperMenu] [" + clipIndex + "] " + clip.name + " processed -- " + savePath); ProxyEditor.CreateAsset(newClip, savePath); } newClips[clipIndex] = newClip; ++clipIndex; } AnimationUtility.SetAnimationClips(animation, newClips); } else { Log.Show("[HelperMenu] No animation component found on object -- " + selection.name); } } }
public static void DumpExtendedComplete() { var path = ThemeSkinset.dumpPath; var savePath = path.GetAssetPath(); var themeName = savePath.Split("/").Last(); ProxyEditor.StartAssetEditing(); EditorUI.ClearProgressBar(); EditorApplication.update -= Stepper.active.Step; foreach (var buffer in ThemeSkinset.dumpBuffer) { var skinPath = savePath + "/" + buffer.Key + ".guiskin"; var customStyles = new List <GUIStyle>(); var styles = buffer.Value is Dictionary <string, GUIStyle>?(Dictionary <string, GUIStyle>)buffer.Value : buffer.Value.GetVariables <GUIStyle>().Distinct(); foreach (var styleData in styles) { var style = new GUIStyle(styleData.Value); if (buffer.Key.Contains(".")) { style.Rename(styleData.Key + " [" + style.name + "]"); } customStyles.Add(style); } if (customStyles.Count > 0) { GUISkin newSkin = ScriptableObject.CreateInstance <GUISkin>(); newSkin.name = buffer.Key; newSkin.customStyles = customStyles.ToArray(); File.Create(path); ProxyEditor.CreateAsset(newSkin, skinPath); } } var skin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector); skin = ScriptableObject.CreateInstance <GUISkin>().Use(skin); ProxyEditor.CreateAsset(skin, savePath + "/" + themeName + ".guiskin"); ProxyEditor.StopAssetEditing(); ThemeSkinset.dumpBuffer.Clear(); }
private static void Step() { if (Class.complete) { return; } int index = Class.index; MeshFilter filter = Class.filters[index]; string updateMessage = "Mesh " + index + "/" + Class.meshCount; bool canceled = EditorUI.DrawProgressBar("Combining Meshes", updateMessage, ((float)index) / Class.meshCount); if (canceled) { Class.meshCount = 0; } else if (filter != null && filter.sharedMesh != null) { if ((Class.vertexCount + filter.sharedMesh.vertexCount) >= 65534) { Log.Show("[Combine Meshes] Added extra submesh due to vertices at " + Class.vertexCount); Class.StepLast(); Class.meshes.Add(new Mesh()); Class.subIndex = index; Class.vertexCount = 0; } Mesh currentMesh = filter.sharedMesh; if (filter.sharedMesh.subMeshCount > 1) { currentMesh = (Mesh)UnityEngine.Object.Instantiate(filter.sharedMesh); currentMesh.triangles = currentMesh.triangles; } Class.combines[index].mesh = currentMesh; Class.combines[index].transform = filter.transform.localToWorldMatrix; Class.vertexCount += currentMesh.vertexCount; if (Class.inline) { Component.DestroyImmediate(filter.gameObject.GetComponent <MeshRenderer>()); Component.DestroyImmediate(filter.gameObject.GetComponent <MeshFilter>()); } } Class.index += 1; if (Class.index >= Class.meshCount) { if (!canceled) { Class.StepLast(); //Material material = File.GetAsset<Material>("Baked.mat"); if (!Class.inline) { foreach (GameObject current in Class.selection) { GameObject target = (GameObject)GameObject.Instantiate(current); target.name = target.name.Replace("(Clone)", ""); target.transform.parent = Locate.GetScenePath("Scene-Combined").transform; MeshFilter[] filters = target.GetComponentsInChildren <MeshFilter>(); foreach (MeshFilter nullFilter in filters) { Component.DestroyImmediate(nullFilter.gameObject.GetComponent <MeshRenderer>()); Component.DestroyImmediate(nullFilter.gameObject.GetComponent <MeshFilter>()); } current.SetActive(false); } } bool singleRoot = Class.selection.Length == 1; string start = singleRoot ? Class.selection[0].name + "/" : ""; foreach (Mesh mesh in Class.meshes) { GameObject container = new GameObject("@Mesh" + Class.meshNumber); if (Class.inline && singleRoot) { container.transform.parent = Class.selection[0].transform; } else { container.transform.parent = Locate.GetScenePath("Scene-Combined/" + start).transform; } //MeshRenderer containerRenderer = container.AddComponent<MeshRenderer>(); MeshFilter containerFilter = container.AddComponent <MeshFilter>(); if (Class.path.IsEmpty()) { Class.path = EditorUtility.SaveFolderPanel("Combine Meshes", Application.dataPath, "").GetAssetPath(); } File.Create(path); ProxyEditor.CreateAsset(mesh, path + "/Combined" + meshNumber + ".asset"); containerFilter.mesh = mesh; //containerRenderer.material = new Material(material); Class.meshNumber += 1; } } TimeSpan span = TimeSpan.FromSeconds(Time.Get() - Class.time); string totalTime = span.Minutes + " minutes and " + span.Seconds + " seconds"; Log.Show("[Combine Meshes] Reduced " + Class.meshCount + " meshes to " + Class.meshes.Count + "."); Log.Show("[Combine Meshes] Completed in " + totalTime + "."); ProxyEditor.SaveAssets(); EditorUI.ClearProgressBar(); Class.complete = true; while (EditorApplication.update == Class.Step) { EditorApplication.update -= Class.Step; } } }
private static void Step() { if (BakeVertexData.complete) { return; } Renderer renderer = BakeVertexData.renderers[BakeVertexData.index]; int size = BakeVertexData.renderers.Length; GameObject current = renderer.gameObject; MeshFilter filter = current.GetComponent <MeshFilter>(); string updateMessage = "Mesh " + BakeVertexData.index + "/" + size; bool canceled = EditorUI.DrawProgressBar("Baking Vertex Colors", updateMessage, ((float)BakeVertexData.index) / size); if (canceled) { size = 0; } else if (filter && filter.sharedMesh && renderer.sharedMaterial) { bool generateMesh = true; string meshPath = File.GetAssetPath(filter.sharedMesh); if (meshPath.Contains(".fbx", true)) { FileData file = File.Find(meshPath); int subMeshIndex = 0; string newPath = file.path.GetAssetPath() + "Baked/" + file.name + "%%.asset"; int vertexCount = filter.sharedMesh.vertices.Length; Color32[] colorValues = new Color32[vertexCount]; Material[] materials = renderer.sharedMaterials; bool complex = renderer.sharedMaterials.Length > 1; foreach (Material material in materials) { bool hasColor = material.HasProperty("_Color"); Color32 color = hasColor ? material.GetColor("_Color") : Colors.Get("Violet"); //color.a = shaderName.Contains("Outline",true) ? 255 : 0; string colorValue = color.ToString().Remove("RGBA(", " ", ",", ")"); string pathID = complex ? "" : "-" + colorValue; newPath = newPath.Replace("%%", pathID); Mesh existing = File.GetAsset <Mesh>(newPath, false); Material targetMaterial = BakeVertexData.baked; string shaderName = material.shader.name; if (shaderName.Contains("Lighted", true)) { targetMaterial = BakeVertexData.bakedShaded; } if (shaderName.Contains("Outline", true)) { targetMaterial = BakeVertexData.bakedOutline; } if (existing != null && !complex) { //Log.Show("[Bake Vertex Colors] Already exists -- " + newPath); filter.sharedMesh = existing; materials[subMeshIndex] = targetMaterial; generateMesh = false; subMeshIndex += 1; continue; } int[] indices = filter.sharedMesh.GetIndices(subMeshIndex); foreach (int index in indices) { colorValues[index] = color; } materials[subMeshIndex] = targetMaterial; subMeshIndex += 1; } if (generateMesh) { var newMesh = (Mesh)UnityEngine.Object.Instantiate(filter.sharedMesh); newMesh.colors32 = colorValues; //Log.Show("[Bake Vertex Colors] Generating -- " + newPath); File.Create(file.path.GetDirectory() + "/Baked"); ProxyEditor.CreateAsset(newMesh, newPath); filter.sharedMesh = newMesh; } renderer.sharedMaterials = materials; } } BakeVertexData.index += 1; if (BakeVertexData.index >= size) { var span = TimeSpan.FromSeconds(Time.Get() - BakeVertexData.time); string totalTime = span.Minutes + " minutes and " + span.Seconds + " seconds"; Log.Show("[Bake Vertex Colors] Baked data for " + size + " renderers."); Log.Show("[Bake Vertex Colors] Completed in " + totalTime + "."); ProxyEditor.SaveAssets(); EditorUI.ClearProgressBar(); EditorApplication.update -= BakeVertexData.Step; BakeVertexData.complete = true; } }