- Home /
Editor Object Field Select From List
I have tried searching and just can't find a solution. Essentially, I am creating a game editor where a designer can pick and choose images for a given case. I have an ObjectField that gets the Texture2D from the directory, but when I click the ObjectField, it gives a selection of all of the Texture2D from the entire Assets.
I need a way to limit the selection of images to a given directory. I want to be able to restrict the designers to only select the images that should be set for the given type of object, and also it breaks the interface because a given image may not exist within the loading path specified. Is there any way to hack it to make the ObjectField selector to only display a list of certain images? Thank you for your help!
Texture2D actionImage = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/SceneAssets/GUI Assets/PersonalActions/"+selectedAction.ImageName+".png", typeof(Texture2D));
if(actionImage != null)
{
Texture2D newImage = (Texture2D)EditorGUILayout.ObjectField("Image", actionImage, typeof(Texture2D), false);
selectedAction.ImageName = newImage.name;
Debug.Log(selectedAction.ImageName);
}
I have also tried a variety of things with this: Including just putting the List in the object field as the object param, but got errors as a result.
Texture2D actionImage = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/SceneAssets/GUI Assets/PersonalActions/"+selectedAction.ImageName+".png", typeof(Texture2D));
if(actionImage != null)
{
List<Texture2D> imgList = new List<Texture2D>();
imgList.Add(actionImage);
for(int i = 0; i < imgList.Count; ++i)
{
imgList[i] = (Texture2D)EditorGUILayout.ObjectField("Image", imgList[i], typeof(Texture2D), false);
selectedAction.ImageName = imgList[i].name;
Debug.Log(selectedAction.ImageName);
}
}
$$anonymous$$aybe try to populate a List with the textures and reference the List in the object field it should avoid refering all the textures of your game, and only populate the List from the path referenced.
Appreciate the response. I tried the above with a list of Texture2D and I still get a selection of every texture in Assets/ Any other ideas?
That is really weird, the only alternative I can think of is to load from Resources, but I guess is gonna break your modularity.
Could you provide an example of a working object field selecting a picture from only a given directory? $$anonymous$$aybe I am just doing it wrong.
Answer by jaised · Jul 12, 2013 at 04:39 PM
I couldn't find an Editor GUI object that would allow the selection of images restricted to a particular file path(s), so I made my own object that does what I need. I'll put the code here because I'm a nice guy and am sure that someone could use this someday. Good luck and happy coding.
TexturePicker.cs
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.IO;
public delegate void ImageSelectedHandler(Texture2D imageName);
public class TexturePickerEditor : EditorWindow
{
public List<Texture2D> images = new List<Texture2D>();
/// <summary>
/// A flag to indicate if the editor window has been setup or not.
/// </summary>
private bool isSetup = false;
private ImageSelectedHandler handler;
#region Setup
/// <summary>
/// Attempts to setup the editor by reading in textures from specified path.
/// </summary>
/// <param name='path'>
/// Path to load images from.
/// </param>
public void Setup(string path, ImageSelectedHandler functionHandler)
{
string[] paths = new string[] { path };
Setup(paths, functionHandler);
} // eo Setup
/// <summary>
/// Attempts to setup the editor by reading in all textures specified
/// by the various paths. Supports multiple paths of textures.
/// </summary>
/// <param name='paths'>
/// Paths of textures to read in.
/// </param>
public void Setup(string[] paths, ImageSelectedHandler functionHandler)
{
isSetup = true;
ReadInAllTextures(paths);
handler = functionHandler;
} // eo Setup
#endregion Setup
#region GUI
Vector2 scrollPosition = Vector2.zero;
void OnGUI()
{
if(!isSetup)
return;
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
// create a button for each image loaded in, 4 buttons in width
// calls the handler when a new image is selected.
int counter = 0;
foreach(Texture2D img in images)
{
if(counter % 4 == 0 || counter == 0)
EditorGUILayout.BeginHorizontal();
++counter;
if(GUILayout.Button(img, GUILayout.Height(100), GUILayout.Width(100)))
{
// tell handler about new image, close selection window
handler(img);
EditorWindow.focusedWindow.Close();
}
if(counter % 4 == 0)
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
} // eo OnGUI
#endregion GUI
#region Utility
/// <summary>
/// Reads the in all textures from the paths.
/// </summary>
/// <param name='paths'>
/// The paths to read images from.
/// </param>
void ReadInAllTextures(string[] paths)
{
foreach(string path in paths)
{
string[] allFilesInPath = Directory.GetFiles(path);
foreach(string filePath in allFilesInPath)
{
Texture2D obj = (Texture2D)AssetDatabase.LoadAssetAtPath(filePath, typeof(Texture2D));
if(obj is Texture2D)
{
images.Add(obj as Texture2D);
}
}
}
} // eo ReadInAllTextures
#endregion Utility
} // End TexturePickerEditor
EditorUtilities.cs
/// <summary>
/// Shows a texture with a label and a button to select a new image
/// from a list of images loaded from the path specified. This allows
/// a selection of an image from a subset of images, unlike the UnityEditor.ObjectField
/// that pulls all images from /Assets/
/// </summary>
/// <param name='label'>
/// Label to display.
/// </param>
/// <param name='selectedImage'>
/// Selected image that shows in the interface.
/// </param>
/// <param name='yPosition'>
/// How far down in the interface to show this tool.
/// </param>
/// <param name='textureFilePath'>
/// Texture file path containing the images to load.
/// </param>
/// <param name='functionHandler'>
/// The function to handle the selection of a new texture.
/// </param>
public static void TexturePreviewWithSelection(string label, Texture selectedImage, float yPosition,
string textureFilePaths, ImageSelectedHandler functionHandler)
{
TexturePreviewWithSelection(label, selectedImage, yPosition, new string[] { textureFilePaths }, functionHandler);
} // eo TexturePreviewWithSelection
/// <summary>
/// Shows a texture with a label and a button to select a new image
/// from a list of images loaded from the paths specified. This allows
/// a selection of an image from a subset of images, unlike the UnityEditor.ObjectField
/// that pulls all images from /Assets/
/// </summary>
/// <param name='label'>
/// Label to display.
/// </param>
/// <param name='selectedImage'>
/// Selected image that shows in the interface.
/// </param>
/// <param name='yPosition'>
/// How far down in the interface to show this tool.
/// </param>
/// <param name='textureFilePaths'>
/// Texture file paths containing the images to load.
/// </param>
/// <param name='functionHandler'>
/// The function to handle the selection of a new texture.
/// </param>
public static void TexturePreviewWithSelection(string label, Texture selectedImage, float yPosition,
string[] textureFilePaths, ImageSelectedHandler functionHandler)
{
EditorGUILayout.BeginVertical(GUILayout.Height(125));
{
EditorGUILayout.LabelField(label);
EditorGUI.DrawPreviewTexture(new Rect(50,yPosition,100,100), selectedImage);
// used to center the select texture button
EditorGUILayout.BeginVertical();
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.Space();
if(GUILayout.Button("Select Texture", GUILayout.MaxWidth(100)))
{
EditorUtilities.TexturePicker(textureFilePaths, functionHandler);
}
EditorGUILayout.Space();
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndVertical();
} // eo TexturePreviewWithSelection
public static void TexturePicker(string path, ImageSelectedHandler functionHandler)
{
EditorUtilities.TexturePicker(new string[] { path }, functionHandler);
} // eo TexturePicker
/// <summary>
/// Creates a window with buttons to select a new image.
/// </summary>
/// <param name='paths'>
/// Paths to load images from.
/// </param>
/// <param name='functionHandler'>
/// How to handle the new image selection.
/// </param>
public static void TexturePicker(string[] paths, ImageSelectedHandler functionHandler)
{
TexturePickerEditor picker = (TexturePickerEditor)EditorWindow.GetWindow(typeof(TexturePickerEditor), true, "Texture Picker");
picker.Setup(paths, functionHandler);
} // eo TexturePicker
Answer by TonyLi · Jul 11, 2013 at 01:06 PM
You can populate an array of Texture2D's in a directory using this routine:
And then pass it to EditorGUI.Popup.
I was thinking about this but it'd be really helpful to editors to be able to select and see the image, rather than just the name.
Your answer
Follow this Question
Related Questions
Make a PropertyField() for a Texture2D SerializedProperty looking like an ObjectField() 2 Answers
How can I restrict the object selection to prefabs only? 1 Answer
Retrieve Array of Texture2Ds dropped in EditorWindow ObjectField 0 Answers
EditorGuiLayout - Objectfield 1 Answer
Are there any Editor fields which are Drag and Drop? 0 Answers