internal override void Apply(VisualElement container) { /// <sample> // Note: PopupField has no UXML support because it is a generic type. var choices = new List <string> { "First", "Second", "Third" }; // Create a new field and assign it its value. var normalField = new PopupField <string>("Normal Field", choices, 0); normalField.value = "Second"; container.Add(normalField); // Create a new field, disable it, and give it a style class. var styledField = new PopupField <string>("Styled Field", choices, 0); styledField.SetEnabled(false); styledField.AddToClassList("some-styled-field"); styledField.value = normalField.value; container.Add(styledField); // Mirror value of uxml field into the C# field. normalField.RegisterCallback <ChangeEvent <string> >((evt) => { styledField.value = evt.newValue; }); /// </sample> }
private void UpdateSelectableComponents(Object dataContext) { if (componentPopup != null) { componentPopup.RemoveFromHierarchy(); componentPopup = null; } var targetGameObject = dataContext as GameObject; if (targetGameObject == null) { return; } var components = new List <Component>(); targetGameObject.GetComponents(components); var selectableObjects = components.Cast <Object>().ToList(); selectableObjects.Insert(0, dataContext); int defaultIndex = selectableObjects.IndexOf(pComponent.objectReferenceValue); if (defaultIndex < 0) { defaultIndex = 0; } //Make sure we're currently set to the default value if (selectableObjects.Count > 0) { pComponent.objectReferenceValue = selectableObjects[defaultIndex]; pComponent.serializedObject.ApplyModifiedProperties(); } componentPopup = new PopupField <Object>("Component", selectableObjects, defaultIndex, FormatComponentType, FormatComponentTypePopup); componentPopup.RegisterCallback <ChangeEvent <Object> >(evt => { pComponent.objectReferenceValue = evt.newValue is GameObject ? null : evt.newValue; pProperty.stringValue = string.Empty; UpdateSelectableProperties(); pComponent.serializedObject.ApplyModifiedProperties(); }); rootContainer.Insert(2, componentPopup); }
private void UpdateChoices(SerializedProperty property, InputActionAsset inputActionAsset, VisualElement result) { result.Clear(); if (inputActionAsset == null) { var propertyField = new ObjectField(property.displayName); propertyField.SetEnabled(false); result.Add(propertyField); return; } var assetReferences = AssetDatabase .LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(inputActionAsset)) .OfType <InputActionReference>() .ToList(); // Ugly hack: GenericMenu interprets "/" as a submenu path. But luckily, "/" is not the only slash we have in Unicode. var choices = inputActionAsset.Select(a => a.actionMap.name + "\uFF0F" + a.name).ToList(); choices.Insert(0, "None"); var references = inputActionAsset.Select(a => assetReferences.Find(r => a == r.action)).ToList(); references.Insert(0, null); var field = new PopupField <string>(property.displayName, choices, 0); { var selectedAction = ((InputActionReference)property.objectReferenceValue)?.action; field.value = choices[Mathf.Max(0, references.FindIndex(a => (a == null ? null : a.action) == selectedAction))]; } field.RegisterCallback <ChangeEvent <string> >(ev => { property.objectReferenceValue = references[Mathf.Clamp(field.index, 0, references.Count - 1)]; property.serializedObject.ApplyModifiedProperties(); }); field.schedule.Execute(() => { //if (!property.isValid) return; if (!property.Next(false)) { return; } var selectedAction = ((InputActionReference)property.objectReferenceValue)?.action; field.value = choices[Mathf.Max(0, references.FindIndex(a => (a == null ? null : a.action) == selectedAction))]; }).Every(100); result.Add(field); }
private void UpdateSelectableProperties() { if (propertyPopup != null) { propertyPopup.RemoveFromHierarchy(); propertyPopup = null; } Object targetObject = pComponent.objectReferenceValue; if (targetObject == null) { targetObject = pDataContext.objectReferenceValue; } if (targetObject == null) { return; } var properties = targetObject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.GetField); var propertyNames = properties.Select(x => x.Name).ToList(); int defaultIndex = propertyNames.IndexOf(pProperty.stringValue); if (defaultIndex < 0) { defaultIndex = 0; } //Make sure we're currently set to the default value if (propertyNames.Count > 0) { pProperty.stringValue = propertyNames[defaultIndex]; pProperty.serializedObject.ApplyModifiedProperties(); } propertyPopup = new PopupField <string>("Property", propertyNames, defaultIndex); propertyPopup.RegisterCallback <ChangeEvent <string> >(evt => { pProperty.stringValue = evt.newValue; pProperty.serializedObject.ApplyModifiedProperties(); }); rootContainer.Add(propertyPopup); }
void CreateListSpreadsheet() { m_SpreadsheetsListContainer.Clear(); var listName = GoogleDocConnectorSettings.Instance.Spreadsheets.Where(v => v.Name != "<Spreadsheet>").Select(v => v.Name).ToList(); listName.Add(k_DefaultSpreadsheetField); var spreadsheetsPopupField = new PopupField <string>("", listName, 0) { value = BuildVersionsSpreadsheet.Name ?? k_DefaultSpreadsheetField }; spreadsheetsPopupField.RegisterCallback <ChangeEvent <string> >(evt => { var selectedSpreadSheet = GoogleDocConnectorSettings.Instance.Spreadsheets.FirstOrDefault(s => s.Name == evt.newValue); BuildSystemSettings.Instance.SpreadsheetId = selectedSpreadSheet != null ? selectedSpreadSheet.Id : string.Empty; }); m_SpreadsheetsListContainer.Add(spreadsheetsPopupField); }
void UpdateGraphicsAPI() { m_GraphicsAPIPlaceholder.Clear(); List <GraphicsDeviceType> graphicsAPIList = null; GraphicsDeviceType initGraphicsDeviceType; if (m_DeviceInfo.IsAndroidDevice()) { graphicsAPIList = new List <GraphicsDeviceType> { GraphicsDeviceType.Vulkan, GraphicsDeviceType.OpenGLES3, GraphicsDeviceType.OpenGLES2 }; initGraphicsDeviceType = m_CustomizedPlayerSettings.androidGraphicsAPIs[0]; } else if (m_DeviceInfo.IsiOSDevice()) { graphicsAPIList = new List <GraphicsDeviceType> { GraphicsDeviceType.Metal, GraphicsDeviceType.OpenGLES3, GraphicsDeviceType.OpenGLES2 }; initGraphicsDeviceType = m_CustomizedPlayerSettings.iOSGraphicsAPIs[0]; } else { return; } // We have to use PopupField to only add a subset of GraphicsDeviceType, and PopupField has no UXML support. // Also we can't modify the values of PopupField, so we have to create it every time when we're switching devices. m_GraphicsAPIField = new PopupField <GraphicsDeviceType>("Graphics API", graphicsAPIList, initGraphicsDeviceType) { style = { width = 270 } }; m_GraphicsAPIField.RegisterCallback <ChangeEvent <GraphicsDeviceType> >(SetGraphicsAPI); m_GraphicsAPIPlaceholder.Add(m_GraphicsAPIField); }
private VisualElement CreateExportSettingsView() { var settingsContainer = new VisualElement() { name = Styles.exportSettings }; settingsContainer.AddToClassList(Styles.exportSettings); var exportTypes = new List <ExportTextureType>() { ExportTextureType.Texture2D, ExportTextureType.Texture3D }; var exportType = new PopupField <ExportTextureType>(exportTypes, exportTypes[0]) { name = Styles.exportType, label = "Texture Type" }; exportType.RegisterCallback <ChangeEvent <ExportTextureType> >( (evt) => { if (evt.newValue == ExportTextureType.Texture2D) { m_exportSettings.Remove(m_exportDims3D); m_exportSettings.Insert(1, m_exportDims2D); } else if (evt.newValue == ExportTextureType.Texture3D) { m_exportSettings.Remove(m_exportDims2D); m_exportSettings.Insert(1, m_exportDims3D); } } ); var dimensionsField2D = new Vector2IntField() { name = Styles.exportDims2D, label = "Dimensions", value = new Vector2Int(512, 512) }; var dimensionsField3D = new Vector3IntField() { name = Styles.exportDims3D, label = "Dimensions", value = new Vector3Int(64, 64, 64) }; var m_listOfFormats = new List <GraphicsFormat>() { // GraphicsFormat.R8_UNorm, // GraphicsFormat.R8_SNorm, GraphicsFormat.R16_UNorm, // GraphicsFormat.R16_SNorm, GraphicsFormat.R16_SFloat, // GraphicsFormat.R32_SFloat, }; var exportFormat = new PopupField <GraphicsFormat>(m_listOfFormats, GraphicsFormat.R16_UNorm) { name = Styles.exportFormat, label = "Texture Format" }; settingsContainer.Add(exportType); settingsContainer.Add(dimensionsField2D); settingsContainer.Add(exportFormat); m_exportSettings = settingsContainer; m_exportType = exportType; m_exportDims2D = dimensionsField2D; m_exportDims3D = dimensionsField3D; m_exportFormat = exportFormat; exportType.value = ExportTextureType.Texture2D; return(settingsContainer); }
public override VisualElement CreateCommandEditorGUI() { var root = new VisualElement(); List <Type> compatibleReferenceTypes = new List <Type> { typeof(IntVariableReference), typeof(BoolVariableReference), typeof(FloatVariableReference), typeof(StringVariableReference), typeof(ColorVariableReference), typeof(ObjectVariableReference), typeof(LayerMaskVariableReference), typeof(Vector2VariableReference), typeof(Vector3VariableReference), typeof(Vector4VariableReference), typeof(RectVariableReference), typeof(AnimationCurveVariableReference), typeof(BoundsVariableReference), typeof(GradientVariableReference), typeof(QuaternionVariableReference), typeof(Vector2IntVariableReference), typeof(Vector3IntVariableReference), typeof(RectIntVariableReference), typeof(BoundsIntVariableReference), }; List <Type> compatibleTypes = compatibleReferenceTypes.Select(t => t.BaseType.GenericTypeArguments[0]).ToList(); Func <Type, string> formatter = (type) => { if (type.IsGenericType) { return(type.GetGenericArguments()[0].Name); } else { return(type.Name); } }; var typeSelector = new PopupField <Type>(compatibleTypes, 0, formatter, formatter); typeSelector.label = "型の変更"; typeSelector.RegisterCallback <ChangeEvent <Type> >(evt => { var type = compatibleReferenceTypes[compatibleTypes.IndexOf(evt.newValue)]; var targetProp = CommandItem.CommandProperty.GetProperty().FindPropertyRelative("target"); var valueToSetProp = CommandItem.CommandProperty.GetProperty().FindPropertyRelative("value"); targetProp.managedReferenceValue = Activator.CreateInstance(type); valueToSetProp.managedReferenceValue = Activator.CreateInstance(type); targetProp.serializedObject.ApplyModifiedProperties(); root.Unbind(); root.Bind(targetProp.serializedObject); }); var defaultType = typeSelector.value; var target = CommandItem.CommandProperty.GetProperty().FindPropertyRelative("target"); var valueToSet = CommandItem.CommandProperty.GetProperty().FindPropertyRelative("value"); root.Add(typeSelector); if (target.hasChildren) { var typeInfo = target.managedReferenceFullTypename.Split(' '); if (typeInfo.Length >= 2) { var name = typeInfo[1]; var matched = compatibleTypes.FirstOrDefault(t => t.FullName == name); if (matched != default) { typeSelector.value = matched; } } else { } } var targetField = new PropertyField(); targetField.bindingPath = target.propertyPath; var valueToSetField = new PropertyField(); valueToSetField.bindingPath = valueToSet.propertyPath; root.Add(targetField); root.Add(valueToSetField); root.Bind(target.serializedObject); CommandEditorRootElement = root; return(root); }
public override VisualElement CreatePropertyGUI(SerializedProperty property) { var root = new VisualElement(); var target = property.FindPropertyRelative("variable"); if (target.FindPropertyRelative("key") == null) { target.managedReferenceValue = new IntVariableReference(); target.serializedObject.ApplyModifiedProperties(); } List <Type> compatibleTypes = new List <Type> { typeof(IntVariableReference), typeof(BoolVariableReference), typeof(FloatVariableReference), typeof(StringVariableReference), typeof(ColorVariableReference), typeof(ObjectVariableReference), typeof(LayerMaskVariableReference), typeof(Vector2VariableReference), typeof(Vector3VariableReference), typeof(Vector4VariableReference), typeof(RectVariableReference), typeof(AnimationCurveVariableReference), typeof(BoundsVariableReference), typeof(GradientVariableReference), typeof(QuaternionVariableReference), typeof(Vector2IntVariableReference), typeof(Vector3IntVariableReference), typeof(RectIntVariableReference), typeof(BoundsIntVariableReference), }; Func <Type, string> formatter = (type) => { if (type.IsGenericType) { return(type.GetGenericArguments()[0].Name); } else { return(type.Name); } }; var typeSelector = new PopupField <Type>(compatibleTypes, 0, formatter, formatter); typeSelector.label = "型の変更"; typeSelector.RegisterCallback <ChangeEvent <Type> >(evt => { var type = evt.newValue; var targetProp = property.FindPropertyRelative("variable"); targetProp.managedReferenceValue = Activator.CreateInstance(type); targetProp.serializedObject.ApplyModifiedProperties(); root.Unbind(); root.Bind(targetProp.serializedObject); }); var defaultType = typeSelector.value; root.Add(typeSelector); var variableField = new PropertyField(target); root.Bind(target.serializedObject); root.Add(variableField); return(root); }
public void OpenProjectSettings(MProject project) { var ModalContent = this.ShowModalWindow("PROJECT SETTINGS"); var NameField = new TextField("Project Name: "); NameField.value = project.ProjectName; ModalContent.Add(NameField); NameField.RegisterCallback <ChangeEvent <string> >((evt) => { project.ProjectName = evt.newValue; }); // Resolution Field. var resolutionField = new PopupField <string>("Resolution: ", ResNames, project.ResolutionIndex); //normalField.value = ResNames[0]; ModalContent.Add(resolutionField); // Create a new field and assign it its value. var framerateField = new PopupField <string>("FrameRate: ", FPSNames, project.FrameRateIndex); ModalContent.Add(framerateField); var customResField = new Vector2IntField("Custom:"); customResField.value = new Vector2Int(project.OutputWidth, project.OutputHeight); customResField.style.display = (project.ResolutionIndex == CustomResIndex) ? DisplayStyle.Flex : DisplayStyle.None; ModalContent.Add(customResField); // Mirror value of uxml field into the C# field. resolutionField.RegisterCallback <ChangeEvent <string> >((evt) => { project.ResolutionIndex = ResNames.IndexOf(evt.newValue); var size = this.ResSizes[project.ResolutionIndex]; project.OutputWidth = (int)size.x; project.OutputHeight = (int)size.y; customResField.style.display = (project.ResolutionIndex == CustomResIndex) ? DisplayStyle.Flex : DisplayStyle.None; project.is360 = _360Indices.Contains(project.ResolutionIndex); project.is360Stereo = (project.ResolutionIndex == _360StereoIndex); }); framerateField.RegisterCallback <ChangeEvent <string> >((evt) => { project.FrameRateIndex = FPSNames.IndexOf(evt.newValue); project.FrameRate = this.FPSValues[project.FrameRateIndex]; }); customResField.RegisterCallback <ChangeEvent <Vector2Int> >((evt) => { project.OutputWidth = evt.newValue.x; project.OutputHeight = evt.newValue.y; }); var toggleScreenShots = new Toggle("Capture ScreenShots:"); toggleScreenShots.value = project.TakeScreenShots; ModalContent.Add(toggleScreenShots); var ScreenShotsInterval = new FloatField("ScreenShots Interval (sec): "); ScreenShotsInterval.value = project.ScreenShotsInterval; ScreenShotsInterval.style.display = (project.TakeScreenShots) ? DisplayStyle.Flex : DisplayStyle.None; ModalContent.Add(ScreenShotsInterval); toggleScreenShots.RegisterCallback <ChangeEvent <bool> >((evt) => { project.TakeScreenShots = evt.newValue; ScreenShotsInterval.style.display = (project.TakeScreenShots) ? DisplayStyle.Flex : DisplayStyle.None; }); ScreenShotsInterval.RegisterCallback <ChangeEvent <float> >((evt) => { project.ScreenShotsInterval = evt.newValue; }); var DeleteButton = new Button(); DeleteButton.text = "DELETE PROJECT"; DeleteButton.clicked += () => { this.ShowConfirmDialog("Delete Project", "Are you sure?", (bool confirm) => { if (confirm) { this.m_MainWindow.DeleteProject(project); } else { this.OpenProjectSettings(project); } }); }; ModalContent.Add(DeleteButton); }
public UtilityAIConsiderationEditor(UtilityAIActionEditor utilityAIActionEditor, UtilityAIConsideration consideration) { this.consideration = consideration; this.utilityAIActionEditor = utilityAIActionEditor; VisualTreeAsset visualTree = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>("Assets/UtilityAI/Scripts/Editor/Utility AI Consideration Editor/UtilityAIConsiderationEditor.uxml"); visualTree.CloneTree(this); StyleSheet stylesheet = AssetDatabase.LoadAssetAtPath <StyleSheet>("Assets/UtilityAI/Scripts/Editor/Utility AI Consideration Editor/UtilityAIConsiderationEditor.uss"); this.styleSheets.Add(stylesheet); this.AddToClassList("utilityAIActionEditor"); Button moveUpButton = this.Query <Button>("moveUpButton").First(); moveUpButton.BringToFront(); moveUpButton.clickable.clicked += MoveConsiderationUp; Button moveDownButton = this.Query <Button>("moveDownButton").First(); moveDownButton.BringToFront(); moveDownButton.clickable.clicked += MoveConsiderationDown; Button deleteButton = this.Query <Button>("deleteButton").First(); deleteButton.BringToFront(); deleteButton.clickable.clicked += DeleteConsideration; considerationContainerFoldout = this.Query <Foldout>("consideration").First(); considerationContainerFoldout.text = consideration.name + ": "; considerationContainerFoldout.Query <Toggle>().First().AddToClassList("considerationFoldout"); responseCurveContainer = this.Query <VisualElement>("responseCurve").First(); TextField nameField = this.Query <TextField>("considerationName").First(); nameField.value = consideration.name; nameField.RegisterCallback <ChangeEvent <string> >( e => { if (e.newValue != "") { consideration.name = (string)e.newValue; considerationContainerFoldout.text = (string)e.newValue + ":"; } } ); Toggle enabledField = this.Query <Toggle>("considerationEnabled").First(); enabledField.value = consideration.enabled; enabledField.RegisterCallback <ChangeEvent <bool> >( e => { consideration.enabled = (bool)e.newValue; } ); VisualElement inputFieldContainer = this.Query <VisualElement>("considerationInput").First(); List <GameObject> considerationInputsPrefabs = FindPrefabsWithComponent <UtilityAIConsiderationInput>(); List <UtilityAIConsiderationInput> considerationInputs = new List <UtilityAIConsiderationInput>(); foreach (GameObject prefab in considerationInputsPrefabs) { considerationInputs.Add(prefab.GetComponent <UtilityAIConsiderationInput>()); } if (consideration.considerationInput == null) { consideration.considerationInput = considerationInputs[0]; } Debug.Log(consideration.considerationInput); int currentIndex = considerationInputs.IndexOf(consideration.considerationInput); PopupField <UtilityAIConsiderationInput> inputFieldPopup = new PopupField <UtilityAIConsiderationInput>("Consideration Inputs: ", considerationInputs, currentIndex); inputFieldPopup.RegisterCallback <ChangeEvent <UtilityAIConsiderationInput> >( e => { consideration.considerationInput = (UtilityAIConsiderationInput)e.newValue; } ); inputFieldContainer.Add(inputFieldPopup); UpdateResponseCurve(); }
// this function is heavily influenced by the API docs example at // https://docs.unity3d.com/Packages/[email protected]/api/UnityEngine.UIElements.ListView.html public void CreateGUI() { classNames.Add(typeof(ResourceProfile)); VisualElement root = rootVisualElement; header = new Label(""); header.style.unityFontStyleAndWeight = FontStyle.Bold; root.Add(header); fileTypeLabel = new Label("any"); fileTypeLabel.style.unityFontStyleAndWeight = FontStyle.Bold; root.Add(fileTypeLabel); VisualElement filtersElement = new VisualElement() { style = { flexDirection = FlexDirection.Row } }; root.Add(filtersElement); typeFilter = new UnityEditor.UIElements.PopupField <Type>(classNames, 0) { style = { flexGrow = 0.4f } }; typeFilter.RegisterCallback <ChangeEvent <Type> >(x => ApplyClassFilter(x.newValue)); filtersElement.Add(typeFilter); nameFilter = new TextField() { style = { flexGrow = 1 } }; nameFilter.RegisterValueChangedCallback <string>(x => ApplyFilter(x.newValue)); filtersElement.Add(nameFilter); busyLabel = new Label("Loading... Please wait."); busyLabel.style.unityFontStyleAndWeight = FontStyle.BoldAndItalic; busyLabel.style.color = Color.red; root.Add(busyLabel); listElements = new List <ResourceProfile>(); // The "makeItem" function is called when the // ListView needs more items to render. Func <VisualElement> makeItem = () => new Label(); // As the user scrolls through the list, the ListView object // recycles elements created by the "makeItem" function, // and invoke the "bindItem" callback to associate // the element with the matching data item (specified as an index in the list). //Action<VisualElement, int> bindItem = (e, i) => (e as Label).text = listElements[i]; Action <VisualElement, int> bindItem = (e, i) => { Label l = e as Label; l.text = listElements[i].ResourceName; // I would love to put the path in a tooltip but there is currently no way to get it from Resources l.tooltip = "Type: " + listElements[i].GetType().Name; }; // Provide the list view with an explict height for every row // so it can calculate how many items to actually display const int itemHeight = 16; listView = new ListView(listElements, itemHeight, makeItem, bindItem); listView.selectionType = SelectionType.Single; listView.onItemsChosen += objects => SetSelected(objects); listView.onSelectionChange += objects => SetSelected(objects); listView.style.flexGrow = 1.0f; root.Add(listView); nameFilter.Focus(); }
public DelegateEntryEditor(ExposedDelegateEditor exposedDelegateEditor, DelegateEntry delegateEntry) { this.exposedDelegateEditor = exposedDelegateEditor; this.delegateEntry = delegateEntry; VisualTreeAsset visualTree = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>("Assets/UtilityAI/Scripts/Editor/Delegate Entry Editor/DelegateEntryEditor.uxml"); visualTree.CloneTree(this); StyleSheet stylesheet = AssetDatabase.LoadAssetAtPath <StyleSheet>("Assets/UtilityAI/Scripts/Editor/Delegate Entry Editor/DelegateEntryEditor.uss"); this.styleSheets.Add(stylesheet); this.AddToClassList("delegateEntryEditor"); if (exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor.GetType() == typeof(UtilityAIAgentEditor)) { UtilityAIAgentEditor editorWindow = (UtilityAIAgentEditor)exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor; if (delegateEntry.TargetGO != editorWindow.utilityAIAgent.gameObject) { delegateEntry.TargetGO = editorWindow.utilityAIAgent.gameObject; } } delegateEntryFoldout = this.Query <Foldout>("delegateEntry"); delegateEntryFoldout.Query <Toggle>().First().AddToClassList("delegateEntryFoldout"); Button moveUpButton = this.Query <Button>("moveUpButton").First(); moveUpButton.BringToFront(); moveUpButton.clickable.clicked += MoveEntryUp; Button moveDownButton = this.Query <Button>("moveDownButton").First(); moveDownButton.BringToFront(); moveDownButton.clickable.clicked += MoveEntryDown; Button deleteButton = this.Query <Button>("deleteButton").First(); deleteButton.BringToFront(); deleteButton.clickable.clicked += DeleteEntry; List <Component> components = new List <Component>(); if (exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor is UtilityAIAgentEditor) { components = delegateEntry.TargetGO.GetComponents <Component>().ToList(); } else if (exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor is UtilityAIActionSetEditor) { if (((UtilityAIActionSetEditor)exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor).utilityAIAgent.inheritingGameObject != null) { components = ((UtilityAIActionSetEditor)exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor).utilityAIAgent.inheritingGameObject.GetComponents <Component>().ToList(); } } if (components.Count > 0) { int index = 0; if (delegateEntry.Target != null) { List <Component> sharedComponents = components.Where(o => o.GetType() == delegateEntry.Target.GetType()).ToList(); if (sharedComponents.Count > 0) { index = components.IndexOf(sharedComponents[0]); } else { if (exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor is UtilityAIAgentEditor && ((UtilityAIAgentEditor)exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor).utilityAIAgent.actionSet != null) { ((UtilityAIAgentEditor)exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor).utilityAIAgent.MakeActionsSetUnique(); ((UtilityAIAgentEditor)exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor).CreateInspectorGUI(); return; } } } PopupField <Component> targetComponentField = new PopupField <Component>("Component: ", components, index); delegateEntry.Target = targetComponentField.value; targetComponentField.RegisterCallback <ChangeEvent <Component> >( e => { delegateEntry.Target = (Component)e.newValue; exposedDelegateEditor.UpdateDelegateEntries(); } ); delegateEntryFoldout.Add(targetComponentField); if (delegateEntry.Target != null) { Type selectedComponentType = delegateEntry.Target.GetType(); BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; //Get a list of methods attached to the component, and create a dropdown menu: List <MethodInfo> methods = selectedComponentType.GetMethods(flags).ToList(); PopupField <MethodInfo> targetMethodField = new PopupField <MethodInfo>("Method: ", methods, methods.Contains(delegateEntry.Method) ? methods.IndexOf(delegateEntry.Method) : 0); if (delegateEntry.Method == null || delegateEntry.Method.Name != targetMethodField.value.Name) { delegateEntry.SetMethod(selectedComponentType, targetMethodField.value.Name); } targetMethodField.RegisterCallback <ChangeEvent <MethodInfo> >( e => { delegateEntry.SetMethod(selectedComponentType, e.newValue.Name); exposedDelegateEditor.UpdateDelegateEntries(); } ); delegateEntryFoldout.Add(targetMethodField); if (delegateEntry.Method != null && delegateEntry.Parameters.Length > 0) { Foldout parametersFoldout = new Foldout(); parametersFoldout.text = "Parameters: "; foreach (SerializableObject parameter in delegateEntry.Parameters) { if (parameter.obj is int) { IntegerField parameterField = new IntegerField(); parameterField.value = (int)parameter.obj; parameterField.RegisterCallback <ChangeEvent <int> >( e => { parameter.obj = (int)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is float) { FloatField parameterField = new FloatField(); parameterField.value = (float)parameter.obj; parameterField.RegisterCallback <ChangeEvent <float> >( e => { parameter.obj = (float)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is bool) { Toggle parameterField = new Toggle(); parameterField.value = (bool)parameter.obj; parameterField.RegisterCallback <ChangeEvent <bool> >( e => { parameter.obj = (bool)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is string) { TextField parameterField = new TextField(); parameterField.value = (string)parameter.obj; parameterField.RegisterCallback <ChangeEvent <string> >( e => { parameter.obj = (string)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is Vector3) { Vector3Field parameterField = new Vector3Field(); parameterField.value = (Vector3)parameter.obj; parameterField.RegisterCallback <ChangeEvent <Vector3> >( e => { parameter.obj = (Vector3)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is Vector2) { Vector2Field parameterField = new Vector2Field(); parameterField.value = (Vector2)parameter.obj; parameterField.RegisterCallback <ChangeEvent <Vector2> >( e => { parameter.obj = (Vector2)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is Bounds) { BoundsField parameterField = new BoundsField(); parameterField.value = (Bounds)parameter.obj; parameterField.RegisterCallback <ChangeEvent <Bounds> >( e => { parameter.obj = (Bounds)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is Rect) { RectField parameterField = new RectField(); parameterField.value = (Rect)parameter.obj; parameterField.RegisterCallback <ChangeEvent <Rect> >( e => { parameter.obj = (Rect)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is Color) { ColorField parameterField = new ColorField(); parameterField.value = (Color)parameter.obj; parameterField.RegisterCallback <ChangeEvent <Color> >( e => { parameter.obj = (Color)e.newValue; } ); parametersFoldout.Add(parameterField); } else if (parameter.obj is UnityEngine.Object) { ObjectField parameterField = new ObjectField(); parameterField.value = (UnityEngine.Object)parameter.obj; parameterField.RegisterCallback <ChangeEvent <UnityEngine.Object> >( e => { parameter.obj = (UnityEngine.Object)e.newValue; } ); parametersFoldout.Add(parameterField); } } delegateEntryFoldout.Add(parametersFoldout); } } } if (delegateEntry.TargetGO != null) { delegateEntryFoldout.text += delegateEntry.TargetGO.name; if (delegateEntry.Target != null) { delegateEntryFoldout.text += "(" + delegateEntry.Target.GetType() + ") "; if (delegateEntry.Method != null) { delegateEntryFoldout.text += delegateEntry.Method.Name; } } delegateEntryFoldout.text += ": "; } else { delegateEntryFoldout.text = "New Delegate Entry:"; } if (exposedDelegateEditor.utilityAIActionEditor.utilityAIAgentEditor is UtilityAIActionSetEditor && components.Count <= 0) { delegateEntryFoldout.text = "No inheriting object selected!"; } }
private void OnMaterialsDropped(Material[] droppedMaterials) { remappingRoot.Clear(); DisposeOfSerializedObjects(); //Construct a dictionary between shaders and their materials shadersToMaterials = new Dictionary <Shader, List <SerializedObject> >(); foreach (Material material in droppedMaterials) { if (!shadersToMaterials.TryGetValue(material.shader, out var list)) { list = new List <SerializedObject>(); shadersToMaterials.Add(material.shader, list); } list.Add(new SerializedObject(material)); } foreach (var pair in shadersToMaterials) { Box shaderRoot = new Box(); shaderRoot.AddToClassList("innerPadding"); remappingRoot.Add(shaderRoot); Shader shader = pair.Key; ObjectField shaderField = new ObjectField { objectType = typeof(Shader), value = shader }; shaderField.SetEnabled(false); shaderRoot.Add(shaderField); //RemapType, to a set of keys referring to values that could be remapped. var remapsFrom = new Dictionary <RemapType, HashSet <string> >(); var remapsTo = new Dictionary <RemapType, HashSet <string> >(); List <SerializedObject> materials = pair.Value; foreach (SerializedObject materialSO in materials) { SerializedProperty savedProperties = materialSO.FindProperty("m_SavedProperties"); //Textures ------------------------------------------------------------------------- SerializedProperty texEnvsArray = savedProperties.FindPropertyRelative("m_TexEnvs"); var textureKeys = new HashSet <string>(); remapsTo.Add(RemapType.Texture, textureKeys); var textureKeysFrom = new HashSet <string>(); remapsFrom.Add(RemapType.Texture, textureKeysFrom); for (int i = 0; i < texEnvsArray.arraySize; i++) { SerializedProperty texEnv = texEnvsArray.GetArrayElementAtIndex(i); SerializedProperty key = texEnv.FindPropertyRelative("first"); SerializedProperty texture = texEnv.FindPropertyRelative("second.m_Texture"); textureKeys.Add(key.stringValue); //Only add to the "from", if there is a key with a meaningful value in it. if (texture.objectReferenceValue != null) { textureKeysFrom.Add(key.stringValue); } } //----------------------------------------------------------------------------------- //Floats ---------------------------------------------------------------------------- SerializedProperty floatsArray = savedProperties.FindPropertyRelative("m_Floats"); //floats have no way of telling if they're not set, so they can use the same set var floatKeys = new HashSet <string>(); remapsTo.Add(RemapType.Float, floatKeys); remapsFrom.Add(RemapType.Float, floatKeys); for (int i = 0; i < floatsArray.arraySize; i++) { SerializedProperty @float = floatsArray.GetArrayElementAtIndex(i); SerializedProperty key = @float.FindPropertyRelative("first"); floatKeys.Add(key.stringValue); } //----------------------------------------------------------------------------------- //Vectors and Colors ---------------------------------------------------------------- SerializedProperty colorsArray = savedProperties.FindPropertyRelative("m_Colors"); //colors have no way of telling if they're not set, so they can use the same set var vectorKeys = new HashSet <string>(); remapsTo.Add(RemapType.VectorOrColor, vectorKeys); remapsFrom.Add(RemapType.VectorOrColor, vectorKeys); for (int i = 0; i < colorsArray.arraySize; i++) { SerializedProperty vector = colorsArray.GetArrayElementAtIndex(i); SerializedProperty key = vector.FindPropertyRelative("first"); vectorKeys.Add(key.stringValue); } //----------------------------------------------------------------------------------- } //CONTROLS var remapTypeField = new EnumField("Remap Type", RemapType.None) { name = remapTypeName }; remapTypeField.RegisterCallback <ChangeEvent <Enum> >(SelectedRemapType); shaderRoot.Add(remapTypeField); PopupField <string> popupFromField = new PopupField <string>(fromKeyLabel, noneList, 0) { name = fromKeyPopupName }; popupFromField.SetEnabled(false); shaderRoot.Add(popupFromField); PopupField <string> popupToField = new PopupField <string>(toKeyLabel, noneList, 0) { name = toKeyPopupName }; popupToField.SetEnabled(false); shaderRoot.Add(popupToField); Button remapButton = new Button { text = "Remap", name = remapButtonName }; remapButton.SetEnabled(false); shaderRoot.Add(remapButton); void SelectedRemapType(ChangeEvent <Enum> remapEvt) { if (remapEvt == null) { throw new ArgumentNullException(nameof(remapEvt)); } RemapType value = (RemapType)remapEvt.newValue; if (value == RemapType.None) { GetButton().SetEnabled(false); GetRemapTo().SetEnabled(false); GetRemapFrom().SetEnabled(false); return; } PopupField <string> child = GetRemapFrom(); int index = shaderRoot.IndexOf(child); child.RemoveFromHierarchy(); List <string> choicesFrom = remapsFrom[value].ToList(); choicesFrom.Insert(0, none); popupFromField = new PopupField <string>(fromKeyLabel, choicesFrom, none) { name = fromKeyPopupName }; shaderRoot.Insert(index, popupFromField); popupFromField.RegisterCallback <ChangeEvent <string> >(SelectedRemapFrom); } void SelectedRemapFrom(ChangeEvent <string> popupFromEvt) { string remapFromKey = popupFromEvt.newValue; if (remapFromKey == none) { GetButton().SetEnabled(false); GetRemapTo().SetEnabled(false); return; } PopupField <string> child = GetRemapTo(); int index = shaderRoot.IndexOf(child); child.RemoveFromHierarchy(); List <string> choicesTo = remapsTo[(RemapType)remapTypeField.value].ToList(); choicesTo.Insert(0, none); popupToField = new PopupField <string>(toKeyLabel, choicesTo, none) { name = toKeyPopupName }; shaderRoot.Insert(index, popupToField); popupToField.RegisterCallback <ChangeEvent <string>, (PopupField <string>, string)>(SelectedRemapTo, (popupToField, remapFromKey)); } void SelectedRemapTo(ChangeEvent <string> popupToEvt, (PopupField <string> popupToField, string remapFromKey) args) { string remapToKey = popupToEvt.newValue; VisualElement background = args.popupToField.Q(null, PopupField <string> .inputUssClassName); if (remapToKey == none) { GetButton().SetEnabled(false); background.style.unityBackgroundImageTintColor = default; return; } if (remapToKey == args.remapFromKey) { background.style.unityBackgroundImageTintColor = new Color(1f, 0.46f, 0.51f); return; } background.style.unityBackgroundImageTintColor = default; var button = GetButton(); button.SetEnabled(true); button.RemoveManipulator(button.clickable); button.clickable = new Clickable(() => PerformRemap(shader, (RemapType)GetRemapType().value, args.remapFromKey, remapToKey)); button.AddManipulator(button.clickable); } Button GetButton() => shaderRoot.Q <Button>(remapButtonName); EnumField GetRemapType() => shaderRoot.Q <EnumField>(remapTypeName); PopupField <string> GetRemapFrom() => shaderRoot.Q <PopupField <string> >(fromKeyPopupName); PopupField <string> GetRemapTo() => shaderRoot.Q <PopupField <string> >(toKeyPopupName); } }
private static void UpdatePropertyGUI(SerializedProperty property, VisualElement root) { root.Clear(); List <Type> compatibleTypes = new List <Type> { typeof(IntVariableReference), typeof(BoolVariableReference), typeof(FloatVariableReference), typeof(StringVariableReference), typeof(ColorVariableReference), typeof(ObjectVariableReference), typeof(LayerMaskVariableReference), typeof(Vector2VariableReference), typeof(Vector3VariableReference), typeof(Vector4VariableReference), typeof(RectVariableReference), typeof(AnimationCurveVariableReference), typeof(BoundsVariableReference), typeof(GradientVariableReference), typeof(QuaternionVariableReference), typeof(Vector2IntVariableReference), typeof(Vector3IntVariableReference), typeof(RectIntVariableReference), typeof(BoundsIntVariableReference), }; Func <Type, string> formatter = (type) => { if (type.BaseType.IsGenericType) { return(type.BaseType.GetGenericArguments()[0].Name); } else { return(type.Name); } }; var typeSelector = new PopupField <Type>(compatibleTypes, 0, formatter, formatter); typeSelector.label = "タイプ"; var typeInfo = property.managedReferenceFullTypename.Split(' '); if (typeInfo.Length >= 2) { var matched = compatibleTypes.FirstOrDefault(t => t.FullName == typeInfo[1]); if (matched != default) { typeSelector.value = matched; } } root.Add(typeSelector); if (string.IsNullOrEmpty(property.managedReferenceFullTypename)) { property.managedReferenceValue = new IntVariableReference(); property.serializedObject.ApplyModifiedProperties(); } var targetTypeProp = property.FindPropertyRelative("storeType"); var targetType = targetTypeProp.enumDisplayNames[targetTypeProp.enumValueIndex]; var typeToggle = new PropertyField(targetTypeProp, "ストア"); root.Add(typeToggle); switch (targetType) { case "Constant": var constantField = new PropertyField(property.FindPropertyRelative("constantValue"), "定数値"); root.Add(constantField); break; default: var targetKey = property.FindPropertyRelative("key"); var keyField = new PropertyField(targetKey, "キー"); root.Add(keyField); break; } root.Bind(property.serializedObject); typeSelector.RegisterCallback <ChangeEvent <Type> >(evt => { var type = evt.newValue; property.managedReferenceValue = Activator.CreateInstance(type); property.serializedObject.ApplyModifiedProperties(); UpdatePropertyGUI(property, root); }); typeToggle.RegisterCallback <ChangeEvent <string> >(evt => { UpdatePropertyGUI(property, root); }); }