public static WindowLayout GenerateLayout(string filepath, FlowWindowLayoutTemplate layout) { filepath = filepath.Replace("//", "/"); WindowLayout instance = null; var sourcepath = ADB.GetAssetPath(layout); filepath = AssetDatabase.GenerateUniqueAssetPath(filepath); System.IO.File.Copy(sourcepath, filepath, true); ADB.Refresh(); var source = ADB.LoadAssetAtPath(filepath, typeof(GameObject)) as GameObject; var prefab = source.GetComponent <WindowLayout>(); instance = UnityEditor.PrefabUtility.InstantiatePrefab(prefab) as WindowLayout; instance = FlowDatabase.ReplaceComponents <FlowWindowLayoutTemplate, WindowLayout>(instance as FlowWindowLayoutTemplate, typeof(WindowLayout)); FlowDatabase.SaveLayout(instance); GameObject.DestroyImmediate(instance.gameObject); instance = (ADB.LoadAssetAtPath(filepath, typeof(GameObject)) as GameObject).GetComponent <WindowLayout>(); return(instance); }
// TODO used rule while migrating the howl project; needs review static AssetMoveResult WillMoveBuildRoot_inReview(string src, string dst) { src = src.DirName(); dst = dst.DirName(); src.MoveFiles(dst, relTo: src, dry: false, "*.cs", "*.asmdef"); ADB.Refresh(); return(DidNotMove); }
public static WindowBase GenerateScreen(string filepath, string className, FlowLayoutWindowTypeTemplate template) { WindowBase instance = null; filepath = filepath.Replace("//", "/"); var sourcepath = ADB.GetAssetPath(template); filepath = AssetDatabase.GenerateUniqueAssetPath(filepath); System.IO.File.Copy(sourcepath, filepath, true); ADB.Refresh(); var source = ADB.LoadAssetAtPath(filepath, typeof(GameObject)) as GameObject; var prefab = source.GetComponent <WindowBase>(); instance = UnityEditor.PrefabUtility.InstantiatePrefab(prefab) as WindowBase; var type = WindowUtilities.GetTypeFromAllAssemblies(className); instance = FlowDatabase.ReplaceComponents <FlowLayoutWindowTypeTemplate, WindowBase>(instance as FlowLayoutWindowTypeTemplate, type); FlowDatabase.SaveScreen(instance); GameObject.DestroyImmediate(instance.gameObject); instance = (ADB.LoadAssetAtPath(filepath, typeof(GameObject)) as GameObject).GetComponent <WindowBase>(); return(instance); }
// PENDING ------------------------------------------------------ // TODO needs review static AssetMoveResult WillMoveHowlRoot_inReview(string src, string dst) { src = src.DirName(); dst = dst.DirName(); // TODO edge cases? src.MoveFiles(dst, relTo: src, dry: false, "*.howl"); ADB.Refresh(); return(DidNotMove); }
public static void SaveLayout(WindowLayout instance) { if (instance == null) { return; } UnityEditor.PrefabUtility.ReplacePrefab(instance.gameObject, UnityEditor.PrefabUtility.GetPrefabParent(instance.gameObject), UnityEditor.ReplacePrefabOptions.ConnectToPrefab); ADB.Refresh(); }
private void HierarchyWindowItemOnGUI(int instanceID, Rect selectionRect) { //AssetDatabase var obj = EditorUtility.InstanceIDToObject(instanceID); //转换数据类型,obj是否为null 将作为数据分类的依据。 int sceneCount = SceneManager.sceneCount; if (this.sceneInstanceIDs.Length != sceneCount) { Array.Resize(ref this.sceneInstanceIDs, sceneCount); //修正数组容器大小,保存 Scene对应的 Instance ID } if (null == obj) //Finger out whether it is a scene or not ,tips : "obj==null " means it is a scene { if (selectionRect.y == 0) //确认首数据的写入点,Debug表明:Rect.y=0,渲染的永远是ScenesBar { index = 0; } else if (index < sceneCount) { index++; } if (this.sceneInstanceIDs[index] != instanceID) //一旦 Instance ID 数据发生改变则更新数据 { this.sceneInstanceIDs[index] = instanceID; } if (GUI.Button(new Rect(selectionRect.width - 40, selectionRect.y, 20, selectionRect.height), "Ping", GUIStyle.none)) { var assetObj = ADB.LoadAssetAtPath <SceneAsset>(SceneManager.GetSceneAt(index).path); if (null != assetObj) { EditorGUIUtility.PingObject(assetObj); } else { this.Focus(); this.ShowNotification(new GUIContent("Please save the scene first!")); } } } #region For Debug if (obj != null) { // Debug.LogFormat("{0} - activeInHierarchy:{1}.at {2} ", obj.name, ((GameObject)obj).activeInHierarchy, selectionRect.y); } else { Debug.LogFormat("{0} - Secene InHierarchy - InstanceID:{1}.at {2} - {3} ", index, instanceID, selectionRect.y, EditorSceneManager.GetSceneAt(index).path); } #endregion }
static AssetMoveResult WillMoveHowlAsset(string src, string dst) { var β = src.BuildPath(); if (dst.In(Path.howlRoot)) { β.MoveTo(dst.BuildPath(), withMetaFile: true); } else { log.message = "Deleting C# file (Howl script moved out of scope)"; β.Delete(withMetaFile: true); } ADB.Refresh(); return(DidNotMove); }
public static AssetDeleteResult OnWillDeleteAsset(string π, RemoveOpt opt) { if (π.HasBuildImage()) { π.BuildPath().DeleteFileOrDir(withMetaFile: true); ADB.Refresh(); return(DidNotDelete); } else if (π.IsHowlBound()) { log.error = "Do not modify Howl-bound assets"; return(FailedDelete); } else { return(DidNotDelete); } }
public static string CreatAssetPath <T>(this T script, string subPath) where T : UnityEngine.Object //class { if (null == script) { return(string.Empty); } string path = ADB.FindAssets("t:Script") .Where(v => Path.GetFileNameWithoutExtension(ADB.GUIDToAssetPath(v)) == script.GetType().Name) .Select(id => ADB.GUIDToAssetPath(id)) .FirstOrDefault() .ToString(); string newPath = Path.Combine(Path.GetDirectoryName(path), subPath); if (!ADB.IsValidFolder(newPath)) { newPath = ADB.GUIDToAssetPath(ADB.CreateFolder(path, subPath)); } return(newPath); }
/// <summary> /// 编辑器下使用,给定一个类的对象,在这个类的同级目录下创建文件夹并返回路径 /// </summary> /// <typeparam name="T">类</typeparam> /// <param name="script">对象</param> /// <param name="subPath">指定要创建的文件夹的名称</param> /// <returns>文件夹的相对路径,相对于Assets文件夹</returns> public static string Creat <T>(T script, string subPath) where T : UnityEngine.Object //class { string newPath = ""; #if UNITY_EDITOR string path = ADB.FindAssets("t:Script") .Where(v => Path.GetFileNameWithoutExtension(ADB.GUIDToAssetPath(v)) == script.GetType().Name) .Select(id => ADB.GUIDToAssetPath(id)) .FirstOrDefault() .ToString(); newPath = Path.Combine(Path.GetDirectoryName(path), subPath); if (!ADB.IsValidFolder(newPath)) { newPath = ADB.GUIDToAssetPath(ADB.CreateFolder(path, subPath)); } #else return(newPath); #endif return(newPath); }
private void BakeCustomReflectionProbe(ReflectionProbe probe, bool usePreviousAssetPath) { string assetPath = ""; if (usePreviousAssetPath) { assetPath = AssetDatabase.GetAssetPath(probe.customBakedTexture); } string extension = !probe.hdr ? "png" : "exr"; if (string.IsNullOrEmpty(assetPath) || (Path.GetExtension(assetPath) != ("." + extension))) { ReflectionProbe probe2; string pathWithoutExtension = FileUtil.GetPathWithoutExtension(SceneManager.GetActiveScene().path); if (string.IsNullOrEmpty(pathWithoutExtension)) { pathWithoutExtension = "Assets"; } else if (!Directory.Exists(pathWithoutExtension)) { Directory.CreateDirectory(pathWithoutExtension); } string fileNameWithoutExtension = probe.name + (!probe.hdr ? "-reflection" : "-reflectionHDR") + "." + extension; fileNameWithoutExtension = Path.GetFileNameWithoutExtension(AssetDatabase.GenerateUniqueAssetPath(Path.Combine(pathWithoutExtension, fileNameWithoutExtension))); assetPath = EditorUtility.SaveFilePanelInProject("Save reflection probe's cubemap.", fileNameWithoutExtension, extension, "", pathWithoutExtension); if (string.IsNullOrEmpty(assetPath) || (this.IsCollidingWithOtherProbes(assetPath, probe, out probe2) && !EditorUtility.DisplayDialog("Cubemap is used by other reflection probe", $"'{assetPath}' path is used by the game object '{probe2.name}', do you really want to overwrite it?", "Yes", "No"))) { return; } } EditorUtility.DisplayProgressBar("Reflection Probes", "Baking " + assetPath, 0.5f); if (!Lightmapping.BakeReflectionProbe(probe, assetPath)) { Debug.LogError("Failed to bake reflection probe to " + assetPath); } EditorUtility.ClearProgressBar(); }
public int GetInsertAfterItemIDForNewItem(string newName, TreeViewItem parentItem, bool isCreatingNewFolder, bool foldersFirst) { int result; if (!parentItem.hasChildren) { result = parentItem.id; } else { int num = parentItem.id; for (int i = 0; i < parentItem.children.Count; i++) { int id = parentItem.children[i].id; bool flag = parentItem.children[i] is AssetsTreeViewDataSource.FolderTreeItem; if (foldersFirst && flag && !isCreatingNewFolder) { num = id; } else { if (foldersFirst && !flag && isCreatingNewFolder) { break; } string assetPath = AssetDatabase.GetAssetPath(id); if (EditorUtility.NaturalCompare(Path.GetFileNameWithoutExtension(assetPath), newName) > 0) { break; } num = id; } } result = num; } return(result); }
internal static IEnumerable <ExportPackageItem> GetAssetItemsForExport(ICollection <string> guids, bool includeDependencies) { // if nothing is selected, export all if (0 == guids.Count) { string[] temp = new string[0]; // <--- I dont get this API guids = new HashSet <string>(AssetDatabase.CollectAllChildren(AssetDatabase.assetFolderGUID, temp)); } ExportPackageItem[] assets = PackageUtility.BuildExportPackageItemsListWithPackageManagerWarning(guids.ToArray(), includeDependencies, true); // If any scripts are included, add all scripts with dependencies if (includeDependencies && assets.Any(asset => UnityEditorInternal.InternalEditorUtility.IsScriptOrAssembly(asset.assetPath))) { assets = PackageUtility.BuildExportPackageItemsListWithPackageManagerWarning( guids.Union(UnityEditorInternal.InternalEditorUtility.GetAllScriptGUIDs()).ToArray(), includeDependencies, true); } // If the user exports the root Assets folder, we need to remove it from the list // explicitly, as it doesnt make sense assets = assets.Where(val => val.assetPath != "Assets").ToArray(); return(assets); }
public GameObject CreateParticleSystem(ParticleSystem parentOfNewParticleSystem, SubModuleUI.SubEmitterType defaultType) { string nextParticleSystemName = this.GetNextParticleSystemName(); GameObject gameObject = new GameObject(nextParticleSystemName, new Type[] { typeof(ParticleSystem) }); GameObject result; if (gameObject) { if (parentOfNewParticleSystem) { gameObject.transform.parent = parentOfNewParticleSystem.transform; } gameObject.transform.localPosition = Vector3.zero; gameObject.transform.localRotation = Quaternion.identity; ParticleSystem component = gameObject.GetComponent <ParticleSystem>(); if (defaultType != SubModuleUI.SubEmitterType.None) { component.SetupDefaultType((int)defaultType); } SessionState.SetFloat("CurrentEmitterAreaScroll", this.m_EmitterAreaScrollPos.x); ParticleSystemRenderer component2 = gameObject.GetComponent <ParticleSystemRenderer>(); Renderer arg_AF_0 = component2; Material[] expr_A2 = new Material[2]; expr_A2[0] = AssetDatabase.GetBuiltinExtraResource <Material>("Default-Particle.mat"); arg_AF_0.materials = expr_A2; result = gameObject; } else { result = null; } return(result); }
private void SetVersionControlSystem(object data) { int popupIndex = (int)data; if (popupIndex < 0 || popupIndex >= vcPopupList.Length) return; PopupElement el = vcPopupList[popupIndex]; string oldVC = EditorSettings.externalVersionControl; EditorSettings.externalVersionControl = el.id; Provider.UpdateSettings(); AssetDatabase.Refresh(); if (oldVC != el.id) { if (el.content.text == ExternalVersionControl.Disabled || el.content.text == ExternalVersionControl.Generic ) { // Close the normal version control window WindowPending.CloseAllWindows(); } } }
public static void SaveScreen(WindowBase instance) { UnityEditor.PrefabUtility.ReplacePrefab(instance.gameObject, UnityEditor.PrefabUtility.GetPrefabParent(instance.gameObject), UnityEditor.ReplacePrefabOptions.ReplaceNameBased); ADB.Refresh(); }
void OnGUI() { if (projectList == null) { projectList = new ReorderableList(scenesInProject, typeof(SceneInfo), false, false, false, false); projectList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "Scenes In Project", EditorStyles.boldLabel); }; projectList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var sceneInfo = scenesInProject[index]; EditorGUI.LabelField(new Rect(rect.x, rect.y, rect.width - 60, rect.height), sceneInfo.name); if (GUI.Button(new Rect(rect.width - 60, rect.y, 20, rect.height), "P", GUIStyle.none)) { EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath <SceneAsset>(sceneInfo.path)); } if (GUI.Button(new Rect(rect.width - 40, rect.y, 20, rect.height), "O", GUIStyle.none)) { List <SceneInfo> scenes = this.GetScenesInHierarchy(); //得到 Hierarchy 中的 已加载的 场景 int sceneIndex = scenes.FindIndex(v => v.path == sceneInfo.path); //确认当前请求添加的场景 的状态 if (sceneIndex == -1) { bool savemodified = EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo(); if (savemodified) //After the user responds positively (with or without saving), open the scene he specified. { int switchIndex = EditorUtility.DisplayDialogComplex("OpenSceneMode", "Addition:Add scene and keep the loaded scene\nSingle:Will Remove all the loaded scene of hierarchy", "Single", "Cancel", "Addition"); switch (switchIndex) { case 0: EditorSceneManager.OpenScene(sceneInfo.path); break; case 2: EditorSceneManager.OpenScene(sceneInfo.path, OpenSceneMode.Additive); break; case 1: default: this.ShowNotification(new GUIContent("Aborting!")); break; } } else { this.ShowNotification(new GUIContent("Aborting!")); } } else //If it is stay in the hierarchy,no matter whether it is load or unload, ping this scene { EditorGUIUtility.PingObject(scenes[sceneIndex].instanceID); this.ShowNotification(new GUIContent("This scene already in the hierarchy!")); } } if (GUI.Button(new Rect(rect.width - 20, rect.y, 20, rect.height), "A", GUIStyle.none)) { int sceneIndex = SceneUtility.GetBuildIndexByScenePath(sceneInfo.path); if (sceneIndex == -1) { var tmpSceneIn = EditorBuildSettings.scenes.ToList(); tmpSceneIn.Add(new EditorBuildSettingsScene(sceneInfo.path, true)); EditorBuildSettings.scenes = tmpSceneIn.ToArray(); ADB.Refresh(); } else { this.ShowNotification(new GUIContent("This scene already in the buildlist!")); } } }; } if (settingList == null) { settingList = new ReorderableList(scenesInSettings, typeof(SceneInfo), true, false, false, true); settingList.onReorderCallback = (ReorderableList list) => { EditorBuildSettings.scenes = list.list.Cast <SceneInfo>() .Select(scene => { var editorScene = new EditorBuildSettingsScene(); editorScene.enabled = scene.enabledInSettings; editorScene.path = scene.path; return(editorScene); }) .ToArray(); }; settingList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "Scenes In Setting", EditorStyles.boldLabel); }; settingList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var sceneInfo = scenesInSettings[index]; sceneInfo.enabledInSettings = GUI.Toggle(new Rect(rect.x, rect.y, 14, rect.height), sceneInfo.enabledInSettings, string.Empty); var tmpScenesInSetting = EditorBuildSettings.scenes.ToList(); tmpScenesInSetting.Where(scene => scene.path == sceneInfo.path).First().enabled = sceneInfo.enabledInSettings; EditorGUI.LabelField(new Rect(rect.x + 14, rect.y, rect.width - 34, rect.height), sceneInfo.name); EditorGUI.LabelField(new Rect(rect.width - 8, rect.y, 20, rect.height), index.ToString()); if (GUI.Button(new Rect(rect.width - 65, rect.y, 20, rect.height), "PH", GUIStyle.none)) { int id = this.GetInstanceId(sceneInfo); if (id != -1) { RemoveNotification(); EditorGUIUtility.PingObject(id); } else { ShowNotification(new GUIContent("The scene you pinged is not in hierarchy!")); } } if (GUI.Button(new Rect(rect.width - 30, rect.y, 20, rect.height), "PP", GUIStyle.none)) { var assetObj = ADB.LoadAssetAtPath <SceneAsset>(sceneInfo.path); if (null != assetObj) { RemoveNotification(); EditorGUIUtility.PingObject(assetObj); } } }; settingList.onRemoveCallback = (ReorderableList list) => { if (EditorUtility.DisplayDialog("Attention:", "Really want to remove this scene from the BuildList?", "Yes", "No")) { var tempList = EditorBuildSettings.scenes.ToList(); tempList.RemoveAt(list.index); tempList.TrimExcess(); EditorBuildSettings.scenes = tempList.ToArray(); ReorderableList.defaultBehaviours.DoRemoveButton(list); } }; } scenesInProject = GetScenesInProject(); scenesInSettings = GetScenesInSettings(); projectList.list = scenesInProject; settingList.list = scenesInSettings; // settingScrollPosition = EditorGUILayout.BeginScrollView(settingScrollPosition); settingList.DoLayoutList(); //EditorGUILayout.EndScrollView(); projectScrollPosition = EditorGUILayout.BeginScrollView(projectScrollPosition); projectList.DoLayoutList(); EditorGUILayout.EndScrollView(); }
private bool IsCollidingWithOtherProbes(string targetPath, ReflectionProbe targetProbe, out ReflectionProbe collidingProbe) { ReflectionProbe[] probeArray = UnityEngine.Object.FindObjectsOfType <ReflectionProbe>().ToArray <ReflectionProbe>(); collidingProbe = null; foreach (ReflectionProbe probe in probeArray) { if (((probe != targetProbe) && (probe.customBakedTexture != null)) && (AssetDatabase.GetAssetPath(probe.customBakedTexture) == targetPath)) { collidingProbe = probe; return(true); } } return(false); }
// shared by compute shader inspector too internal static void ShaderErrorListUI(Object shader, ShaderMessage[] messages, ref Vector2 scrollPosition) { int n = messages.Length; GUILayout.Space(kSpace); GUILayout.Label(string.Format("Errors ({0}):", n), EditorStyles.boldLabel); int errorListID = GUIUtility.GetControlID(kErrorViewHash, FocusType.Passive); float height = Mathf.Min(n * 20f + 40f, 150f); scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUISkin.current.box, GUILayout.MinHeight(height)); EditorGUIUtility.SetIconSize(new Vector2(16.0f, 16.0f)); float lineHeight = Styles.messageStyle.CalcHeight(EditorGUIUtility.TempContent(Styles.errorIcon), 100); Event e = Event.current; for (int i = 0; i < n; ++i) { Rect r = EditorGUILayout.GetControlRect(false, lineHeight); string err = messages[i].message; string plat = messages[i].platform.ToString(); bool warn = messages[i].severity != ShaderCompilerMessageSeverity.Error; string fileName = FileUtil.GetLastPathNameComponent(messages[i].file); int line = messages[i].line; // Double click opens shader file at error line if (e.type == EventType.MouseDown && e.button == 0 && r.Contains(e.mousePosition)) { GUIUtility.keyboardControl = errorListID; if (e.clickCount == 2) { string filePath = messages[i].file; Object asset = string.IsNullOrEmpty(filePath) ? null : AssetDatabase.LoadMainAssetAtPath(filePath); // if we don't have an asset and the filePath is an absolute path, it's an error in a system // cginc - open that instead if (asset == null && System.IO.Path.IsPathRooted(filePath)) { ShaderUtil.OpenSystemShaderIncludeError(filePath, line); } else { AssetDatabase.OpenAsset(asset ?? shader, line); } GUIUtility.ExitGUI(); } e.Use(); } // Context menu, "Copy" if (e.type == EventType.ContextClick && r.Contains(e.mousePosition)) { e.Use(); var menu = new GenericMenu(); // need to copy current value to be used in delegate // (C# closures close over variables, not their values) var errorIndex = i; menu.AddItem(EditorGUIUtility.TrTextContent("Copy error text"), false, delegate { string errMsg = messages[errorIndex].message; if (!string.IsNullOrEmpty(messages[errorIndex].messageDetails)) { errMsg += '\n'; errMsg += messages[errorIndex].messageDetails; } EditorGUIUtility.systemCopyBuffer = errMsg; }); menu.ShowAsContext(); } // background if (e.type == EventType.Repaint) { if ((i & 1) == 0) { GUIStyle st = Styles.evenBackground; st.Draw(r, false, false, false, false); } } // error location on the right side Rect locRect = r; locRect.xMin = locRect.xMax; if (line > 0) { GUIContent gc; if (string.IsNullOrEmpty(fileName)) { gc = EditorGUIUtility.TempContent(line.ToString(CultureInfo.InvariantCulture)); } else { gc = EditorGUIUtility.TempContent(fileName + ":" + line.ToString(CultureInfo.InvariantCulture)); } // calculate size so we can right-align it Vector2 size = EditorStyles.miniLabel.CalcSize(gc); locRect.xMin -= size.x; GUI.Label(locRect, gc, EditorStyles.miniLabel); locRect.xMin -= 2; // ensure some minimum width so that platform field next will line up if (locRect.width < 30) { locRect.xMin = locRect.xMax - 30; } } // platform to the left of it Rect platRect = locRect; platRect.width = 0; if (plat.Length > 0) { GUIContent gc = EditorGUIUtility.TempContent(plat); // calculate size so we can right-align it Vector2 size = EditorStyles.miniLabel.CalcSize(gc); platRect.xMin -= size.x; // draw platform in dimmer color; it's often not very important information Color oldColor = GUI.contentColor; GUI.contentColor = new Color(1, 1, 1, 0.5f); GUI.Label(platRect, gc, EditorStyles.miniLabel); GUI.contentColor = oldColor; platRect.xMin -= 2; } // error message Rect msgRect = r; msgRect.xMax = platRect.xMin; GUI.Label(msgRect, EditorGUIUtility.TempContent(err, warn ? Styles.warningIcon : Styles.errorIcon), Styles.messageStyle); } EditorGUIUtility.SetIconSize(Vector2.zero); GUILayout.EndScrollView(); }
public void SaveAndReimport() { AssetDatabase.ImportAsset(this.assetPath); }
internal static void ScanModes() { var modesData = new Dictionary <string, object> { [k_DefaultModeId] = new Dictionary <string, object> { [ModeDescriptor.LabelKey] = "Default" } }; var builtinModeFile = Path.Combine(EditorApplication.applicationContentsPath, "Resources/default.mode"); FillModeData(builtinModeFile, modesData); var modeDescriptors = AssetDatabase.EnumerateAllAssets(new SearchFilter { searchArea = SearchFilter.SearchArea.InPackagesOnly, classNames = new[] { nameof(ModeDescriptor) }, showAllHits = true }); while (modeDescriptors.MoveNext()) { var md = modeDescriptors.Current.pptrValue as ModeDescriptor; if (md == null) { continue; } FillModeData(md.path, modesData); } modes = new ModeEntry[modesData.Keys.Count]; modes[0] = CreateEntry(k_DefaultModeId, (JSONObject)modesData[k_DefaultModeId]); var modeIndex = 1; hasSwitchableModes = false; foreach (var modeId in modesData.Keys) { if (modeId == k_DefaultModeId) { continue; } var modeFields = (JSONObject)modesData[modeId]; modes[modeIndex] = CreateEntry(modeId, modeFields); hasSwitchableModes |= !JsonUtils.JsonReadBoolean(modeFields, "builtin"); modeIndex++; } Array.Sort(modes, (m1, m2) => { if (m1.id == "default") { return(-1); } if (m2.id == "default") { return(1); } return(m1.id.CompareTo(m2.id)); }); }
internal static void RegisterCustomDependency(string dependency, Hash128 hashOfValue) => AssetDatabaseExp.RegisterCustomDependency(dependency, hashOfValue);
internal static void UnregisterCustomDependencyPrefixFilter(string prefixFilter) => AssetDatabaseExp.UnregisterCustomDependencyPrefixFilter(prefixFilter);
internal static bool IsAssetImportWorkerProcess() => AssetDatabaseExp.IsAssetImportWorkerProcess();
void ListArea(Rect rect, PresetLibrary lib, object newPresetObject) { if (lib == null) { return; } Event evt = Event.current; if (m_PresetLibraryFileLocation == PresetFileLocation.ProjectFolder && evt.type == EventType.Repaint) { m_IsOpenForEdit = AssetDatabase.IsOpenForEdit(pathWithExtension, StatusQueryOptions.UseCachedIfPossible); } else if (m_PresetLibraryFileLocation == PresetFileLocation.PreferencesFolder) { m_IsOpenForEdit = true; } if (!m_IsOpenForEdit) { Rect versionControlRect = new Rect(rect.x, rect.yMax - versionControlAreaHeight, rect.width, versionControlAreaHeight); VersionControlArea(versionControlRect); rect.height -= versionControlAreaHeight; } // To ensure we setup grid to visible rect we need to run once to check if scrollbar is taking up screen estate. // To optimize the first width is based on the last frame and we therefore most likely will only run once. for (int i = 0; i < 2; i++) { gridWidth = m_ShowedScrollBarLastFrame ? rect.width - 17 : rect.width; SetupGrid(gridWidth, lib.Count()); bool isShowingScrollBar = m_Grid.height > rect.height; if (isShowingScrollBar == m_ShowedScrollBarLastFrame) { break; } else { m_ShowedScrollBarLastFrame = isShowingScrollBar; } } // Draw horizontal lines for scrollview content to clip against if ((m_ShowedScrollBarLastFrame || alwaysShowScrollAreaHorizontalLines) && Event.current.type == EventType.Repaint) { Rect scrollEdgeRect = new RectOffset(1, 1, 1, 1).Add(rect); scrollEdgeRect.height = 1; EditorGUI.DrawRect(scrollEdgeRect, new Color(0, 0, 0, 0.3f)); scrollEdgeRect.y += rect.height + 1; EditorGUI.DrawRect(scrollEdgeRect, new Color(0, 0, 0, 0.3f)); } Rect contentRect = new Rect(0, 0, 1, m_Grid.height); m_State.m_ScrollPosition = GUI.BeginScrollView(rect, m_State.m_ScrollPosition, contentRect); { int startIndex, endIndex; float yOffset = 0f; int maxIndex = m_ShowAddNewPresetItem ? lib.Count() : lib.Count() - 1; bool isGridVisible = m_Grid.IsVisibleInScrollView(rect.height, m_State.m_ScrollPosition.y, yOffset, maxIndex, out startIndex, out endIndex); bool drawDragInsertionMarker = false; if (isGridVisible) { // Handle renaming overlay before item handling because its needs mouse input first to end renaming if clicked outside if (GetRenameOverlay().IsRenaming() && !GetRenameOverlay().isWaitingForDelay) { if (!m_State.m_RenameOverlay.OnGUI()) { EndRename(); evt.Use(); } Repaint(); } for (int i = startIndex; i <= endIndex; ++i) { int itemControlID = i + 1000000; Rect itemRect = m_Grid.CalcRect(i, yOffset); Rect previewRect = itemRect; Rect labelRect = itemRect; switch (m_State.itemViewMode) { case PresetLibraryEditorState.ItemViewMode.List: previewRect.width = m_State.m_PreviewHeight * m_PreviewAspect; labelRect.x += previewRect.width + 8f; labelRect.width -= previewRect.width + 10f; labelRect.height = kGridLabelHeight; labelRect.y = itemRect.yMin + (itemRect.height - kGridLabelHeight) * 0.5f; break; case PresetLibraryEditorState.ItemViewMode.Grid: // only preview is shown: no label break; } // Add new preset button if (m_ShowAddNewPresetItem && i == lib.Count()) { CreateNewPresetButton(previewRect, newPresetObject, lib, m_IsOpenForEdit); continue; } // Rename overlay bool isRenamingThisItem = IsRenaming(i); if (isRenamingThisItem) { Rect renameRect = labelRect; renameRect.y -= 1f; renameRect.x -= 1f; // adjustment to fit perfectly m_State.m_RenameOverlay.editFieldRect = renameRect; } // Handle event switch (evt.type) { case EventType.Repaint: if (m_State.m_HoverIndex == i) { if (itemRect.Contains(evt.mousePosition)) { // TODO: We need a better hover effect so disabling for now... //if (!GetRenameOverlay().IsRenaming ()) // DrawHoverEffect (itemRect, false); } else { m_State.m_HoverIndex = -1; } } if (m_DragState.draggingIndex == i || GUIUtility.hotControl == itemControlID) { DrawHoverEffect(itemRect, false); } lib.Draw(previewRect, i); if (!isRenamingThisItem && drawLabels) { GUI.Label(labelRect, GUIContent.Temp(lib.GetName(i))); } if (m_DragState.dragUponIndex == i && m_DragState.draggingIndex != m_DragState.dragUponIndex) { drawDragInsertionMarker = true; } // We delete presets on alt-click if (GUIUtility.hotControl == 0 && Event.current.alt && m_IsOpenForEdit) { EditorGUIUtility.AddCursorRect(itemRect, MouseCursor.ArrowMinus); } break; case EventType.MouseDown: if (evt.button == 0 && itemRect.Contains(evt.mousePosition)) { GUIUtility.hotControl = itemControlID; if (evt.clickCount == 1) { m_ItemClickedCallback(evt.clickCount, lib.GetPreset(i)); evt.Use(); } } break; case EventType.MouseDrag: if (GUIUtility.hotControl == itemControlID && m_IsOpenForEdit) { DragAndDropDelay delay = (DragAndDropDelay)GUIUtility.GetStateObject(typeof(DragAndDropDelay), itemControlID); if (delay.CanStartDrag()) { // Start drag DragAndDrop.PrepareStartDrag(); DragAndDrop.SetGenericData("DraggingPreset", i); DragAndDrop.StartDrag(""); m_DragState.draggingIndex = i; m_DragState.dragUponIndex = i; GUIUtility.hotControl = 0; } evt.Use(); } break; case EventType.DragUpdated: case EventType.DragPerform: { Rect dragRect = GetDragRect(itemRect); if (dragRect.Contains(evt.mousePosition)) { m_DragState.dragUponIndex = i; m_DragState.dragUponRect = itemRect; if (m_State.itemViewMode == PresetLibraryEditorState.ItemViewMode.List) { m_DragState.insertAfterIndex = ((evt.mousePosition.y - dragRect.y) / dragRect.height) > 0.5f; } else { m_DragState.insertAfterIndex = ((evt.mousePosition.x - dragRect.x) / dragRect.width) > 0.5f; } bool perform = evt.type == EventType.DragPerform; if (perform) { if (m_DragState.draggingIndex >= 0) { MovePreset(m_DragState.draggingIndex, m_DragState.dragUponIndex, m_DragState.insertAfterIndex); DragAndDrop.AcceptDrag(); } ClearDragState(); } DragAndDrop.visualMode = DragAndDropVisualMode.Move; evt.Use(); } } break; case EventType.DragExited: if (m_DragState.IsDragging()) { ClearDragState(); evt.Use(); } break; case EventType.MouseUp: if (GUIUtility.hotControl == itemControlID) { GUIUtility.hotControl = 0; if (evt.button == 0 && itemRect.Contains(evt.mousePosition)) { if (Event.current.alt && m_IsOpenForEdit) { DeletePreset(i); evt.Use(); } } } break; case EventType.ContextClick: if (itemRect.Contains(evt.mousePosition)) { PresetContextMenu.Show(m_IsOpenForEdit, i, newPresetObject, this); evt.Use(); } break; case EventType.MouseMove: if (itemRect.Contains(evt.mousePosition)) { if (m_State.m_HoverIndex != i) { m_State.m_HoverIndex = i; Repaint(); } } else if (m_State.m_HoverIndex == i) { m_State.m_HoverIndex = -1; Repaint(); } break; } } // end foreach item // Draw above all items if (drawDragInsertionMarker) { DrawDragInsertionMarker(); } } } GUI.EndScrollView(); }
internal static void DrawPreview(IPreviewable defaultPreview, Rect previewArea, UnityObject[] targets) { string text = string.Empty; Event evt = Event.current; // If multiple targets, draw a grid of previews if (targets.Length > 1) { // Draw the previews inside the region of the background that's solid colored Rect previewPositionInner = new RectOffset(16, 16, 20, 25).Remove(previewArea); // Number of previews to aim at int maxRows = Mathf.Max(1, Mathf.FloorToInt((previewPositionInner.height + kGridSpacing) / (kPreviewMinSize + kGridSpacing + kPreviewLabelHeight))); int maxCols = Mathf.Max(1, Mathf.FloorToInt((previewPositionInner.width + kGridSpacing) / (kPreviewMinSize + kGridSpacing))); int countWithMinimumSize = maxRows * maxCols; int neededCount = Mathf.Min(targets.Length, kGridTargetCount); // Get number of columns and rows bool fixedSize = true; int[] division = new int[2] { maxCols, maxRows }; if (neededCount < countWithMinimumSize) { division = GetGridDivision(previewPositionInner, neededCount, kPreviewLabelHeight); fixedSize = false; } // The available cells in the grid may be slightly higher than what was aimed at. // If the number of targets is also higher, we might as well fill in the remaining cells. int count = Mathf.Min(division[0] * division[1], targets.Length); // Calculations become simpler if we add one spacing to the width and height, // so there is the same number of spaces and previews. previewPositionInner.width += kGridSpacing; previewPositionInner.height += kGridSpacing; Vector2 cellSize = new Vector2( Mathf.FloorToInt(previewPositionInner.width / division[0] - kGridSpacing), Mathf.FloorToInt(previewPositionInner.height / division[1] - kGridSpacing) ); float previewSize = Mathf.Min(cellSize.x, cellSize.y - kPreviewLabelHeight); if (fixedSize) { previewSize = Mathf.Min(previewSize, kPreviewMinSize); } bool selectingOne = (evt.type == EventType.MouseDown && evt.button == 0 && evt.clickCount == 2 && previewArea.Contains(evt.mousePosition)); defaultPreview.ResetTarget(); for (int i = 0; i < count; i++) { Rect r = new Rect( previewPositionInner.x + (i % division[0]) * previewPositionInner.width / division[0], previewPositionInner.y + (i / division[0]) * previewPositionInner.height / division[1], cellSize.x, cellSize.y ); if (selectingOne && r.Contains(Event.current.mousePosition)) { if (defaultPreview.target is AssetImporter) { // The new selection should be the asset itself, not the importer Selection.objects = new[] { AssetDatabase.LoadAssetAtPath <UnityObject>(((AssetImporter)defaultPreview.target).assetPath) } } ; else { Selection.objects = new UnityObject[] { defaultPreview.target } }; } // Make room for label underneath r.height -= kPreviewLabelHeight; // Make preview square Rect rSquare = new Rect(r.x + (r.width - previewSize) * 0.5f, r.y + (r.height - previewSize) * 0.5f, previewSize, previewSize); // Draw preview inside a group to prevent overdraw // @TODO: Make style with solid color that doesn't have overdraw GUI.BeginGroup(rSquare); Editor.m_AllowMultiObjectAccess = false; defaultPreview.OnInteractivePreviewGUI(new Rect(0, 0, previewSize, previewSize), Styles.preBackgroundSolid); Editor.m_AllowMultiObjectAccess = true; GUI.EndGroup(); // Draw the name of the object r.y = rSquare.yMax; r.height = 16; GUI.Label(r, targets[i].name, Styles.previewMiniLabel); defaultPreview.MoveNextTarget(); } defaultPreview.ResetTarget(); // Remember to reset referenceTargetIndex to prevent following calls to 'editor.target' will return a different target which breaks all sorts of places. Fix for case 600235 if (Event.current.type == EventType.Repaint) { text = string.Format("Previewing {0} of {1} Objects", count, targets.Length); } } // If only a single target, just draw that one else { defaultPreview.OnInteractivePreviewGUI(previewArea, Styles.preBackground); if (Event.current.type == EventType.Repaint) { // TODO: This should probably be calculated during import and stored together with the asset somehow. Or maybe not. Not sure, really... text = defaultPreview.GetInfoString(); if (text != string.Empty) { text = text.Replace("\n", " "); text = string.Format("{0}\n{1}", defaultPreview.target.name, text); } } } // Draw the asset info. if (Event.current.type == EventType.Repaint && text != string.Empty) { var textHeight = Styles.dropShadowLabelStyle.CalcHeight(GUIContent.Temp(text), previewArea.width); EditorGUI.LabelField(new Rect(previewArea.x, previewArea.yMax - textHeight - kPreviewLabelPadding, previewArea.width, textHeight), text, Styles.preOverlayLabel); } }
public override bool IsRenamingItemAllowed(TreeViewItem item) { return(!AssetDatabase.IsSubAsset(item.id) && item.parent != null); }
// Internal for testing framework internal void SaveDirtyPrefabAssets(bool reloadInspectors) { if (assetTargets == null) { return; } if (assetTarget == null) { return; } m_DirtyPrefabAssets.Clear(); foreach (var asset in assetTargets) { // The asset could have been deleted when this method is called from OnDestroy(). // E.g delete the selected prefab asset from the Project Browser. if (asset == null) { continue; } if (!EditorUtility.IsPersistent(asset)) { continue; } if (!(asset is GameObject)) { continue; } var rootGameObject = (GameObject)asset; if (IsDirty(rootGameObject)) { string currentGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(rootGameObject)); var changeTracking = new TrackedAsset() { asset = rootGameObject, guid = currentGuid, hash = AssetDatabase.GetSourceAssetFileHash(currentGuid) }; m_DirtyPrefabAssets.Add(changeTracking); } } if (m_DirtyPrefabAssets.Count > 0) { AssetDatabase.StartAssetEditing(); try { foreach (var trackedAsset in m_DirtyPrefabAssets) { bool savedSuccesfully; PrefabUtility.SavePrefabAsset(trackedAsset.asset, out savedSuccesfully); if (!savedSuccesfully) { string title = L10n.Tr("Saving Failed"); string message = L10n.Tr("Check the Console window to get more insight into what needs to be fixed on the Prefab Asset.\n\nYou can open Prefab Mode to fix any issues on child GameObjects"); EditorUtility.DisplayDialog(title, message, L10n.Tr("OK")); m_SavingHasFailed = true; break; } } } finally { AssetDatabase.StopAssetEditing(); if (reloadInspectors) { foreach (var trackedAsset in m_DirtyPrefabAssets) { if (AssetDatabase.GetSourceAssetFileHash(trackedAsset.guid) != trackedAsset.hash) { // We only call ForceReloadInspectors (and not ForceRebuildInspectors) to ensure local inspector state // is not destroyed, such as a foldout state maintained by an editor (case 1255013). // And we need to reload Prefab asset inspectors in order for the preview to be regenerated since the preview shows // an instantiated Prefab. E.g disable a MeshRenderer on a Prefab Asset and the mesh should be hidden in the preview. EditorUtility.ForceReloadInspectors(); break; } } } } } }
internal virtual bool HasLargeHeader() { return(AssetDatabase.IsMainAsset(target) || AssetDatabase.IsSubAsset(target)); }
private static string CreateDisplayName(int instanceID) { return(Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(instanceID))); }