Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

static List se resetea al entrar en Play Mode

Iniciado por Jose134, Septiembre 25, 2016, 03:02:57 PM

Tema anterior - Siguiente tema
Bueno pues estoy intentando hacer una pequeña extension para Unity en la cual tengo una lista estatica de una clase hecha por mi. He creado un EditorWindow donde añado y quito elementos a la lista pero cuando entro en PlayMode esta lista se resetea y se borran todos los elementos que tengo hechos. Os dejo mis scripts a ver si alguien sabe por que es
 
 
 
Clase de la que creo la lista
 

using UnityEngine;
public class ColorAsign {
    public string name;
    public Color32 color;
    public GameObject prefab;
    public ColorAsign (string name)
    {
        this.name = name;
        this.color = new Color32(, , , 255);
        this.prefab = null;
    }
}

 
 
 
Script en el que esta la lista
 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public static class ColorDB {
    public static List<ColorAsign> colors = new List<ColorAsign>();
    public static GameObject FindPrefab(Color color)
    {
        for (int i = ; i < colors.Count; i++)
        {
            if (colors[i].color == color)
            {
                return colors[i].prefab;
            }
        }
        return null;
    }
}

 
 
 
La EditorWindow
 

using UnityEngine;
using Unit***itor;
public class ColorAsignWindow : EditorWindow {
    private static ColorAsignWindow window;
    [MenuItem ("Window/LevelEditor: Color Asign")]
    private static void Init ()
    {
        window = (ColorAsignWindow)EditorWindow.GetWindow(typeof(ColorAsignWindow));
        window.Show();
    }
    private void OnGUI ()
    {
        for (int i = ; i < ColorDB.colors.Count; i++)
        {
            GUILayout.Label(ColorDB.colors[i].name);
            ColorDB.colors[i].name = EditorGUILayout.TextField("Name", ColorDB.colors[i].name);
            ColorDB.colors[i].color = EditorGUILayout.ColorField("Color", ColorDB.colors[i].color);
            ColorDB.colors[i].prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", ColorDB.colors[i].prefab, typeof(GameObject));
        }
        if (GUI.Button(new Rect(10, window.position.height - 65, window.position.width - 20, 25), "Add Color Asign"))
        {
            ColorDB.colors.Add(new ColorAsign("" + ColorDB.colors.Count));
        }
        if (GUI.Button(new Rect(10, window.position.height - 35, window.position.width - 20, 25), "Reset All Color Asign"))
        {
            ColorDB.colors.Clear();
        }
    }
}

 
 

Este código funciona en un script ExecuteInEditMode, y mantiene una variable al entrar y salir de PlayMode:
 

using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class Test : MonoBehaviour {
    public int[] numeros;
 
// Use this for initialization
void Start () {
        if (storage.numeros == null) storage.numeros = this.numeros;
        else this.numeros = storage.numeros;   
}

// Update is called once per frame
void Update () {

}
    void OnDestroy()
    {
        storage.numeros = this.numeros;
    }
}
public static class storage
{
    public static int[] numeros;
}

 
 

Cita de: kaito date=1474814398Este código funciona en un script ExecuteInEditMode, y mantiene una variable al entrar y salir de PlayMode:
   
   

using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class Test : MonoBehaviour {
    public int[] numeros;
 
// Use this for initialization
void Start () {
        if (storage.numeros == null) storage.numeros = this.numeros;
        else this.numeros = storage.numeros;   
}

// Update is called once per frame
void Update () {

}
    void OnDestroy()
    {
        storage.numeros = this.numeros;
    }
}
public static class storage
{
    public static int[] numeros;
}

   
       
   


Hice este codigo pero sigue sin funcionar, pasa exactamente lo mismo asi que supongo que sera otro de mis  scripts el que este causando el problema
 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
public class SaveDB : MonoBehaviour {
    private List<ColorAsign> colors;
    private void Start ()
    {
        if (ColorDB.colors == null)
        {
            ColorDB.colors = colors;
        }
        else
        {
            colors = ColorDB.colors;
        }
    }
    private void OnDestroy ()
    {
        ColorDB.colors = colors;
    }
}

 
 

Septiembre 25, 2016, 06:58:24 PM #3 Ultima modificación: Septiembre 25, 2016, 06:59:13 PM por hammer
No se mucho de esto, has probado con [Serializable] o con  [SerializeField] ???
 
https://blogs.unity3d.com/es/2012/10/25/unity-serialization/
 
 

La lista se resetea porqué la creas tú. Tienes que dejar que Unity la cree para que la serialice y así guarde el contenido. O derivas de MonoBehaviour o la haces serializable con [System.Serializable]

Cita de: hammer date=1474822704No se mucho de esto, has probado con [Serializable] o con  [SerializeField] ???
   
   
      https://blogs.unity3d.com/es/2012/10/25/unity-serialization/
   
   
       
   


 
 
Cita de: iRobb date=1474822773La lista se resetea porqué la creas tú. Tienes que dejar que Unity la cree para que la serialice y así guarde el contenido. O derivas de MonoBehaviour o la haces serializable con [System.Serializable]
   


Vale, he intentado asi:
 
ColorAsign.cs
 

using UnityEngine;
[System.Serializable]
public class ColorAsign {
    [SerializeField] public string name;
    [SerializeField] public Color32 color;
    [SerializeField] public GameObject prefab;
    public ColorAsign (string name)
    {
        this.name = name;
        this.color = new Color32(, , , 255);
        this.prefab = null;
    }
}

 
 
 
ColorDB.cs
 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class ColorDB {
    [SerializeField]
    public static List<ColorAsign> colors;
    public static GameObject FindPrefab(Color color)
    {
        for (int i = ; i < colors.Count; i++)
        {
            if (colors[i].color == color)
            {
                return colors[i].prefab;
            }
        }
        Debug.LogError("Not Found");
        return null;
    }
}

 
Peeeeeero sigue sin funcionar, es la primera vez que serializo algo asi que seguro que me he saltado algo pero no se el que

Pero, los campos estáticos no se pueden serializar, y segundo la lista no está inicializada por lo cual no vas a poder utilizarla.
 
Deberías serializar a byte y guardarlo dentro de un TXT o cualquier archivo y cada vez que vuelvas a utilizar la clase carga desde dicho archivo los datos de la lista.

Cita de: francoe1 date=1474837818Pero, los campos estáticos no se pueden serializar, y segundo la lista no está inicializada por lo cual no vas a poder utilizarla.
   
   
      Deberías serializar a byte y guardarlo dentro de un TXT o cualquier archivo y cada vez que vuelvas a utilizar la clase carga desde dicho archivo los datos de la lista.
   


La lista esta inicializada pero en uno de mis intentos random de arreglar el problema probe a inicializarla en el script de la EditorWindow.
 
 
 
Ya habia pensado lo de pasar la info a un txt pero qurria ver si se podia arreglar de una forma mas sencilla.
 
Como me interesa que la lista siga siendo estatica al final optare por el txt
 
 
 
Muchas gracias a todos por vuestra ayuda

Claro, si vos necesitas que la información perdure al cerrar Unity Apagar la PC u otros entonces requiere de que guardes la información en algún lugar. Si se trata de una herramienta fijate que podrias utilizar la misma carpeta del proyecto pero un nivel atrás  "../ASSETS" para entonces poder configurar de formas diferentes cada proyecto y pasar de proyecto en proyecto las cosas no se sobre escriban. 
 
 
 
 

Septiembre 25, 2016, 11:44:49 PM #9 Ultima modificación: Septiembre 26, 2016, 12:11:36 AM por kaito
@Jose134 Edito el código anterior:
 
 
 

using UnityEngine;
using System.Collections.Generic;
[ExecuteInEditMode]
public class Test : MonoBehaviour {
    public List<int> list;
    int numero = 0;
// Use this for initialization
void Start () {
        if(storage.list == null)
        {
            if (this.list == null) storage.list = this.list = new List<int>();
            else storage.list = this.list;
        } else
        {
            this.list = storage.list;
        }

}

// Update is called once per frame
void Update () {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            this.list.Add(this.numero++);
        }

}
    void OnDestroy()
    {
        storage.list = this.list;
    }
}
public static class storage
{
    public static List<int> list;
}

 
 
 
Este código, sigue funcionando tanto al entrar/salir PlayMode como cuando eliminas el componentes y lo vuelves a crear. Los datos se quedan almacenado en la variable de la clase estática.

Cita de: kaito date=1474839889@Jose134 Edito el código anterior:
   
   
       
   
   

using UnityEngine;
using System.Collections.Generic;
[ExecuteInEditMode]
public class Test : MonoBehaviour {
    public List<int> list;
    int numero = 0;
// Use this for initialization
void Start () {
        if(storage.list == null)
        {
            if (this.list == null) storage.list = this.list = new List<int>();
            else storage.list = this.list;
        } else
        {
            this.list = storage.list;
        }

}

// Update is called once per frame
void Update () {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            this.list.Add(this.numero++);
        }

}
    void OnDestroy()
    {
        storage.list = this.list;
    }
}
public static class storage
{
    public static List<int> list;
}

   
       
   
   
      Este código, sigue funcionando tanto al entrar/salir PlayMode como cuando eliminas el componentes y lo vuelves a crear. Los datos se quedan almacenado en la variable de la clase estática.
   


Muchas gracias pero ese script habria que añadirselo a un GameObject y como lo que estoy haciendo es un plugin me gustaria que fuera lo mas user-friendly posible y por tanto prefiero usar un txt y que asi el usuario no tenga que agregar un script extra en cada escena.
 
PD: disculpa por responder un poco tarde, no he tenido mucho tiempo para programar ultimamente
 
PD2: Para el que le interese aqui teneis una captura de como va la ventanita de mi plugin :P
 

Etiquetas: