Last active
October 15, 2023 01:35
-
-
Save pacoelayudante/04645f4c30666f45f1352bb06bc6137e to your computer and use it in GitHub Desktop.
despues la actualizao
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using System.Reflection; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
using UnityEditor.SceneManagement; | |
#endif | |
///<summary> | |
/// Es así la cosa, se lo pones a un object reference e indicas que metodo de busqueda usar | |
/// de ahi se muestra drop down al costado que encuentra las opciones viables | |
/// tambien hay un flag para indicar si queres que te alerte si el valor esta null | |
///</summary> | |
public class AutoBuscarObjetoAttribute : PropertyAttribute | |
{ | |
public enum Metodo | |
{ | |
GetComponent, // solo valido para comps (scriptable objet no tiene sus propios componentes) | |
GetComponentInChildren, // idem | |
FindObjectOfType // ver temita de los prefab stage y supongo de escenas diferentes y eso | |
} | |
private Metodo _metodo; | |
public AutoBuscarObjetoAttribute(Metodo metodo) | |
{ | |
_metodo = metodo; | |
} | |
#if UNITY_EDITOR | |
[CustomPropertyDrawer(typeof(AutoBuscarObjetoAttribute))] | |
public class ObjectFieldAutoFinderAttributeEditor : PropertyDrawer | |
{ | |
private const string LIMPIAR = "> Limpiar_"; | |
private static readonly string[] LISTA_VACIA = new string[0]; | |
private static readonly string[] MULTI_INVALIDO = new string[] { LIMPIAR, "GetComponent invalido para seleccion multiple :(" }; | |
private static readonly string[] NADA_ENCONTRADO = new string[] { LIMPIAR, "Ninguna opcion encontrada :(" }; | |
private static readonly string[] MULTI_STAGE = new string[] { LIMPIAR, "Objetos de diferentes Stages seleccionados :(" }; | |
private static List<Object> objetosEncontrados = new(16); | |
private const float ANCHO = 20f; | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
{ | |
if (property.propertyType != SerializedPropertyType.ObjectReference) | |
{ | |
// icono o algo avisando que no se puede | |
EditorGUI.PropertyField(position, property, label); | |
return; | |
} | |
position.width -= ANCHO; | |
EditorGUI.PropertyField(position, property, label); | |
position.x = position.xMax; | |
position.width = ANCHO; | |
var metodoDeBusqueda = ((AutoBuscarObjetoAttribute)attribute)._metodo; | |
var serializedObject = property.serializedObject; | |
bool multiValorInvalido = metodoDeBusqueda != Metodo.FindObjectOfType | |
&& serializedObject.isEditingMultipleObjects; | |
using (var change = new EditorGUI.ChangeCheckScope()) | |
{ | |
string[] opciones = null; | |
if (Event.current.type == EventType.MouseDown && position.Contains(Event.current.mousePosition)) | |
{ | |
if (multiValorInvalido) | |
opciones = MULTI_INVALIDO; | |
else | |
opciones = GenerarOpciones(metodoDeBusqueda, property, serializedObject); | |
} | |
else | |
{ | |
opciones = LISTA_VACIA; | |
} | |
var indiceMasUno = EditorGUI.Popup(position, -1, opciones); | |
if (change.changed && !multiValorInvalido && objetosEncontrados.Count > 0) | |
{ | |
if (indiceMasUno == 0) | |
property.objectReferenceValue = null; | |
else if (!multiValorInvalido && objetosEncontrados.Count > 0) | |
{ | |
var objetoElegido = objetosEncontrados[indiceMasUno - 1]; | |
property.objectReferenceValue = objetoElegido; | |
if (objetoElegido != null) | |
EditorGUIUtility.PingObject(property.objectReferenceValue); | |
} | |
} | |
} | |
} | |
public string[] GenerarOpciones(Metodo metodo, SerializedProperty property, SerializedObject serializedObject) | |
{ | |
// get type | |
var targetObject = serializedObject.targetObject; | |
var targetObjectType = targetObject.GetType(); | |
var fieldInfo = targetObjectType.GetField( property.propertyPath, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance); | |
var tipo = fieldInfo.FieldType; | |
objetosEncontrados.Clear(); | |
if (metodo == Metodo.GetComponent) | |
{ | |
} | |
else if (metodo == Metodo.GetComponentInChildren) | |
{ | |
if (targetObject is Component comp) | |
{ | |
// me suena que en realidad la unica parte que tengo que branchear | |
// es la de Get o Find lo demas esta bien que sea todo igual | |
var encontrados = comp.GetComponentsInChildren(tipo, includeInactive: true); | |
if (encontrados.Length == 0) | |
return NADA_ENCONTRADO; | |
else | |
{ | |
var listaDeNombres = new string[encontrados.Length + 1]; | |
listaDeNombres[0] = LIMPIAR; | |
for (int i = 0; i < encontrados.Length; i++) | |
{ | |
var encontrado = encontrados[i]; | |
objetosEncontrados.Add(encontrado); | |
// deberia mostrar el hierarchy name (al menos el parent/root?) | |
listaDeNombres[i + 1] = encontrado.name; | |
} | |
return listaDeNombres; | |
} | |
} | |
} | |
if (metodo == Metodo.FindObjectOfType) | |
{ | |
// falta resolver temita del stage - prefab stage | |
var encontrados = Object.FindObjectsOfType(tipo, includeInactive: true); | |
if (encontrados.Length == 0) | |
return NADA_ENCONTRADO; | |
else | |
{ | |
var listaDeNombres = new string[encontrados.Length + 1]; | |
listaDeNombres[0] = LIMPIAR; | |
for (int i = 0; i < encontrados.Length; i++) | |
{ | |
var encontrado = encontrados[i]; | |
objetosEncontrados.Add(encontrado); | |
// deberia mostrar el hierarchy name (al menos el parent/root?) | |
listaDeNombres[i + 1] = encontrado.name; | |
} | |
return listaDeNombres; | |
} | |
} | |
else | |
{ | |
// get comp local <- este es mas facil podria estar primero | |
// get comp in child <- este no deberia necesitar el tema de staging creo | |
return new string[0]; | |
} | |
} | |
} | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment