how to use Serializable?

Hi everybody!

I Try to use a serializable in a singleton to make an automatic button creator, so I write it in my “Controller” script, I create my list in the unity editor, and I wanted to get the name and the material to an other script I attached it in a prefab button I would instanciate as many tyme as I indicated in the list of type.

so here is my questions:

how to get the info to the other code?
and
how to instanciate as many button that I indicate in the unity editor list?

here’s my code:

using UnityEngine;

using System;

using System.Collections;

using System.Collections.Generic;




public class manager : MonoBehaviour {

	public static manager instance = null;
	
	#region Singleton

		
	public static manager Instance{

			get{
			
					if (instance == null) 
				instance = GameObject.FindObjectOfType (typeof(manager)) as manager;
					if (instance == null) {
					
							var go = new GameObject ("Controller");
				go.AddComponent<manager> ();
				instance = go.GetComponent<manager>();
					}
						return instance;
				
				}
			
			}

	
	[Serializable]
	public class categoriesMateriaux{
		public string nom;
		public List<materiau> materiaux;
	}
	
	[Serializable]
	public class materiau{
		public string nom;
		public UITexture logo;
		public Material mat;
	}

	
	public List<categoriesMateriaux> categoriesDeMateriaux;
	
	
	void OnApplicationQuit ()
	{
		
		instance = null;
		
	}

	#endregion Singleton
	
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	// UI
	
	public void change_texture(){
		
	}
}

thanks

Well, since it’s a singleton you can simply do:

Material m = manager.Instance.categoriesDeMateriaux[1].materiaux[3].mat;

This would access the “mat” of the 4th “materiau” in the 2nd category. However i guess you want to access your things by name instead of an index. You could add this method to your manager:

public materiau FindMat(string aCategory, string aName)
{
    foreach(var cat in categoriesDeMateriaux)
    {
        if (cat.nom == aCategory)
        {
            foreach(var m in cat.materiaux)
            {
                if (m.nom == aName)
                    return m;
            }
        }
    }
    
    // instead of throwing an exception you can also return null
    // but you have to handle errors when you execute the method
    throw new System.Exception("Can't find material " + aName + " in category " + aCategory );
    //return null;
}

With that method you can simply do:

materiau m = manager.Instance.FindMat("some category name", "Some material name");
renderer.sharedMaterial = m.mat;

Note: The names are case sensitive, so watch out how you spell them.

There are some other things i should mention:

  • First your singleton is required to exist already in the scene, so it makes no sense to create an instance when it’s not found. When you create the instance at runtime the “categoriesDeMateriaux” List would be null.
  • Class names should always start with an uppercase letter. So your classes should be named “Manager”, “CategoriesMateriaux” and “Materiau”. This is one of the most important style-rules otherwise you can confuse them with variable names.
  • Because of the last point you now have a pronlem. categoriesDeMateriaux is your classname but you named your public List the same. You can’t use class names as variable names.
  • Even i don’t speak frensh (i just guess it’s frensh) the name “categoriesMateriaux” seems wrong for that class (besides the first letter). The class represents one single category so it’s name should be singular, not plural. The public list of that class should be plural as it contains multiple category-class-instances.
  • In C# method names also start with a capital letter. methods can’t be confused that easy with class names since you would have “()” behind it when you call it. That’s not that important but it’s always goot to have everything consistent across your project. All Unity methods / callbacks start with a capital letter so it would be the best to stick to that scheme.
  • In unity it’s generally not recommended to put a “using System;” at the top since the System namespace and the UnityEngine namespace have some classes with the same names like “Random” and “Object”. Since you need the System namespace only in some rare cases it’s better to use the full name at these places. So just remove the using System; and replace [Serializable] with [System.Serializable]

Ok thanks a lot for the help and for the advice.

can I ask another question?

how can I do to create a gameobject by list and by sublist? but I want the sublist gO in children of the list gO