/// <summary> /// Renders two buttons named "Previous" and "Next". The /// "Previous" button isn't rendered in the first window. /// If button "Previous" is pressed, PrevWindow() is called. /// If button "Next" is pressed (or acceptEnterAsNext == true /// && key enter is released), NextWindow() is called. /// </summary> /// <param name="acceptEnterAsNext">True to accept key "enter" to behave button "Next" is pressed.</param> public void PrevNextButtons(bool acceptEnterAsNext = false) { bool buttonPrevPressed = false; bool buttonNextPressed = false; bool keyEnterIsReleased = acceptEnterAsNext && Event.current != null && Event.current.isKey && Event.current.type == EventType.KeyUp && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter); GUILayout.BeginHorizontal(); { // Disable button "Previous" if we're in the first window. EditorGUI.BeginDisabledGroup(CurrentWindow == 0); { buttonPrevPressed = GUILayout.Button(GUI.MakeLabel("Previous"), GUI.Skin.button); } EditorGUI.EndDisabledGroup(); buttonNextPressed = GUILayout.Button(GUI.MakeLabel("Next"), GUI.Skin.button); } GUILayout.EndHorizontal(); if (buttonPrevPressed) { PrevWindow(); } else if (buttonNextPressed || keyEnterIsReleased) { NextWindow(); } }
public static object DeformableTerrainShovelExcavationSettingsDrawer(object[] objects, InvokeWrapper wrapper) { var data = new ExcavationSettingsResult() { Value = wrapper.Get <DeformableTerrainShovelSettings.ExcavationSettings>(objects[0]) }; if (InspectorGUI.Foldout(EditorData.Instance.GetData(objects[0] as Object, wrapper.Member.Name), InspectorGUI.MakeLabel(wrapper.Member))) { using (InspectorGUI.IndentScope.Single) { data.Value.Enabled = InspectorGUI.Toggle(GUI.MakeLabel("Enabled"), data.Value.Enabled); data.EnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; data.Value.CreateDynamicMassEnabled = InspectorGUI.Toggle(GUI.MakeLabel("Create Dynamic Mass Enabled"), data.Value.CreateDynamicMassEnabled); data.CreateDynamicMassEnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; data.Value.ForceFeedbackEnabled = InspectorGUI.Toggle(GUI.MakeLabel("Force Feedback Enabled"), data.Value.ForceFeedbackEnabled); data.ForceFeedbackEnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; } UnityEngine.GUI.changed = data.ContainsChanges; } return(data); }
public override void OnPostTargetMembersGUI() { var skin = InspectorEditor.Skin; var beginWinches = GetTargets <Wire, WireWinch>(wire => wire.BeginWinch).Where(winch => winch != null); var endWinches = GetTargets <Wire, WireWinch>(wire => wire.EndWinch).Where(winch => winch != null); if (beginWinches.Count() > 0) { GUILayout.Label(GUI.MakeLabel("Begin winch", true), skin.Label); using (InspectorGUI.IndentScope.Single) { if (beginWinches.Count() != NumTargets) { InspectorGUI.WarningLabel("Not all selected wires has a begin winch."); } InspectorEditor.DrawMembersGUI(beginWinches.ToArray()); } } if (endWinches.Count() > 0) { GUILayout.Label(GUI.MakeLabel("End winch", true), skin.Label); using (InspectorGUI.IndentScope.Single) { if (endWinches.Count() != NumTargets) { InspectorGUI.WarningLabel("Not all selected wires has an end winch."); } InspectorEditor.DrawMembersGUI(endWinches.ToArray()); } } }
private Tuple <PropertyWrapper, CableProperties.Direction, object> OnPropertyGUI(CableProperties.Direction dir, CableProperties properties) { Tuple <PropertyWrapper, CableProperties.Direction, object> changed = null; var data = EditorData.Instance.GetData(properties, "CableProperty" + dir.ToString()); if (InspectorGUI.Foldout(data, GUI.MakeLabel(dir.ToString()))) { using (InspectorGUI.IndentScope.Single) { var wrappers = PropertyWrapper.FindProperties <CableProperty>(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); foreach (var wrapper in wrappers) { if (wrapper.GetContainingType() == typeof(float) && InspectorEditor.ShouldBeShownInInspector(wrapper.Member)) { var value = EditorGUILayout.FloatField(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <float>(properties[dir])); if (UnityEngine.GUI.changed) { changed = new Tuple <PropertyWrapper, CableProperties.Direction, object>(wrapper, dir, value); UnityEngine.GUI.changed = false; } } } } } return(changed); }
protected override void OnPreFrameGUI(CableRouteNode node) { using (InspectorGUI.IndentScope.Single) { node.Type = (Cable.NodeType)EditorGUILayout.EnumPopup(GUI.MakeLabel("Type"), node.Type, InspectorEditor.Skin.Popup); } }
public static void DrawUrdfPose(AGXUnity.IO.URDF.Pose pose) { EditorGUILayout.PrefixLabel(GUI.MakeLabel("Origin", true)); using (new InspectorGUI.IndentScope()) { InspectorGUI.Vector3Field(GUI.MakeLabel("Position"), pose.Xyz); InspectorGUI.Vector3Field(GUI.MakeLabel("Roll, Pitch, Yaw"), pose.Rpy, "R,P,Y"); } }
public static void DrawUrdfPose(AGXUnity.IO.URDF.Pose pose) { UnityEngine.GUI.Label(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), GUI.MakeLabel("Origin", true), InspectorEditor.Skin.Label); using (new InspectorGUI.IndentScope()) { InspectorGUI.Vector3Field(GUI.MakeLabel("Position"), pose.Xyz); InspectorGUI.Vector3Field(GUI.MakeLabel("Roll, Pitch, Yaw"), pose.Rpy, "R,P,Y"); } }
private void OnShapeConfigGUI(bool hasRadius) { using (InspectorGUI.IndentScope.Create(2)) { State.ShapeAsParent = InspectorGUI.Toggle(GUI.MakeLabel("Shape as parent"), State.ShapeAsParent); if (hasRadius) { State.ExpandRadius = InspectorGUI.Toggle(GUI.MakeLabel("Expand radius"), State.ExpandRadius); } } }
public static Constraint.ESolveType ConstraintSolveTypeGUI(Constraint.ESolveType solveType) { // Matching with disable buttons above where each button is 76. var position = EditorGUILayout.GetControlRect(GUILayout.Width(EditorGUIUtility.labelWidth + 2.0f * 76.0f)); solveType = (Constraint.ESolveType)EditorGUI.EnumPopup(position, GUI.MakeLabel("Solve Type", true), solveType, InspectorEditor.Skin.Popup); return(solveType); }
private void MeshStatisticsGUI() { if (IsMultiSelect || Mesh.PrecomputedCollisionMeshes.Length == 0) { return; } EditorGUILayout.Space(); InspectorGUI.BrandSeparator(); var numCollisionMeshes = Mesh.PrecomputedCollisionMeshes.Length; var totNumVertices = Mesh.PrecomputedCollisionMeshes.Select(collisionMesh => collisionMesh.Vertices.Length).Sum(); var totNumTriangles = Mesh.PrecomputedCollisionMeshes.Select(collisionMesh => collisionMesh.Indices.Length).Sum() / 3; var meshPlural = numCollisionMeshes > 1 ? "es" : string.Empty; var summaryString = $"Summary ({numCollisionMeshes} mesh{meshPlural}, {totNumTriangles} triangles, {totNumVertices} vertices)"; if (InspectorGUI.Foldout(GetMeshStatisticsEditorData(Mesh), GUI.MakeLabel(summaryString))) { InspectorGUI.Separator(); EditorGUILayout.LabelField(GUI.MakeLabel("Number of meshes"), GUI.MakeLabel(Mesh.PrecomputedCollisionMeshes.Length.ToString(), Color.green), InspectorEditor.Skin.TextField); using (InspectorGUI.IndentScope.Single) { InspectorGUI.Separator(); for (int i = 0; i < Mesh.PrecomputedCollisionMeshes.Length; ++i) { var numVertices = Mesh.PrecomputedCollisionMeshes[i].Vertices.Length; var numTriangles = Mesh.PrecomputedCollisionMeshes[i].Indices.Length / 3; EditorGUILayout.LabelField(GUI.MakeLabel($"[{i}] Number of triangles (vertices)"), GUI.MakeLabel($"{numTriangles.ToString().Color( InspectorGUISkin.BrandColorBlue )} ({numVertices.ToString()})"), InspectorEditor.Skin.TextField); } InspectorGUI.Separator(); } var totNumTrianglesString = totNumTriangles.ToString().Color(InspectorGUISkin.BrandColorBlue); var hasReducedNumTriangles = Mesh.Options != null && (Mesh.Options.Mode != AGXUnity.Collide.CollisionMeshOptions.MeshMode.Trimesh || Mesh.Options.ReductionEnabled); if (hasReducedNumTriangles) { totNumTrianglesString += $" (originally: {Mesh.SourceObjects.Select( source => source.triangles.Length / 3 ).Sum().ToString().Color( Color.red )})"; } EditorGUILayout.LabelField(GUI.MakeLabel("Total number of triangles"), GUI.MakeLabel(totNumTrianglesString), InspectorEditor.Skin.TextField); } }
public static void ShapeMeshSourceGUI(Mesh currentSource, System.Action <Mesh> onNewMesh) { using (new GUI.EnabledBlock(UnityEngine.GUI.enabled && !EditorApplication.isPlayingOrWillChangePlaymode)) { var newSource = EditorGUILayout.ObjectField(GUI.MakeLabel("Source"), currentSource, typeof(Mesh), false) as Mesh; if (newSource != currentSource) { onNewMesh?.Invoke(newSource); } } }
private void ShowForces(EventType eventType) { if (m_textLabelStyle == null) { m_textLabelStyle = new GUIStyle(GUI.Skin.label); m_textLabelStyle.alignment = TextAnchor.MiddleLeft; var fonts = Font.GetOSInstalledFontNames(); foreach (var font in fonts) { if (font == "Consolas") { m_textLabelStyle.font = Font.CreateDynamicFontFromOSFont(font, 24); break; } } } var textColor = Color.Lerp(Color.black, Color.white, 1.0f); var valueColor = Color.Lerp(Color.green, Color.white, 0.45f); Func <string, agx.Vec3, GUIContent> Vec3Content = (name, v) => { return(GUI.MakeLabel(string.Format("{0} [{1}, {2}, {3}] kN", GUI.AddColorTag(name, textColor), GUI.AddColorTag(v.x.ToString("0.00").PadLeft(7, ' '), valueColor), GUI.AddColorTag(v.y.ToString("0.00").PadLeft(7, ' '), valueColor), GUI.AddColorTag(v.z.ToString("0.00").PadLeft(7, ' '), valueColor)))); }; var shovel = m_shovels[0].Native; var penetrationForce = new agx.Vec3(); var penetrationTorque = new agx.Vec3(); Native.getPenetrationForce(shovel, ref penetrationForce, ref penetrationTorque); var separationForce = -Native.getSeparationContactForce(shovel); var deformerForce = -Native.getDeformationContactForce(shovel); var contactForce = -Native.getContactForce(shovel); GUILayout.Label(Vec3Content("Penetration force:", 1.0E-3 * penetrationForce), m_textLabelStyle); GUILayout.Space(4); GUILayout.Label(Vec3Content("Separation force: ", 1.0E-3 * separationForce), m_textLabelStyle); GUILayout.Space(4); GUILayout.Label(Vec3Content("Deformer force: ", 1.0E-3 * deformerForce), m_textLabelStyle); GUILayout.Space(4); GUILayout.Label(Vec3Content("Contact force: ", 1.0E-3 * contactForce), m_textLabelStyle); }
public static void DrawUrdfMaterial(AGXUnity.IO.URDF.Material material) { // Name has already been rendered. InspectorGUI.Toggle(GUI.MakeLabel("Is Reference"), material.IsReference); if (material.IsReference) { return; } var colorRect = EditorGUILayout.GetControlRect(); EditorGUI.PrefixLabel(colorRect, GUI.MakeLabel("Color")); var oldXMax = colorRect.xMax; colorRect.x += EditorGUIUtility.labelWidth; colorRect.xMax = oldXMax; EditorGUI.DrawRect(colorRect, material.Color); }
public static Constraint.ECollisionsState ConstraintCollisionsStateGUI(Constraint.ECollisionsState state) { var skin = InspectorEditor.Skin; var guiWasEnabled = UnityEngine.GUI.enabled; GUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel(GUI.MakeLabel("Disable Collisions", true), InspectorEditor.Skin.LabelMiddleLeft); UnityEngine.GUI.enabled = !EditorApplication.isPlaying; var rbVsRbActive = !EditorGUI.showMixedValue && state == Constraint.ECollisionsState.DisableRigidBody1VsRigidBody2; var refVsConActive = !EditorGUI.showMixedValue && state == Constraint.ECollisionsState.DisableReferenceVsConnected; if (GUILayout.Button(GUI.MakeLabel("Rb " + GUI.Symbols.ArrowLeftRight.ToString() + " Rb", rbVsRbActive, "Disable all shapes in rigid body 1 against all shapes in rigid body 2."), skin.GetButton(rbVsRbActive, InspectorGUISkin.ButtonType.Left), GUILayout.Width(76))) { state = state == Constraint.ECollisionsState.DisableRigidBody1VsRigidBody2 ? Constraint.ECollisionsState.KeepExternalState : Constraint.ECollisionsState.DisableRigidBody1VsRigidBody2; } if (GUILayout.Button(GUI.MakeLabel("Ref " + GUI.Symbols.ArrowLeftRight.ToString() + " Con", refVsConActive, "Disable Reference object vs. Connected object."), skin.GetButton(refVsConActive, InspectorGUISkin.ButtonType.Right), GUILayout.Width(76))) { state = state == Constraint.ECollisionsState.DisableReferenceVsConnected ? Constraint.ECollisionsState.KeepExternalState : Constraint.ECollisionsState.DisableReferenceVsConnected; } UnityEngine.GUI.enabled = guiWasEnabled; } GUILayout.EndHorizontal(); return(state); }
/// <returns>True when button is pressed.</returns> private bool OnButtonGUI(Rect rect, string name, InspectorGUISkin.ButtonType buttonType, Event current, Action onMouseOver) { using (InspectorGUI.IndentScope.Create(2)) { var down = UnityEngine.GUI.Button(rect, GUI.MakeLabel(name), InspectorEditor.Skin.GetButton(true, buttonType)); if (current.type == EventType.Repaint && rect.Contains(current.mousePosition)) { onMouseOver(); } return(down); } }
public void Update(InvokeWrapper wrapper, object targetInstance) { var foldoutBeginAttribute = wrapper.GetAttribute <InspectorGroupBeginAttribute>(); if (foldoutBeginAttribute != null || wrapper.HasAttribute <InspectorGroupEndAttribute>()) { End(); } if (foldoutBeginAttribute == null) { return; } var groupIdentifier = (targetInstance != null ? targetInstance.GetType().FullName : "null") + "_" + foldoutBeginAttribute.Name; Begin(!InspectorGUI.Foldout(EditorData.Instance.GetData(targetInstance as Object, groupIdentifier), GUI.MakeLabel(foldoutBeginAttribute.Name))); }
private static DefaultAndUserValueResult HandleDefaultAndUserValue <ValueT>(object[] objects, InvokeWrapper wrapper) where ValueT : struct { if (s_floatFieldMethod == null) { s_floatFieldMethod = typeof(EditorGUI).GetMethod("FloatField", new[] { typeof(Rect), typeof(string), typeof(float) }); } if (s_vector3FieldMethod == null) { s_vector3FieldMethod = typeof(EditorGUI).GetMethod("Vector3Field", new[] { typeof(Rect), typeof(string), typeof(Vector3) }); } var method = typeof(ValueT) == typeof(float) ? s_floatFieldMethod : typeof(ValueT) == typeof(Vector3) ? s_vector3FieldMethod : null; if (method == null) { throw new NullReferenceException("Unknown DefaultAndUserValue type: " + typeof(ValueT).Name); } var updateButtonWidth = 20.0f; var rect = EditorGUILayout.GetControlRect(); // Now we know the total width if the Inspector. Remove // width of button and right most spacing. rect.xMax -= updateButtonWidth; // We don't want the tooltip of the toggle to show when // hovering the update button or float field(s) so use // xMax as label width minus some magic number so that // e.g., Mass float field slider appears and works. var widthUntilButton = rect.xMax; rect.xMax = EditorGUIUtility.labelWidth - 28; // Result and reference instance. var result = new DefaultAndUserValueResult(); var instance = wrapper.Get <DefaultAndUserValue <ValueT> >(objects[0]); UnityEngine.GUI.changed = false; var hasMixedUseDefault = !CompareMulti <ValueT>(objects, wrapper, other => other.UseDefault == instance.UseDefault); EditorGUI.showMixedValue = hasMixedUseDefault; var toggleInput = hasMixedUseDefault ? false : instance.UseDefault; // During showMixedValue - Toggle will always return true (enabled) // when the user clicks regardless of instance.UseDefault. var toggleOutput = EditorGUI.ToggleLeft(rect, GUI.MakeLabel(wrapper.Member.Name.SplitCamelCase(), false, "If checked - value will be default. Uncheck to manually enter value."), toggleInput); if (toggleOutput != toggleInput) { result.DefaultToggleChanged = true; result.UseDefault = toggleOutput; } // Restore width and calculate new start of the float // field(s). Start is label width but we have to remove // the current indent level since label width is independent // of the indent level. Unsure why we have to add LayoutMagicNumber pixels... // could be float field(s) default minimum label size. rect.xMax = widthUntilButton; rect.x = EditorGUIUtility.labelWidth - InspectorGUI.IndentScope.PixelLevel + InspectorGUI.LayoutMagicNumber; rect.xMax += -rect.x + InspectorGUI.LayoutMagicNumber; s_fieldMethodArgs[0] = rect; s_fieldMethodArgs[2] = instance.Value; var newValue = default(ValueT); EditorGUI.showMixedValue = !CompareMulti <ValueT>(objects, wrapper, other => instance.Value.Equals(other.Value)); using (new GUI.EnabledBlock(!instance.UseDefault && !hasMixedUseDefault)) { EditorGUI.BeginChangeCheck(); newValue = (ValueT)method.Invoke(null, s_fieldMethodArgs); if (EditorGUI.EndChangeCheck()) { // Validate input here so that, e.g., 0 isn't propagated. It's // not possible to check this in the CopyOp callback. var clampAttribute = wrapper.GetAttribute <ClampAboveZeroInInspector>(); if (clampAttribute == null || clampAttribute.IsValid(newValue)) { result.OnChange <ValueT>(instance.Value, newValue); } } } rect.x = rect.xMax; rect.width = updateButtonWidth; rect.height = EditorGUIUtility.singleLineHeight - EditorGUIUtility.standardVerticalSpacing; result.UpdateDefaultClicked = InspectorGUI.Button(rect, MiscIcon.Update, instance.UseDefault, InspectorEditor.Skin.ButtonRight, "Force update of default value.", 1.2f); return(result); }
private void OnGUI() { ValidateLicenseDirectory(); using (GUI.AlignBlock.Center) GUILayout.Box(IconManager.GetAGXUnityLogo(), GUI.Skin.customStyles[3], GUILayout.Width(System.Math.Min(400.0f, position.width - 20.0f)), GUILayout.Height(100)); EditorGUILayout.LabelField("© " + System.DateTime.Now.Year + " Algoryx Simulation AB", InspectorEditor.Skin.LabelMiddleCenter); InspectorGUI.BrandSeparator(1, 6); m_scroll = EditorGUILayout.BeginScrollView(m_scroll); if (IsUpdatingLicenseInformation) { ShowNotification(GUI.MakeLabel("Reading...")); } else if (AGXUnity.LicenseManager.IsBusy) { ShowNotification(GUI.MakeLabel(AGXUnity.LicenseManager.IsActivating ? "Activating..." : "Refreshing...")); } using (new GUI.EnabledBlock(!IsUpdatingLicenseInformation && !AGXUnity.LicenseManager.IsBusy)) { for (int i = 0; i < m_licenseData.Count; ++i) { var data = m_licenseData[i]; LicenseDataGUI(data); if (i + 1 < m_licenseData.Count) { InspectorGUI.Separator(2, 6, InspectorGUISkin.BrandColorBlue); } } if (m_licenseData.Count > 0) { InspectorGUI.Separator(2, 6, InspectorGUISkin.BrandColorBlue); } ActivateLicenseGUI(); } InspectorGUI.BrandSeparator(1, 6); GUILayout.Label(GUI.MakeLabel("Online Documentation", true), InspectorEditor.Skin.Label); if (InspectorGUI.Link(GUI.MakeLabel("License Manager", false, s_licenseManagerUrl))) { Application.OpenURL(s_licenseManagerUrl); } if (InspectorGUI.Link(GUI.MakeLabel("Licensing AGX Dynamics for Unity", false, s_licensingUrl))) { Application.OpenURL(s_licensingUrl); } if (InspectorGUI.Link(GUI.MakeLabel("Free Trial", false, s_freeTrialUrl))) { Application.OpenURL(s_freeTrialUrl); } EditorGUILayout.EndScrollView(); if (AGXUnity.LicenseManager.IsBusy || IsUpdatingLicenseInformation) { Repaint(); } }
private void LicenseDataGUI(LicenseData data) { var highlight = m_licenseData.Count > 1 && !IsUpdatingLicenseInformation && !AGXUnity.LicenseManager.IsBusy && data.LicenseInfo.UniqueId == AGXUnity.LicenseManager.LicenseInfo.UniqueId; if (highlight && m_activeLicenseStyle == null) { m_activeLicenseStyle = new GUIStyle(InspectorEditor.Skin.Label); } // The texture is deleted when hitting stop in the editor while // m_activeLicenseStyle != null. if (m_activeLicenseStyle != null && m_activeLicenseStyle.normal.background == null) { m_activeLicenseStyle.normal.background = GUI.CreateColoredTexture(1, 1, Color.Lerp(InspectorGUI.BackgroundColor, Color.green, 0.025f)); } var licenseFileButtons = new InspectorGUI.MiscButtonData[] { InspectorGUI.MiscButtonData.Create(MiscIcon.Update, () => { RefreshLicense(data); }, UnityEngine.GUI.enabled && data.LicenseInfo.Type == AGXUnity.LicenseInfo.LicenseType.Service, "Refresh license from server."), InspectorGUI.MiscButtonData.Create(MiscIcon.EntryRemove, () => { var deactivateDelete = EditorUtility.DisplayDialog("Deactivate and erase license.", "Would you like to deactivate the current license " + "and remove the license file from this project?\n\n" + "It's possible to activate the license again in this " + "License Manager and/or download the license file again " + "from the license portal.", "Yes", "Cancel"); if (deactivateDelete) { AGXUnity.LicenseManager.DeactivateAndDelete(data.Filename); StartUpdateLicenseInformation(); } }, UnityEngine.GUI.enabled, "Deactivate and erase license file from project.") }; var highlightScope = highlight ? new EditorGUILayout.VerticalScope(m_activeLicenseStyle) : null; InspectorGUI.SelectableTextField(GUI.MakeLabel("License file"), data.Filename, licenseFileButtons); InspectorGUI.SelectableTextField(GUI.MakeLabel("License type"), data.LicenseInfo.TypeDescription); InspectorGUI.Separator(1, 6); InspectorGUI.LicenseEndDateField(data.LicenseInfo); EditorGUILayout.EnumFlagsField(GUI.MakeLabel("Enabled modules", false, data.LicenseInfo.EnabledModules.ToString()), data.LicenseInfo.AllModulesEnabled ? AGXUnity.LicenseInfo.Module.All : data.LicenseInfo.EnabledModules, false, InspectorEditor.Skin.Popup); InspectorGUI.SelectableTextField(GUI.MakeLabel("User"), data.LicenseInfo.User); InspectorGUI.SelectableTextField(GUI.MakeLabel("Contact"), data.LicenseInfo.Contact); highlightScope?.Dispose(); }
private void ActivateLicenseGUI() { GUILayout.Label(GUI.MakeLabel("Activate license", true), InspectorEditor.Skin.Label); var selectLicenseRect = GUILayoutUtility.GetLastRect(); selectLicenseRect.x += selectLicenseRect.width; selectLicenseRect.width = 28; selectLicenseRect.x -= selectLicenseRect.width; selectLicenseRect.y -= EditorGUIUtility.standardVerticalSpacing; var selectLicensePressed = InspectorGUI.Button(selectLicenseRect, MiscIcon.Locate, UnityEngine.GUI.enabled, "Select license file on this computer", 1.25f); if (selectLicensePressed) { var sourceLicense = EditorUtility.OpenFilePanel("Copy AGX Dynamics license file", ".", $"{AGXUnity.LicenseManager.GetLicenseExtension( AGXUnity.LicenseInfo.LicenseType.Service ).Remove( 0, 1 )}," + $"{AGXUnity.LicenseManager.GetLicenseExtension( AGXUnity.LicenseInfo.LicenseType.Legacy ).Remove( 0, 1 )}"); if (!string.IsNullOrEmpty(sourceLicense)) { var targetLicense = AGXUnity.IO.Environment.FindUniqueFilename($"{LicenseDirectory}/{Path.GetFileName( sourceLicense )}").PrettyPath(); if (EditorUtility.DisplayDialog("Copy AGX Dynamics license", $"Copy \"{sourceLicense}\" to \"{targetLicense}\"?", "Yes", "Cancel")) { try { File.Copy(sourceLicense, targetLicense, false); StartUpdateLicenseInformation(); GUIUtility.ExitGUI(); } catch (ExitGUIException) { throw; } catch (System.Exception e) { Debug.LogException(e); } } } } using (InspectorGUI.IndentScope.Single) { m_licenseActivateData.Id = EditorGUILayout.TextField(GUI.MakeLabel("License Id"), m_licenseActivateData.Id, InspectorEditor.Skin.TextField); if (m_licenseActivateData.Id.Any(c => !char.IsDigit(c))) { m_licenseActivateData.Id = new string( m_licenseActivateData.Id.Where(c => char.IsDigit(c)).ToArray()); } m_licenseActivateData.Password = EditorGUILayout.PasswordField(GUI.MakeLabel("Activation Code"), m_licenseActivateData.Password); InspectorGUI.SelectFolder(GUI.MakeLabel("License File Directory"), LicenseDirectory, "License file directory", newDirectory => { newDirectory = newDirectory.PrettyPath(); if (string.IsNullOrEmpty(newDirectory)) { newDirectory = "Assets"; } if (!Directory.Exists(newDirectory)) { Debug.LogWarning($"Invalid license directory: {newDirectory} - directory doesn't exist."); return; } else if (!IO.Utils.IsValidProjectFolder(newDirectory)) { Debug.LogWarning($"Invalid license directory: {newDirectory} - directory has to be in the project."); return; } LicenseDirectory = newDirectory; }); using (new GUI.EnabledBlock(UnityEngine.GUI.enabled && m_licenseActivateData.Id.Length > 0 && m_licenseActivateData.Password.Length > 0)) { // It isn't possible to press this button during activation. if (UnityEngine.GUI.Button(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), GUI.MakeLabel(AGXUnity.LicenseManager.IsBusy ? "Activating..." : "Activate"), InspectorEditor.Skin.Button)) { AGXUnity.LicenseManager.ActivateAsync(System.Convert.ToInt32(m_licenseActivateData.Id), m_licenseActivateData.Password, LicenseDirectory, success => { if (success) { m_licenseActivateData = IdPassword.Empty(); } else { Debug.LogError("License Error: ".Color(Color.red) + AGXUnity.LicenseManager.LicenseInfo.Status); } StartUpdateLicenseInformation(); UnityEngine.GUI.FocusControl(""); }); } } } }
public static void DrawUrdfElement(AGXUnity.IO.URDF.Element element, int elementArrayIndex = -1) { if (element == null) { return; } var dropDownName = string.IsNullOrEmpty(element.Name) ? elementArrayIndex >= 0 ? $"{element.GetType().Name}[{elementArrayIndex}]" : element.GetType().Name : element.Name; if (!InspectorGUI.Foldout(GetEditorData(element, dropDownName), GUI.MakeLabel(InspectorGUISkin.Instance.TagTypename($"Urdf.{element.GetType().Name}") + ' ' + dropDownName))) { return; } using (InspectorGUI.IndentScope.Single) { var ignoreName = element is AGXUnity.IO.URDF.Inertial; if (!ignoreName) { var nameRect = EditorGUILayout.GetControlRect(); EditorGUI.PrefixLabel(nameRect, GUI.MakeLabel("Name"), InspectorEditor.Skin.Label); var orgXMax = nameRect.xMax; nameRect.x += EditorGUIUtility.labelWidth - 14.0f * InspectorGUI.IndentScope.Level; nameRect.xMax = orgXMax; EditorGUI.SelectableLabel(nameRect, element.Name, InspectorEditor.Skin.TextField); } if (element is AGXUnity.IO.URDF.Pose) { DrawUrdfPose(element as AGXUnity.IO.URDF.Pose); } else if (element is AGXUnity.IO.URDF.Material) { DrawUrdfMaterial(element as AGXUnity.IO.URDF.Material); return; } var properties = GetOrFindProperties(element.GetType()); var elementArg = new object[] { element }; var geometry = element as AGXUnity.IO.URDF.Geometry; foreach (var property in properties) { // Ignoring Unity specific properties such as "name" and "hideFlags". if (!char.IsUpper(property.Member.Name[0])) { continue; } if (!InspectorEditor.ShouldBeShownInInspector(property.Member)) { continue; } var containingType = property.GetContainingType(); if (containingType.IsArray) { if (typeof(AGXUnity.IO.URDF.Element).IsAssignableFrom(containingType.GetElementType())) { var array = property.Get <System.Collections.ICollection>(element); if (!InspectorGUI.Foldout(GetEditorData(element, property.Member.Name), InspectorGUI.MakeLabel(property.Member, $" [{array.Count}]"))) { continue; } using (InspectorGUI.IndentScope.Single) { var arrayIndex = 0; foreach (var arrayItem in array) { DrawUrdfElement(arrayItem as AGXUnity.IO.URDF.Element, arrayIndex++); } } } } else if (typeof(AGXUnity.IO.URDF.Element).IsAssignableFrom(containingType)) { DrawUrdfElement(property.Get <AGXUnity.IO.URDF.Element>(element), -1); } else if (geometry == null || IsValidGeometryProperty(geometry, property)) { var drawerMethod = GetDrawerMethod(containingType); drawerMethod.Drawer?.Invoke(null, new object[] { elementArg, property }); } } } }
public override void OnPreTargetMembersGUI() { var skin = InspectorEditor.Skin; var constraints = GetTargets <Constraint>().ToArray(); var refConstraint = constraints[0]; var differentTypes = false; var anyUnknownType = constraints.Any(c => c.Type == ConstraintType.Unknown); for (int i = 1; i < constraints.Length; ++i) { differentTypes = differentTypes || refConstraint.Type != constraints[i].Type; } // Render AttachmentPair GUI. ConstraintAttachmentFrameTool.OnPreTargetMembersGUI(); Undo.RecordObjects(constraints, "ConstraintTool"); UnityEngine.GUI.changed = false; // The constraint type is Unknown when, e.g., go.AddComponent<Constraint>() // or when the constraint has been reset. If any of the selected constraints // is of type Unknown, we exit the GUI here. if (!ConstraintTypeGUI(constraints, differentTypes)) { return; } EditorGUI.showMixedValue = constraints.Any(constraint => refConstraint.CollisionsState != constraint.CollisionsState); var collisionsState = ConstraintCollisionsStateGUI(refConstraint.CollisionsState); EditorGUI.showMixedValue = false; if (UnityEngine.GUI.changed) { foreach (var constraint in constraints) { constraint.CollisionsState = collisionsState; } UnityEngine.GUI.changed = false; } EditorGUI.showMixedValue = constraints.Any(constraint => refConstraint.SolveType != constraint.SolveType); var solveType = ConstraintSolveTypeGUI(refConstraint.SolveType); EditorGUI.showMixedValue = false; if (UnityEngine.GUI.changed) { foreach (var constraint in constraints) { constraint.SolveType = solveType; } UnityEngine.GUI.changed = false; } EditorGUI.showMixedValue = constraints.Any(constraint => refConstraint.ConnectedFrameNativeSyncEnabled != constraint.ConnectedFrameNativeSyncEnabled); var frameNativeSync = ConstraintConnectedFrameSyncGUI(refConstraint.ConnectedFrameNativeSyncEnabled); EditorGUI.showMixedValue = false; if (UnityEngine.GUI.changed) { foreach (var constraint in constraints) { constraint.ConnectedFrameNativeSyncEnabled = frameNativeSync; } UnityEngine.GUI.changed = false; } if (differentTypes) { InspectorGUI.WarningLabel("Constraints are of different types.\nRow data editing not supported."); return; } Func <string, EditorDataEntry> selected = (id) => { return(EditorData.Instance.GetData(refConstraint, id, entry => entry.Bool = false)); }; var constraintsParser = (from constraint in constraints select ConstraintUtils.ConstraintRowParser.Create(constraint)).ToArray(); var allElementaryConstraints = constraints.SelectMany(constraint => constraint.GetOrdinaryElementaryConstraints()).ToArray(); Undo.RecordObjects(allElementaryConstraints, "ConstraintTool"); var ecRowDataWrappers = InvokeWrapper.FindFieldsAndProperties <ElementaryConstraintRowData>(); foreach (ConstraintUtils.ConstraintRowParser.RowType rowType in Enum.GetValues(typeof(ConstraintUtils.ConstraintRowParser.RowType))) { if (!InspectorGUI.Foldout(selected("ec_" + rowType.ToString()), GUI.MakeLabel(rowType.ToString() + " properties", true))) { continue; } using (InspectorGUI.IndentScope.Single) { var refTransOrRotRowData = constraintsParser[0][rowType]; foreach (var wrapper in ecRowDataWrappers) { if (!InspectorEditor.ShouldBeShownInInspector(wrapper.Member)) { continue; } for (int i = 0; i < 3; ++i) { var rowDataInstances = (from constraintParser in constraintsParser where constraintParser[rowType][i] != null select constraintParser[rowType][i].RowData).ToArray(); using (new GUI.EnabledBlock(refTransOrRotRowData[i] != null)) { var labelContent = i == 0 ? InspectorGUI.MakeLabel(wrapper.Member) : null; var fieldContent = GUI.MakeLabel(RowLabels[i], RowColors[i]); if (wrapper.IsType <float>()) { EditorGUI.showMixedValue = !wrapper.AreValuesEqual(rowDataInstances); var value = InspectorGUI.CustomFloatField(labelContent, fieldContent, wrapper.Get <float>(refTransOrRotRowData[i]?.RowData)); if (UnityEngine.GUI.changed) { foreach (var constraintParser in constraintsParser) { wrapper.ConditionalSet(constraintParser[rowType][i]?.RowData, value); } } } else if (wrapper.IsType <RangeReal>()) { EditorGUI.showMixedValue = rowDataInstances.Any(rowData => !Equals(wrapper.Get <RangeReal>(refTransOrRotRowData[i]?.RowData).Min, wrapper.Get <RangeReal>(rowData).Min)) || rowDataInstances.Any(rowData => !Equals(wrapper.Get <RangeReal>(refTransOrRotRowData[i]?.RowData).Max, wrapper.Get <RangeReal>(rowData).Max)); var rangeChangeData = InspectorGUI.RangeRealField(labelContent, wrapper.Get <RangeReal>(refTransOrRotRowData[i]?.RowData), GUI.MakeLabel(RowLabels[i], RowColors[i])); if (rangeChangeData.MinChanged || rangeChangeData.MaxChanged) { foreach (var constraintParser in constraintsParser) { var range = wrapper.Get <RangeReal>(constraintParser[rowType][i].RowData); if (rangeChangeData.MinChanged) { range.Min = rangeChangeData.Min; } if (rangeChangeData.MaxChanged) { range.Max = rangeChangeData.Max; } // Validation of Min > Max has to go somewhere else because if e.g., // Min = 50 and the user wants to type Max = 200 we're receiving // Max = 2 as the user types. wrapper.ConditionalSet(constraintParser[rowType][i].RowData, range); } } } } UnityEngine.GUI.changed = false; EditorGUI.showMixedValue = false; } } // For type wrappers. } // Indentation. } // For Translational, Rotational. var ecControllers = refConstraint.GetElementaryConstraintControllers(); if (ecControllers.Length > 0 && InspectorGUI.Foldout(selected("controllers"), GUI.MakeLabel("Controllers", true))) { using (InspectorGUI.IndentScope.Single) { foreach (var refController in ecControllers) { var controllerType = refController.GetControllerType(); var controllerTypeTag = controllerType.ToString()[0].ToString(); var controllerName = ConstraintUtils.FindName(refController); if (controllerName.EndsWith(" Controller")) { controllerName = controllerName.Remove(controllerName.LastIndexOf(" Controller")); } var controllerLabel = GUI.MakeLabel((controllerType == Constraint.ControllerType.Rotational ? GUI.Symbols.CircleArrowAcw.ToString() + " " : GUI.Symbols.ArrowRight.ToString() + " ") + controllerName, true); if (!InspectorGUI.Foldout(selected(controllerTypeTag + controllerName), controllerLabel)) { continue; } var controllers = (from constraint in constraints from controller in constraint.GetElementaryConstraintControllers() where controller.GetType() == refController.GetType() && controller.GetControllerType() == refController.GetControllerType() select controller).ToArray(); using (InspectorGUI.IndentScope.Single) { InspectorEditor.DrawMembersGUI(controllers); InspectorEditor.DrawMembersGUI(controllers, controller => (controller as ElementaryConstraint).RowData[0]); } } } } }
private bool ConstraintTypeGUI(Constraint[] constraints, bool differentTypes) { var anyUnknownType = constraints.Any(c => c.Type == ConstraintType.Unknown); // Reference type is set to unknown if we have multi-select and // the types aren't the same. This is to detect if the user has // selected some valid type, with the limitation that it's not // possible to change to Unknown (that action will be ignored). var refType = differentTypes ? ConstraintType.Unknown : constraints[0].Type; EditorGUI.showMixedValue = differentTypes; var newType = refType; using (new GUI.EnabledBlock(!EditorApplication.isPlayingOrWillChangePlaymode)) { if (refType == ConstraintType.Unknown) { newType = (ConstraintType)EditorGUILayout.EnumPopup(GUI.MakeLabel("Choose type"), refType, InspectorEditor.Skin.Popup); } else { newType = (ConstraintType)EditorGUILayout.EnumPopup(GUI.MakeLabel("Type"), refType, InspectorEditor.Skin.Popup, GUILayout.Width(EditorGUIUtility.labelWidth + 2.0f * 76.0f)); } } EditorGUI.showMixedValue = false; // Avoiding change to Unknown when it wasn't possible // to handle undo/redo for that case. if (newType != refType && newType != ConstraintType.Unknown) { var performChange = constraints.All(c => c.Type == ConstraintType.Unknown) || EditorUtility.DisplayDialog("Change constraint type", "Any changes to parameters (compliance, damping etc.) and/or states of " + $"any controller will be lost when the type changes to {newType}.\n\n" + "Do you want to continue?", "Yes", "Cancel"); if (performChange) { var undoIndex = Undo.GetCurrentGroup(); foreach (var constraint in constraints) { if (newType == constraint.Type) { continue; } constraint.ChangeType(newType, createdObject => { Undo.RegisterCreatedObjectUndo(createdObject, "ElementaryConstraint created."); }, destroyObject => { Undo.DestroyObjectImmediate(destroyObject); }); } Undo.CollapseUndoOperations(undoIndex); } } return(!anyUnknownType); }
private void OnGUI() { AGXDynamicsForUnityLogoGUI(); EditorGUILayout.LabelField(GUI.MakeLabel("Thank you for using AGX Dynamics for Unity!", true), InspectorEditor.Skin.LabelMiddleCenter); GUILayout.Space(6); var fieldColor = EditorGUIUtility.isProSkin ? Color.white : Color.black; var fieldErrorColor = Color.Lerp(Color.red, Color.black, 0.25f); var versionInfo = PackageUpdateHandler.FindCurrentVersion(); InspectorGUI.SelectableTextField(GUI.MakeLabel("Version"), (versionInfo.IsValid ? versionInfo.VersionString : "git checkout").Color(fieldColor), InspectorEditor.Skin.Label); string agxDynamicsVersion = s_agxInfo.Version; if (string.IsNullOrEmpty(agxDynamicsVersion)) { agxDynamicsVersion = GUI.AddColorTag("Unknown", fieldErrorColor); } else { agxDynamicsVersion = GUI.AddColorTag(agxDynamicsVersion, fieldColor); } InspectorGUI.SelectableTextField(GUI.MakeLabel("AGX Dynamics version"), agxDynamicsVersion, InspectorEditor.Skin.Label); InspectorGUI.LicenseEndDateField(s_agxInfo); InspectorGUI.BrandSeparator(1, 8); GUILayout.Label(GUI.MakeLabel("Online Documentation", true), InspectorEditor.Skin.Label); using (new EditorGUILayout.HorizontalScope(GUILayout.Width(200))) { if (InspectorGUI.Link(GUI.MakeLabel("AGX Dynamics for Unity"))) { Application.OpenURL(TopMenu.AGXDynamicsForUnityManualURL); } GUILayout.Label(" - ", InspectorEditor.Skin.Label); if (InspectorGUI.Link(GUI.MakeLabel("Examples"))) { Application.OpenURL(TopMenu.AGXDynamicsForUnityExamplesURL); } } using (new EditorGUILayout.HorizontalScope(GUILayout.Width(200))) { if (InspectorGUI.Link(GUI.MakeLabel("AGX Dynamics user manual"))) { Application.OpenURL(TopMenu.AGXUserManualURL); } GUILayout.Label(" - ", InspectorEditor.Skin.Label); if (InspectorGUI.Link(GUI.MakeLabel("AGX Dynamics API Reference"))) { Application.OpenURL(TopMenu.AGXAPIReferenceURL); } } InspectorGUI.BrandSeparator(1, 8); GUILayout.Label("Support", EditorStyles.boldLabel); EditorGUILayout.SelectableLabel("Please refer to the information received when purchasing your license for support contact information.", InspectorEditor.Skin.LabelWordWrap); }
public static object GenericListDrawer(object[] objects, InvokeWrapper wrapper) { var list = wrapper.Get <System.Collections.IList>(objects[0]); var target = objects[0] as Object; if (InspectorGUI.Foldout(EditorData.Instance.GetData(target, wrapper.Member.Name), InspectorGUI.MakeLabel(wrapper.Member))) { object insertElementBefore = null; object insertElementAfter = null; object eraseElement = null; var skin = InspectorEditor.Skin; var buttonLayout = new GUILayoutOption[] { GUILayout.Width(1.0f * EditorGUIUtility.singleLineHeight), GUILayout.Height(1.0f * EditorGUIUtility.singleLineHeight) }; foreach (var listObject in list) { using (InspectorGUI.IndentScope.Single) { GUILayout.BeginHorizontal(); { InspectorGUI.Separator(1.0f, EditorGUIUtility.singleLineHeight); if (InspectorGUI.Button(MiscIcon.EntryInsertBefore, true, "Insert new element before this.", buttonLayout)) { insertElementBefore = listObject; } if (InspectorGUI.Button(MiscIcon.EntryInsertAfter, true, "Insert new element after this.", buttonLayout)) { insertElementAfter = listObject; } if (InspectorGUI.Button(MiscIcon.EntryRemove, true, "Remove this element.", buttonLayout)) { eraseElement = listObject; } } GUILayout.EndHorizontal(); InspectorEditor.DrawMembersGUI(new Object[] { target }, ignored => listObject); } } InspectorGUI.Separator(1.0f, 0.5f * EditorGUIUtility.singleLineHeight); if (list.Count == 0) { GUILayout.Label(GUI.MakeLabel("Empty", true), skin.Label); } bool addElementToList = false; GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); addElementToList = InspectorGUI.Button(MiscIcon.EntryInsertAfter, true, "Add new element.", buttonLayout); } GUILayout.EndHorizontal(); object newObject = null; if (addElementToList || insertElementBefore != null || insertElementAfter != null) { newObject = Activator.CreateInstance(list.GetType().GetGenericArguments()[0], new object[] { }); } if (eraseElement != null) { list.Remove(eraseElement); } else if (newObject != null) { if (addElementToList || (list.Count > 0 && insertElementAfter != null && insertElementAfter == list[list.Count - 1])) { list.Add(newObject); } else if (insertElementAfter != null) { list.Insert(list.IndexOf(insertElementAfter) + 1, newObject); } else if (insertElementBefore != null) { list.Insert(list.IndexOf(insertElementBefore), newObject); } } if (eraseElement != null || newObject != null) { EditorUtility.SetDirty(target); } } // A bit of a hack until I figure out how to handle multi-selection // of lists, if that should be possible at all. We're handling the // list from inside this drawer and by returning null the return // value isn't propagated to any targets. return(null); }
public override void OnPreTargetMembersGUI() { // TODO: Improvements. // - "Copy-paste" shape. // 1. Select object with primitive shape(s) // 2. Select object to copy the shape(s) to // - Move from-to existing bodies or create a new body. // - Mesh object operations. // * Simplify assembly // * Multi-select to create meshes // - Inspect element (hold 'i'). if (!AGXUnity.Utils.Math.IsUniform(Assembly.transform.lossyScale, 1.0E-3f)) { Debug.LogWarning("Scale of AGXUnity.Assembly transform isn't uniform. If a child rigid body is moving under this transform the (visual) behavior is undefined.", Assembly); } var skin = InspectorEditor.Skin; if (!IsMultiSelect) { bool rbButtonPressed = false; bool shapeButtonPressed = false; bool constraintButtonPressed = false; InspectorGUI.ToolButtons(InspectorGUI.ToolButtonData.Create(ToolIcon.CreateRigidBody, m_mode == Mode.RigidBody, "Create/manage rigid bodies in this assembly.", () => rbButtonPressed = true), InspectorGUI.ToolButtonData.Create(ToolIcon.CreateShapeGivenVisual, m_mode == Mode.Shape, "Create shapes given visual representations.", () => shapeButtonPressed = true), InspectorGUI.ToolButtonData.Create(ToolIcon.CreateConstraint, m_mode == Mode.Constraint, "Create new constraint.", () => constraintButtonPressed = true)); HandleModeGUI(); if (rbButtonPressed) { ChangeMode(Mode.RigidBody); } if (shapeButtonPressed) { ChangeMode(Mode.Shape); } if (constraintButtonPressed) { ChangeMode(Mode.Constraint); } } else { GUILayout.Label(GUI.MakeLabel("Assemblies", 24, true), skin.LabelMiddleCenter); } OnObjectListsGUI(this); }
private void HandleModeRigidBodyGUI() { var skin = InspectorEditor.Skin; using (GUI.AlignBlock.Center) { if (m_subMode == SubMode.SelectRigidBody) { GUILayout.Label(GUI.MakeLabel("Select rigid body object in scene view.", true), skin.Label); } else { GUILayout.Label(GUI.MakeLabel("Select object(s) in scene view.", true), skin.Label); } } bool selectionHasRigidBody = m_selection.Find(entry => entry.Object.GetComponentInParent <RigidBody>() != null) != null; bool createNewRigidBodyPressed = false; bool addToExistingRigidBodyPressed = false; bool moveToNewRigidBodyPressed = false; GUILayout.BeginHorizontal(); { GUILayout.Space(12); GUILayout.BeginVertical(); { UnityEngine.GUI.enabled = m_selection.Count == 0 || !selectionHasRigidBody; createNewRigidBodyPressed = GUILayout.Button(GUI.MakeLabel("Create new" + (m_selection.Count == 0 ? " (empty)" : ""), false, "Create new rigid body with selected objects"), skin.Button, GUILayout.Width(128)); UnityEngine.GUI.enabled = m_selection.Count > 0 && Assembly.GetComponentInChildren <RigidBody>() != null; addToExistingRigidBodyPressed = GUILayout.Button(GUI.MakeLabel("Add to existing", false, "Add selected objects to existing rigid body"), skin.GetButton(m_subMode == SubMode.SelectRigidBody), GUILayout.Width(100)); UnityEngine.GUI.enabled = selectionHasRigidBody; moveToNewRigidBodyPressed = GUILayout.Button(GUI.MakeLabel("Move to new", false, "Move objects that already contains a rigid body to a new rigid body"), skin.Button, GUILayout.Width(85)); UnityEngine.GUI.enabled = true; } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); // Creates new rigid body and move selected objects to it (as children). if (createNewRigidBodyPressed || moveToNewRigidBodyPressed) { CreateOrMoveToRigidBodyFromSelectionEntries(m_selection); m_selection.Clear(); } // Toggle to select a rigid body in scene view to move the current selection to. else if (addToExistingRigidBodyPressed) { // This will toggle if sub-mode already is SelectRigidBody. ChangeSubMode(SubMode.SelectRigidBody); } // The user has chosen a rigid body to move the current selection to. if (m_rbSelection != null) { CreateOrMoveToRigidBodyFromSelectionEntries(m_selection, m_rbSelection.RigidBody.gameObject); m_selection.Clear(); ChangeSubMode(SubMode.None); } }
private void MeshOptionsGUI() { InspectorGUI.Separator(); using (new GUI.EnabledBlock(!EditorApplication.isPlayingOrWillChangePlaymode)) { if (InspectorGUI.Foldout(GetEditorData(Mesh), GUI.MakeLabel("Options"))) { using (InspectorGUI.IndentScope.Single) { InspectorEditor.DrawMembersGUI(Targets, t => (t as AGXUnity.Collide.Mesh).Options); var applyResetResult = InspectorGUI.PositiveNegativeButtons(UnityEngine.GUI.enabled, "Apply", "Apply the changes", "Reset", "Delete collision meshes and reset mesh options values to default."); if (applyResetResult == InspectorGUI.PositiveNegativeResult.Positive) { var meshes = GetTargets <AGXUnity.Collide.Mesh>().ToArray(); var collisionMeshGenerator = new AGXUnity.Collide.CollisionMeshGenerator(); var generatorStartTime = EditorApplication.timeSinceStartup; collisionMeshGenerator.GenerateAsync(meshes); var isCanceled = false; while (!isCanceled && collisionMeshGenerator.IsRunning) { var progressBarTitle = $"Generating collision meshes: {(int)( EditorApplication.timeSinceStartup - generatorStartTime )} s"; var progressBarInfo = string.Empty; var progress = collisionMeshGenerator.Progress; isCanceled = EditorUtility.DisplayCancelableProgressBar(progressBarTitle, progressBarInfo, progress); if (!isCanceled) { System.Threading.Thread.Sleep(50); } } EditorUtility.ClearProgressBar(); if (isCanceled) { CanceledAsyncCollisionMeshGeneretors.RegisterCanceled(collisionMeshGenerator); } else { var results = collisionMeshGenerator.CollectResults(); using (new Utils.UndoCollapseBlock("Apply collision mesh data")) { foreach (var result in results) { Undo.RecordObject(result.Mesh, "Collision Meshes"); result.Mesh.Options = result.Options; result.Mesh.PrecomputedCollisionMeshes = result.CollisionMeshes; } } var hasPrefabAssetBeenChanged = results.Any(result => PrefabUtility.GetCorrespondingObjectFromOriginalSource(result.Mesh.gameObject) == null && PrefabUtility.GetPrefabInstanceHandle(result.Mesh.gameObject) == null); // Trying to dirty gizmos rendering of all affected prefab instances. // We don't have to dirty them all but it's hard to determine where // the instance is located in the hierarchy. if (hasPrefabAssetBeenChanged) { var allMeshes = Object.FindObjectsOfType <AGXUnity.Collide.Mesh>(); foreach (var m in allMeshes) { m.OnPrecomputedCollisionMeshDataDirty(); } } } collisionMeshGenerator = null; GUIUtility.ExitGUI(); } else if (applyResetResult == InspectorGUI.PositiveNegativeResult.Negative && EditorUtility.DisplayDialog("Reset collision meshes to default", "Destroy collision meshes and reset mesh options to default?", "Yes", "Cancel")) { var meshes = GetTargets <AGXUnity.Collide.Mesh>().ToArray(); using (new Utils.UndoCollapseBlock("Reset collision mesh data")) { for (int i = 0; i < meshes.Length; ++i) { var mesh = meshes[i]; Undo.RecordObject(mesh, "Resetting collision mesh data"); mesh.DestroyCollisionMeshes(); if (mesh.Options != null) { Undo.RecordObject(mesh, "Resetting mesh options to default"); mesh.Options.ResetToDesfault(); } } } } } } } }
public void OnInspectorGUI() { InspectorGUI.OnDropdownToolBegin($"Disable collisions between {m_mainObject.name} and other objects selected in Scene View."); var skin = InspectorEditor.Skin; var emptyContent = GUI.MakeLabel(" "); EditorGUILayout.LabelField(GUI.MakeLabel("Disable: ", true), SelectGameObjectDropdownMenuTool.GetGUIContent(m_mainObject), skin.TextArea); EditorGUILayout.LabelField(emptyContent, GUI.MakeLabel(GUI.Symbols.ArrowLeftRight.ToString())); if (m_selected.Count == 0) { EditorGUILayout.LabelField(emptyContent, GUI.MakeLabel("Select object(s) in scene view" + AwaitingUserActionDots()), skin.TextArea); } else { int removeIndex = -1; for (int i = 0; i < m_selected.Count; ++i) { GUILayout.BeginHorizontal(); { EditorGUILayout.LabelField(emptyContent, SelectGameObjectDropdownMenuTool.GetGUIContent(m_selected[i]), skin.TextArea); if (InspectorGUI.Button(MiscIcon.EntryRemove, true, "Remove pair.", GUILayout.Width(14))) { removeIndex = i; } } GUILayout.EndHorizontal(); } if (removeIndex >= 0) { m_selected.RemoveAt(removeIndex); } } var applyCancelState = InspectorGUI.PositiveNegativeButtons(m_selected.Count > 0, "Apply", "Apply current configuration.", "Cancel"); if (applyCancelState == InspectorGUI.PositiveNegativeResult.Positive) { string selectedGroupName = m_mainObject.GetInstanceID().ToString(); string mainObjectGroupName = ""; for (int i = 0; i < m_selected.Count; ++i) { mainObjectGroupName += m_selected[i].GetInstanceID().ToString() + (i != m_selected.Count - 1 ? "_" : ""); } Undo.SetCurrentGroupName("Disabling collisions"); var undoGroupId = Undo.GetCurrentGroup(); if (m_mainObject.GetComponent <CollisionGroups>() == null) { Undo.AddComponent <CollisionGroups>(m_mainObject); } Undo.RecordObject(m_mainObject.GetComponent <CollisionGroups>(), "Adding collision group"); m_mainObject.GetComponent <CollisionGroups>().AddGroup(mainObjectGroupName, ShouldPropagateToChildren(m_mainObject)); foreach (var selected in m_selected) { if (selected.GetComponent <CollisionGroups>() == null) { Undo.AddComponent <CollisionGroups>(selected); } Undo.RecordObject(selected.GetComponent <CollisionGroups>(), "Adding collision group"); selected.GetComponent <CollisionGroups>().AddGroup(selectedGroupName, ShouldPropagateToChildren(selected)); } // TopMenu.GetOrCreate works with Undo. Undo.RecordObject(TopMenu.GetOrCreateUniqueGameObject <CollisionGroupsManager>(), "Adding collision group to manager."); CollisionGroupsManager.Instance.SetEnablePair(mainObjectGroupName, selectedGroupName, false); Undo.CollapseUndoOperations(undoGroupId); PerformRemoveFromParent(); } else if (applyCancelState == InspectorGUI.PositiveNegativeResult.Negative) { PerformRemoveFromParent(); } InspectorGUI.OnDropdownToolEnd(); }
public static bool ConstraintConnectedFrameSyncGUI(bool enabled) { enabled = InspectorGUI.Toggle(GUI.MakeLabel("Connected Frame Animated", true), !EditorGUI.showMixedValue && enabled); return(enabled); }