Jump to content
UnitySpain
Sign in to follow this  
ftejada

¿Se puede cargar un ScriptableObject desde ventana del editor via codigo?

Recommended Posts

Hola Gente!

Tengo una ventana de Editor que estoy programando y dentro de ella una variable de un script, con ciertos comportamientos, que es un ScriptableObject.

Actualmente, en la ventana del editor que he creado, tengo el campo para que se pueda arrastrar ese "Script ScriptableObject" una vez creado y que el script de la Ventana de Editor pueda trabajar con él internamente.

El caso es que me gustaría NO tener que arrastrar el scriptableObject al campo que he creado en la ventana, sino que al abrir la ventana del editor, se carge el scriptableObject a la variable dandole el patch donde está almacenado en el project... Algo asi como lo que se hace con los Resources.Load().

He probado a intentar cargarlo con Resources.Load() pero me da error...

 

No se cual es la mejor manera de abordar esto. A ver si alguien puede orientarme un poco.

 

Saludos

Edited by ftejada

Share this post


Link to post
Share on other sites

mmmm EditorWindow deriva de ScriptableObject, así que puedes usar el OnEnable() para decirle que la carga se haga en ese momento:

https://docs.unity3d.com/ScriptReference/EditorWindow.html

 

El tema de la carga del fichero en sí, imagino que se hace con una serialización a una instancia del ScriptableObject. Recuerda que son una especie de "prefab" con datos. No hay fichero único en sí, hay instancias del mismo tipo de asset.

Share this post


Link to post
Share on other sites
8 hours ago, ftejada said:

El caso es que me gustaría NO tener que arrastrar el scriptableObject al campo que he creado en la ventana, sino que al abrir la ventana del editor, se carge el scriptableObject a la variable dandole el patch donde está almacenado en el project... Algo asi como lo que se hace con los Resources.Load().

Es un asset así que en teoría podrías hacer eso, revisá AssetDataBase:

https://docs.unity3d.com/ScriptReference/AssetDatabase.html

quizas FindAssets.

 

Share this post


Link to post
Share on other sites

Gracias por las respuestas!!

He estado mirando lo que dijo lightbug (AssetDatabase), pero no encuentro la manera de hacerlo. "FindAssets" devuelve un array de string[] y no un scriptableObject.asset en si.

Mirando lo que dice pioj "Recuerda que son una especie de "prefab" con datos. No hay fichero único en sí, hay instancias del mismo tipo de asset." No se si la unica manera de hacer esto es Instanciar uno cada vez que se abre la ventana en OnEnable()), e ir borrandolos al cerrarse la ventana con OnDisable()

 

De todos modos comparto el codigo que hice por si a alguien le ayuda o teneis alguna sugerencia:

public class NombreClaseWindows : EditorWindow
{
	CreateAnchorPoints createAnchorPoints;     //class Tipo ScriptableObject
	
	//...

	private void OnEnable()
    {
        CreateAsset();
    }

    private void OnDisable()
    {
        DeleteAsset();
    }


private void CreateAsset()
        {
            string[] guids;
            string[] folders = new string[] { "Assets/NombreCarpeta/NombreCarpeta" };

            // search for a ScriptObject called ScriptObj
            guids = AssetDatabase.FindAssets("t:CreateAnchorPoints", folders);
            foreach (string guid in guids)
            {
                Debug.Log("Ya esxiste este asset en la siguiente ruta: " + AssetDatabase.GUIDToAssetPath(guid));
Debug.LogError("Debe arrastrar al Field 'PROFILE DE COMPORTAMIENTO' el profile de la ruta: " +
                          AssetDatabase.GUIDToAssetPath(guid));	
                return;
            }

            CreateAnchorPoints asset = (CreateAnchorPoints)ScriptableObject.CreateInstance(typeof(CreateAnchorPoints));
            AssetDatabase.CreateAsset(asset, "Assets/NombreCarpeta/NombreCarpeta/CreateAnchorPoints.asset");
            createAnchorPoints = asset;
        }
        private void DeleteAsset()
        {
            if (AssetDatabase.DeleteAsset(""Assets/NombreCarpeta/NombreCarpeta/CreateAnchorPoints.asset"))
            {
                Debug.Log("Successfully removed...");
            }
            else
            {
                Debug.Log("Delete failed...");
            }
        }
	
}

 

Saludos y gracias por la ayuda!!

Share this post


Link to post
Share on other sites
4 hours ago, ftejada said:

He estado mirando lo que dijo lightbug (AssetDatabase), pero no encuentro la manera de hacerlo. "FindAssets" devuelve un array de string[] y no un scriptableObject.asset en si.

Jaja es que ni siquiera me fijé que hacía FindAssets, solamente me guié por el bonito nombre.

 

Gracias por compartirlo, osea que la combinación de FindAssets + GUIDToAssetPath() hizo el truco?

Share this post


Link to post
Share on other sites

Si y no.... Porque eso solo me sirve de control para ver si ya existe el asset. Pero al final tengo que crearlo/Instanciarlo por script de todos modos y no puedo coger uno de los que ya tuviese creado manualmente sin script... Es decir no puedo hacer algo como:

 

CreateAnchorPoints createAnchorPoints = AssetDatabase.FindAssets("t:CreateAnchorPoints", folders); //Suponiendo que esto obtuviese el asset que está guardado en la carpeta que se le pasa como ruta

Share this post


Link to post
Share on other sites
5 hours ago, ftejada said:

Si y no.... Porque eso solo me sirve de control para ver si ya existe el asset. Pero al final tengo que crearlo/Instanciarlo por script de todos modos y no puedo coger uno de los que ya tuviese creado manualmente sin script... Es decir no puedo hacer algo como:

 


CreateAnchorPoints createAnchorPoints = AssetDatabase.FindAssets("t:CreateAnchorPoints", folders); //Suponiendo que esto obtuviese el asset que está guardado en la carpeta que se le pasa como ruta

y no probaste con los métodos "Load"?

LoadAllAssetRepresentationsAtPath         Returns all sub Assets at assetPath.
LoadAllAssetsAtPath         Returns an array of all Assets at assetPath.
LoadAssetAtPath         Returns the first asset object of type type at given path assetPath.
LoadMainAssetAtPath         Returns the main asset object at assetPath.

 

https://docs.unity3d.com/ScriptReference/AssetDatabase.LoadAssetAtPath.html

Share this post


Link to post
Share on other sites

No, lo probé. Pero es justo lo que buscaba, concretamente el que he utilizado y mejor me viene es el LoadAssetAtPath

Gracias @lightbug!!!!!

Share this post


Link to post
Share on other sites

Re-abro este post pq creo que es mejor seguir por este hilo el problema que me ocurre ya que viene de todo esto que hemos estado mirando...

Dejo este video abajo explicandolo todo pq creo que es mas comodo y rapido de explicar y entender para los demas. En resumen la Ventana Editor que programe me da problemas al cerrar y abrir Unity cuando esta ventana la dejo abierta. Unity crashea al cerrarlo. Y al abrirlo me pide reset el layout de ventanas para poder iniciar Unity.

En el codigo de la Ventana de Editor utilizo OnEnable() y OnDisable() para crear un profile y destruirlo cuando se abre o cierra la Ventana. Pero si cierro Unity con la Ventana abierta me da el problema.

Video

 

A ver si alguien sabe que ocurre y como solucionarlo, Saludos

 

Share this post


Link to post
Share on other sites
Sign in to follow this  

×
×
  • Create New...