/// <summary> /// Creates a new tooltip with a title, a summary, and an optional array of characters for the shortcut. /// /// To specify modifier keys, use the Windows control keys. ProBuilder manages switching to Linux /// control keys for the macOS and Linux versions of the Unity Editor. /// </summary> /// <param name="title">The header text for this tooltip.</param> /// <param name="summary">The body of the tooltip text. This should be kept brief.</param> /// <param name="shortcut">A set of keys to be displayed as the shortcut for this action.</param> public TooltipContent(string title, string summary, params char[] shortcut) : this(title, summary, "") { if (shortcut != null && shortcut.Length > 0) { this.shortcut = string.Empty; for (int i = 0; i < shortcut.Length - 1; i++) { if (!EditorUtility.IsUnix()) { this.shortcut += InternalUtility.ControlKeyString(shortcut[i]) + " + "; } else { this.shortcut += shortcut[i] + " + "; } } if (!EditorUtility.IsUnix()) { this.shortcut += InternalUtility.ControlKeyString(shortcut[shortcut.Length - 1]); } else { this.shortcut += shortcut[shortcut.Length - 1]; } } }
/// <summary> /// Force a rebuild of all editor picking meshes for all graphics attached to all /// groups. Editor picking meshes are what allow graphics to be accurately picked /// in the scene view even if they are in a curved space. /// </summary> public void RebuildEditorPickingMeshes() { //No picking meshes for prefabs if (InternalUtility.IsPrefab(_renderer)) { return; } if (!Application.isPlaying) { if (_renderer._space != null) { _renderer._space.RebuildHierarchy(); _renderer._space.RecalculateTransformers(); } validateGraphics(); foreach (var group in _renderer._groups) { group.editor.ValidateGraphicList(); group.RebuildFeatureData(); group.RebuildFeatureSupportInfo(); group.editor.RebuildEditorPickingMeshes(); } } foreach (var group in _renderer._groups) { group.editor.RebuildEditorPickingMeshes(); } }
protected virtual void OnEnable() { #if UNITY_EDITOR if (InternalUtility.IsPrefab(this)) { return; } if (Application.isPlaying) { #endif //If we are not attached, and if we are about not about to become attached if (!isAttachedToGroup && !_willBeAttached) { var parentRenderer = GetComponentInParent <LeapGraphicRenderer>(); if (parentRenderer != null) { parentRenderer.TryAddGraphic(this); } } patchReferences(); #if UNITY_EDITOR } #endif }
bool GeoLevelShortcuts(Shortcut shortcut) { switch (shortcut.action) { case "Escape": ClearElementSelection(); EditorUtility.ShowNotification("Top Level"); UpdateSelection(); selectMode = SelectMode.Object; return(true); // Used to be (incorrectly) named handle pivot, and since shortcuts are serialized this value is still valid case "Toggle Handle Pivot": case "Toggle Handle Orientation": VertexManipulationTool.handleOrientation = InternalUtility.NextEnumValue(VertexManipulationTool.handleOrientation); return(true); // TODO Remove once a workaround for non-upper-case shortcut chars is found case "Toggle Selection Mode": if (s_UniqueModeShortcuts) { return(false); } ToggleSelectionMode(); EditorUtility.ShowNotification(selectMode.ToString()); return(true); case "Delete Face": EditorUtility.ShowNotification(EditorToolbarLoader.GetInstance <DeleteFaces>().DoAction().notification); return(true); case "Set Pivot": if (selection.Count > 0) { foreach (ProBuilderMesh pbo in selection) { UndoUtility.RecordObjects(new UObject[2] { pbo, pbo.transform }, "Set Pivot"); if (pbo.selectedIndexesInternal.Length > 0) { pbo.CenterPivot(pbo.selectedIndexesInternal); } else { pbo.CenterPivot(null); } } EditorUtility.ShowNotification("Set Pivot"); } return(true); default: return(false); } }
static void UndoRedoPerformed() { // material preview when dragging in scene-view is done by applying then undoing changes. we don't want to // rebuild the mesh every single frame when dragging. if (SceneDragAndDropListener.isDragging) { return; } // Synchronize just checks that the mesh is not null, and UV2 is still valid. This should be very cheap except // for the FindObjectsOfType call. foreach (var mesh in Object.FindObjectsOfType <ProBuilderMesh>()) { EditorUtility.SynchronizeWithMeshFilter(mesh); mesh.InvalidateCaches(); } foreach (var mesh in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms)) { mesh.InvalidateCaches(); mesh.Rebuild(); mesh.Optimize(); } ProBuilderEditor.Refresh(); SceneView.RepaintAll(); }
public override ActionResult DoAction() { mode = InternalUtility.NextEnumValue(mode); return(new ActionResult(ActionResult.Status.Success, "Set Drag Select\n" + (mode == RectSelectMode.Complete ? "Complete" : "Intersect"))); }
public static void RegisterListener(Action <PathfinderEvent> listener, string debugName = null, int?priority = null) { InternalUtility.ValidateNoId(log: false); RegisterExpressionListener(listener.Method.GetParameters()[0].ParameterType, new ListenerObject(listener.Method, new ListenerOptions { DebugName = debugName, PriorityStore = priority })); }
/// <summary> /// Registers an event listener by compile time type. /// </summary> /// <param name="listener">The listener function that will be executed on an event call</param> /// <param name="debugName">Name to assign for debug purposes</param> /// <typeparam name="T">The PathfinderEvent Compile time Type to listen for</typeparam> public static void RegisterListener <T>(Action <T> listener, string debugName, int?priority) where T : PathfinderEvent { InternalUtility.ValidateNoId(log: false); RegisterExpressionListener(typeof(T), new ListenerObject(listener.Method, new ListenerOptions { DebugName = debugName, PriorityStore = priority })); }
public static Color GetColor(string key, Color fallback) { if (s_Preferences != null && preferences.HasKey <Color>(key)) { return(preferences.GetColor(key, fallback)); } InternalUtility.TryParseColor(EditorPrefs.GetString(key), ref fallback); return(fallback); }
bool HasFrameBounds() { if (m_Mesh == null) { m_Mesh = (ProBuilderMesh)target; } return(ProBuilderEditor.instance != null && InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms).Sum(x => x.selectedIndexesInternal.Length) > 0); }
/// <summary> /// Registers a daemon interface. /// </summary> /// <returns>The daemon's full id if added to the game, <c>null</c> otherwise.</returns> /// <param name="id">The daemon interface id to insert.</param> /// <param name="inter">The interface to add.</param> public static string RegisterDaemon(string id, Interface inter) { id = InternalUtility.Validate(id, "Daemon", inter.GetType().FullName, true); if (ModDaemons.ContainsKey(id)) { return(null); } ModDaemons.Add(id, inter); return(id); }
private void onAnySave() { if (_renderer == null || InternalUtility.IsPrefab(_renderer)) { InternalUtility.OnAnySave -= onAnySave; return; } DoEditorUpdateLogic(fullRebuild: true); }
public void DoLateUpdateEditor() { Undo.RecordObject(_renderer, "Update graphic renderer."); Assert.IsFalse(InternalUtility.IsPrefab(_renderer), "Should never do editor updates for prefabs"); _renderer.validateSpaceComponent(); bool needsRebuild = false; using (new ProfilerSample("Calculate Should Rebuild")) { foreach (var group in _renderer._groups) { #if UNITY_EDITOR if (!Application.isPlaying) { group.editor.ValidateGraphicList(); } #endif foreach (var graphic in group.graphics) { if (graphic.isRepresentationDirty) { needsRebuild = true; break; } } foreach (var feature in group.features) { if (feature.isDirty) { needsRebuild = true; break; } } } Hash hierarchyHash = Hash.GetHierarchyHash(_renderer.transform); if (_renderer._space != null) { hierarchyHash.Add(_renderer._space.GetSettingHash()); } if (_previousHierarchyHash != hierarchyHash) { _previousHierarchyHash = hierarchyHash; needsRebuild = true; } } DoEditorUpdateLogic(needsRebuild); }
public static string RegisterPort(string id, Type port) { id = InternalUtility.Validate(id, "Port Type", $"[{port}]", true); if (PortTypes.ContainsKey(id)) { return(null); } port.PortId = id; PortTypes.Add(id, port); return(id); }
private static void RegisterExpressionListener(Type pathfinderEventType, ListenerObject listenerObj) { InternalUtility.ValidateNoId("Event Listener", listenerObj.Options.DebugName, $" with priority {listenerObj.Options.Priority}"); if (!eventListeners.ContainsKey(pathfinderEventType)) { eventListeners.Add(pathfinderEventType, new List <ListenerObject>()); } var list = eventListeners[pathfinderEventType]; list.Add(listenerObj); list.Sort((x, y) => y.Options.Priority - x.Options.Priority); }
public void DoEditorUpdateLogic(bool fullRebuild) { Undo.RecordObject(_renderer, "Do Editor Update Logic"); Assert.IsFalse(InternalUtility.IsPrefab(_renderer), "Should never do editor updates for prefabs"); using (new ProfilerSample("Validate Space Component")) { _renderer.validateSpaceComponent(); } if (fullRebuild) { if (_renderer._space != null) { using (new ProfilerSample("Rebuild Space")) { _renderer._space.RebuildHierarchy(); _renderer._space.RecalculateTransformers(); } } using (new ProfilerSample("Validate graphics")) { validateGraphics(); } foreach (var group in _renderer._groups) { using (new ProfilerSample("Validate Graphic List")) { group.editor.ValidateGraphicList(); } using (new ProfilerSample("Rebuild Feature Data")) { group.RebuildFeatureData(); } using (new ProfilerSample("Rebuild Feature Support Info")) { group.RebuildFeatureSupportInfo(); } using (new ProfilerSample("Update Renderer Editor")) { group.editor.UpdateRendererEditor(); } } } using (new ProfilerSample("Update Renderer")) { foreach (var group in _renderer._groups) { group.UpdateRenderer(); } } Undo.CollapseUndoOperations(Undo.GetCurrentGroup()); }
static void SetIsTrigger(bool val, GameObject target) { Collider[] colliders = InternalUtility.GetComponents <Collider>(target); foreach (Collider col in colliders) { if (val && col is MeshCollider) { ((MeshCollider)col).convex = true; } col.isTrigger = val; } }
private void OnValidate() { #if UNITY_EDITOR if (!InternalUtility.IsPrefab(this)) { if (!Application.isPlaying) { editor.ScheduleRebuild(); } editor.OnValidate(); } #endif }
public override ProBuilderMesh Build(bool isPreview = false) { var positions = InternalUtility.StringToVector3Array(verts); if (positions.Length % 4 == 0) { return(ProBuilderMesh.CreateInstanceWithPoints( InternalUtility.StringToVector3Array(verts) )); } return(ProBuilderMesh.Create()); }
Bounds OnGetFrameBounds() { if (!ProBuilderEditor.selectMode.IsMeshElementMode()) { return(m_MeshRenderer != null ? m_MeshRenderer.bounds : default(Bounds)); } if (onGetFrameBoundsEvent != null) { onGetFrameBoundsEvent(); } Vector3 min = Vector3.zero, max = Vector3.zero; bool init = false; foreach (ProBuilderMesh mesh in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms)) { int[] tris = mesh.selectedIndexesInternal; if (tris == null || tris.Length < 1) { continue; } Vector3[] verts = mesh.positionsInternal; var trs = mesh.transform; if (!init) { init = true; min = trs.TransformPoint(verts[tris[0]]); max = trs.TransformPoint(verts[tris[0]]); } for (int i = 0, c = tris.Length; i < c; i++) { Vector3 p = trs.TransformPoint(verts[tris[i]]); min.x = Mathf.Min(p.x, min.x); max.x = Mathf.Max(p.x, max.x); min.y = Mathf.Min(p.y, min.y); max.y = Mathf.Max(p.y, max.y); min.z = Mathf.Min(p.z, min.z); max.z = Mathf.Max(p.z, max.z); } } return(new Bounds((min + max) / 2f, max != min ? max - min : Vector3.one * .1f)); }
/// <summary> /// Adds an executable interface by id. /// </summary> /// <returns>The full mod id if added to the game, <c>null</c> otherwise.</returns> /// <param name="id">The Executable Identifier to try and add.</param> /// <param name="inter">The interface object.</param> public static string RegisterExecutable(string id, Interface inter) { id = InternalUtility.Validate(id, "Executable Interface", inter.GetType().FullName, true); if (ModExecutables.ContainsKey(id)) { return(null); } var type = inter.GetType(); var fileData = GenerateFileDataString(type.Assembly.GetName().Name, type.FullName, id); if (fileData.Length < 1 || ModExecutables.Any(pair => pair.Value.Item2 == fileData)) { throw new ArgumentException("created data for '" + id + "' is not unique"); } ModExecutables.Add(id, new Tuple <Interface, string>(inter, fileData)); return(id); }
public static void MenuRemoveDegenerateTriangles() { int count = 0; foreach (ProBuilderMesh pb in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms)) { int removedVertexCount; if (!MeshValidation.EnsureMeshIsValid(pb, out removedVertexCount)) { pb.Rebuild(); pb.Optimize(); count += removedVertexCount; } } EditorUtility.ShowNotification("Removed " + count + " vertices \nbelonging to degenerate triangles."); }
public static void MenuRemoveDegenerateTriangles() { int count = 0; foreach (ProBuilderMesh pb in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms)) { pb.ToMesh(); int[] rm = pb.RemoveDegenerateTriangles(); count += rm != null ? rm.Length : 0; pb.ToMesh(); pb.Refresh(); pb.Optimize(); } EditorUtility.ShowNotification("Removed " + (count / 3) + " degenerate triangles."); }
private void LateUpdate() { #if UNITY_EDITOR //No updates for prefabs! if (InternalUtility.IsPrefab(this)) { return; } if (!Application.isPlaying) { editor.DoLateUpdateEditor(); } else #endif { doLateUpdateRuntime(); } }
public void OnValidate() { Assert.IsFalse(InternalUtility.IsPrefab(_renderer), "Should never run editor validation on a prefab"); for (int i = _renderer._groups.Count; i-- > 0;) { if (_renderer._groups[i] == null) { _renderer._groups.RemoveAt(i); } } _renderer.validateSpaceComponent(); foreach (var group in _renderer._groups) { group.editor.OnValidate(); } }
void StubCodeAndSave(string assetPath, string allScript, string stubCode) { var ioPath = Application.dataPath.Replace("Assets", "") + assetPath; var lastIndex = allScript.LastIndexOf("}"); var text = allScript.Substring(0, lastIndex); var sb = new StringBuilder(); sb.Append(text); sb.AppendLine(""); var line = sb.ToString().Split('\n').Length; sb.AppendLine(stubCode); sb.AppendLine("}"); var script = sb.ToString(); SaveWindowScript(assetPath, script); InternalUtility.OpenFileOnSpecificLineAndColumn(ioPath, line, 0); }
/// <summary> /// Older versions of probuilder stored a fixed size array of colors in EditorPrefs. Use this function to get a /// pb_ColorPalette from the older version. /// </summary> /// <returns> /// </returns> static void CopyColorsFromEditorPrefs(ColorPalette target) { List <Color> colors = new List <Color>(); for (int i = 0; i < k_EditorPrefsColorPaletteCount; i++) { Color color = Color.white; if (InternalUtility.TryParseColor(EditorPrefs.GetString(pbVertexColorPrefs + i), ref color)) { colors.Add(color); } } if (colors.Count > 0) { target.SetColors(colors); UnityEditor.EditorUtility.SetDirty(target); } }
/// <summary> /// Reparent tile game objects into world space so that their transforms can be /// maintained when they are placed into their new chunks. /// </summary> /// <param name="map">New tile map.</param> private void ReparentTileGameObjectsIntoWorldSpace(TileData[,] map) { int mapRows = map.GetLength(0); int mapColumns = map.GetLength(1); for (int row = 0; row < mapRows; ++row) { this.taskProgress += this.taskIncrement; InternalUtility.ProgressHandler("Rebuilding Tile System", "Clearing existing chunks.", this.taskProgress); for (int column = 0; column < mapColumns; ++column) { var tile = map[row, column]; if (tile == null || tile.Empty || tile.gameObject == null) { continue; } tile.gameObject.transform.SetParent(null); } } }
public static string RegisterExtension(string id, Info extensionInfo) { id = InternalUtility.Validate(id, "Extension", extensionInfo.GetType().FullName, true, true); if (ModExtensions.ContainsKey(id)) { return(null); } extensionInfo.Id = id; Texture2D t = null; if (File.Exists(extensionInfo.LogoPath)) { using (var fs = File.OpenRead(extensionInfo.LogoPath)) t = Texture2D.FromStream(Game1.getSingleton().GraphicsDevice, fs); } ModExtensions.Add(id, new Tuple <Info, Texture2D, GUI.Button>(extensionInfo, t, new GUI.Button(-1, -1, 450, 50, Utility.ActiveModId + ": " + extensionInfo.Name, Color.White))); return(id); }
protected virtual void OnDisable() { #if UNITY_EDITOR if (InternalUtility.IsPrefab(this)) { return; } if (Application.isPlaying) { #endif if (isAttachedToGroup) { attachedGroup.TryRemoveGraphic(this); } else if (_willBeAttached) { _groupToBeAttachedTo.TryRemoveGraphic(this); } #if UNITY_EDITOR } #endif }