Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Unity, C#, XML and Custom Editor: Handling Atlas textures for 2D game

Discussion in 'Scripting' started by Learner, Jul 7, 2013.

  1. Learner

    Learner

    Joined:
    Dec 13, 2008
    Posts:
    91
    Hi Unity users,

    I am playing around with Unity, C#, XML and custom editor and to be honest I am totally lost. So far I was able to load a XML file and parse it. Also I got some results customizing the editor. What I can not do is to integrate both, I mean how to display the result of XML file in the custom inspector. What I have done so far and what I want to do is this:

    1. I already have an Atlas texture (1024x1024) made in Adobe Fireworks with all images I need for a 2D game
    2. I successfully exported the information of the images in XML format
    3. I created a class (LoadXML) in Unity that can read the XML file and stores the result in a Dictionary variable with a format like this: ImageName (KEY): { x, y, width, height}
    4. I have another class (SetUV) that uses the position of the image (x,y) and the dimensions of the image (width, height) in the Atlas texture to calculate the Scale and OffSet of the material
    5. What I want to do is to run LoadXML class ONCE and use the information stored in the Dictionary variable each time I attach the custom editor script to the objects in the scene to select their image (I am thinking to do this filling a EditorGUILayout.Popup with the KEYs from the Dictionary) and calculate the Scale and OffSet of the material.

    Any idea how I can do that?

    I will appreciate your help

    Regards

    Learner
     
  2. VeryThiefLike

    VeryThiefLike

    Joined:
    Jul 4, 2013
    Posts:
    8
    Hey Learner,

    You could load that information onto a game object that has the data behaviour class . Like AtlasData : Monobehaviour or something. And any class that uses the textures, for example Sprite : Monobehaviour, it simply needs have a reference slot that lets you use it. That way data is loaded once, but can be used multiple times.

    The only limitations is that Dictionary won't serialize on the editor side. So you'll need to the store your texture sources as a list of string names and a list of texture sources. That will also give you the list of strings you can use for EditorGUILayout.Popup. The index of the string can then be used to reference the texture source when used in the editor. At runtime, in Awake you can convert them to Dictionary for increased performance.

    Forgive any mistakes, this was a quick bash.
    Code (csharp):
    1. using UnityEngine;using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5.  
    6. public class AtlasData : MonoBehaviour {
    7.     [Serializable]
    8.     public class TextureSource
    9.     {
    10.         public int index;
    11.         public string name;
    12.         public Rect rect;
    13.     }
    14.    
    15.     [SerializeField, HideInInspector]
    16.     private List<string> _names;
    17.     public List<string> names {
    18.         get { return _names; }    
    19.     }
    20.     [SerializeField, HideInInspector]
    21.     private List<TextureSource> _sources;
    22.     public List<TextureSource> sources
    23.     {
    24.         get { return _sources; }
    25.     }
    26.    
    27.     private Dictionary<string, int> _runtimeTable = null;
    28.    
    29.     public TextureSource this[int index]
    30.     {
    31.         get { return _sources[index]; }
    32.     }
    33.    
    34.     public TextureSource this[string name]
    35.     {
    36.         get {
    37.             if(_runtimeTable != null) {
    38.                 return _sources[_runtimeTable[name]];
    39.             }
    40.            
    41.             for(int i = 0; i < _names.Count; i++) {
    42.                 if(_names[i] == name) return _sources[i];
    43.             }
    44.            
    45.             return null;
    46.         }
    47.     }
    48.    
    49.     void Awake() {
    50.         // create the runtime table to quickly get sources at runtime
    51.         _runtimeTable = new Dictionary<string, int>();
    52.         for(int i = 0; i < _names.Count; i++) {
    53.             _runtimeTable.Add(_names[i], i);
    54.         }
    55.     }
    56.    
    57.     public void LoadXml(string xmlFile)
    58.     {
    59.         // DO FILE LOADING
    60.     }
    61. }
    62.  
    63.  
    64. public class Sprite : MonoBehaviour
    65. {
    66.     public AtlasData atlas;
    67.     public int textureSource = -1;
    68.    
    69.     [SerializeField, HideInInspector]
    70.     private Mesh sourceMesh;
    71.    
    72.     public bool SetSource(string name)
    73.     {
    74.         if(!atlas) return false;
    75.        
    76.          AtlasData.TextureSource source = atlas[name];
    77.        
    78.         // DO TEXTURE MESH SET UP!
    79.        
    80.         return true;
    81.     }
    82. }
    There is also heaps of discussion on texture atlas and sprite sheets in the forum. Search for some of them and it should help solidify some concepts.

    Hope that helped!
     
    Last edited: Jul 7, 2013
  3. Learner

    Learner

    Joined:
    Dec 13, 2008
    Posts:
    91
    Thanks arcan3artist for your helpful response. I have a doubt about the first part of your answer. You said to attach the script (LoadXML) to a game object to be accessed from any script but how this works with a custom inspector? I mean, the idea is to use the information from XML file to calculate the UVs before to play the game, from the custom inspector.

    Thanks again

    Learner
     
  4. Learner

    Learner

    Joined:
    Dec 13, 2008
    Posts:
    91
    Guys, let me change my questions:

    1. If I have a Custom Inspector Script which is typeof a class that loads a XML file (lets call it LoadXML), is it possible to access variables, for instance a Dictionary, in the LoadXML class from the Custom Inspector Script? If so, how?
    2. If it is possible to do what I mentioned in point 1, it is possible too to access the Custom Inspector script from another Custom Inspector script and access variables with information obtained from the XML file?

    Thanks in advance for your answers

    Learner