x


Using JSON to get tree data into JavaScript objects

I am using JSON to transfer data back and forth between my database and my unity app. JSON is a nice alternative to XML that is faster.

Currently I am passing (variable depth acyclic) tree structures.

I have found a C# parser called litJSON that is compatible with all .net languages. An informative thread about this can be found at : http://answers.unity3d.com/questions/531/what-is-the-easiest-json-library-to-integrate-with-unity Here you may also find a useful script for getting the data out of the JSON string. All C# coders that are thinking about using JSON as a data carrier should check it out.

But alas, I can not get it to work. My problem is that i am trying to use JavaScript and I am not able to access the objects made in C#. (Is this possible?) I've been trying for three days, and I am stuck. Can anyone point me towards a simple way of building a tree structure of objects in javascript based on a JSON string? I am a bit confused because the JSON parsers out there promising to do this are all JavaScript, not Unity JavaScript, and the eval() function does not exist in Unity Javascript (or does it?).

How can I create a javascript object tree from JSON string (similar to eval()) at runtime.

more ▼

asked Jul 20 '10 at 08:26 AM

Jens T gravatar image

Jens T
138 6 7 17

irrelevant but i couldnt resist PRESS X TO JSON

Jul 24 '10 at 02:21 PM yeoldesnake 1
(comments are locked)
10|3000 characters needed characters left

3 answers: sort voted first

If the JSON parser script that you're trying to use is C#, and you're trying to access the results from Javascript, you are most likely running into the compilation order problem.

See this answer for details, but basically you may find that putting your JSON parser scripts into a new folder named "Plugins" (in your Assets folder), will solve your problem.

more ▼

answered Jul 20 '10 at 08:40 AM

duck gravatar image

duck ♦♦
41k 92 148 415

Thank you. I did, and I got it to work now. Cheers. And as I read in the documentation, i cant go both ways, something has to compile first. This means I cannot write to the console when in C# (placed in the plugin folder). Guess this is something I will have to live with.

Jul 21 '10 at 06:42 AM Jens T

Jens T - Would you mind posting a full solution to this problem yourself? I have to do this in the next few days, and a quick walkthrough would be immensely useful.

Jul 22 '10 at 05:29 AM grey

I will. I just have to do it first. Planning to do it next week. Decided to have sit-down with a friend of mine who is "The lord of code" or something. I am the "Lord of Datastructures". Together we control the matrix.

Jul 25 '10 at 06:31 AM Jens T
(comments are locked)
10|3000 characters needed characters left

Sorry for the delay everybody. Here is an simplified version of the parser*

Trying feeding it pure string first, then get it to work using a textasset. Then finally, try to get the WWW object coroutine bastard thing to work (with yield).

And you need a class called Component (Comp) to get this to work. It should implement the following methods : setParentComponent(Comp), getComponentName():String, and a few more, you will notice them in the code.

     class JsonParser
        {
            private var str : String = null;
            private var cix : int = 0;
            private var identifiers : String = "{}[],:";
            private var debug : boolean =false;
            private var arr:Array =  new Array();


        function Parse( json : String )
        {

            str = json;
            cix = 0;

            out( str );
        var componentRoot = new Comp();

        ReadObject(componentRoot);


        }
    function ReadObject(intoComp:Comp) : Array
        {
            str.Trim();

            while ( cix < str.length )
            {

                if ( ReadTo( "{" ) == "Component" )
                {

                    comp = ReadComponent(intoComp);
                    if ( comp ){

                        comp.setParentComponent(intoComp);
                        break;
                    }else{
                        Error( "Adding Assembly failed!" );
                        break;
                    }
                }
                else
                {
                    Error( "Assembly expected" );
                    return null;
                }

                if ( NextIdentifier() == "," ){
                    ReadTo(",");
                }
            }

        }

        function ReadComponent(parentComp :Comp) 
            {
                var comp : Comp = new Comp();
            //  Out("Adding new component under "+ parentComp.getComponentName()+);


                while ( ReadyAttribute() )
                {
                    var attrName = ReadTo( ":" );

                    switch( attrName )
                    {
                    case "name":
                        comp.setComponentName(ReadString());
                        break;

                    case "children":
                        ReadComponentChildren( comp);
                        break;


                    case "assetLink":
                        comp.setAssetLink(ReadString());
                        break;

                    case "x":
                        comp.setXoffset(ReadFloat());
                        break;
                    case "y":
                        comp.setYoffset(ReadFloat());
                        break;
                    case "z":
                        comp.setZoffset(ReadFloat());
                        break;  
                    case "h":
                        comp.setAYoffset(ReadFloat());
                        break;
                    case "p":
                        comp.setAXoffset(ReadFloat());
                        break;
                    case "b":
                        comp.setAZoffset(ReadFloat());
                        break;
                    default:
                        Error( "Unidentified Component attribue: '" + attrName + "'");
                        ReadToAny("},");
                        --cix;
                        break;
                    }
                }

                if ( NextIdentifier() == "}" )
                {
                    ReadTo( "}" );
                }
                else
                    Error( "'}' or ':' expected" );


            }

            function ReadComponentChildren( parent : Comp)
            {
                if ( NextIdentifier() == "[" )
                {
                    ReadTo("[");

                    while( NextIdentifier() != "]" )
                    {
                        var objName = ReadTo( "{" );

                        switch( objName )
                        {           

                        case "Component":
                            ReadComponent(parent);
                            componentsAdded ++;
                            break;


                        if ( NextIdentifier() == "," ){
                            ReadTo( "," );
                        }
                    }
                    ReadTo("]");
                }
                else
                {
                    Error( "'[' expected");
                }
            }


            function ReadTo( identifier : String )
            {
                var pos : int       = str.IndexOf( identifier, cix );       // Find first occurance of identifier after current position.
                var length : int    = pos - cix;                            // Find distance from current position to identifier ( size of substring )
                var result : String = str.Substring( cix, length ).Trim();  // Get substring and remove whitespace.
                cix = pos + 1;                                              // Update current position to include identifier.

                out( "Read: " + result );
                return result;
            }

            function ReadToAny( identifiers : String )
            {
                var pos : int        = str.IndexOfAny( identifiers.ToCharArray(), cix );
                var length : int     = pos - cix;
                var result : String = str.Substring( cix, length ).Trim();  
                cix = pos + 1;  

                out( "Read: " + result );

                return result;
            }


            function NextIdentifier()
            {
                if (cix < str.Length){
                    var pos : int       = str.IndexOfAny( identifiers.ToCharArray(), cix );
                    if (pos < str.Length){
                        var result : char   = str.Chars[pos];
                        return result;
                    }
                }

            }


            function ReadString()
            {
                var begin : int     = str.IndexOf( "\"", cix ) + 1;
                var end : int       = str.IndexOf( "\"", begin );
                var length : int    = end - begin;

                var string : String = str.Substring( begin, length );
                cix = end + 1;

                out( "String: " + string );

                return string;
            }

            function ReadInteger()
            {
                var numbers : String    = "0123456789-";
                var delimit : String    = " ,\n]}";
                var begin : int         = str.IndexOfAny( numbers.ToCharArray(), cix );
                var end : int           = str.IndexOfAny( delimit.ToCharArray(), begin );
                var length : int        = end - begin;

                var numStr : String     = str.Substring( begin, length );
                var valueAsFloat :float     = parseFloat( numStr );
                var value:int = Mathf.Floor(valueAsFloat);
                cix = end;

                out( "Integer: " + value );

                return value;
            }

            function ReadFloat()
            {
                var numbers : String    = "0123456789.-";
                var delimit : String    = " .\n}]";
                var begin : int         = str.IndexOfAny( numbers.ToCharArray(), cix );
                var end : int           = str.IndexOfAny( delimit.ToCharArray(), begin );
                var length : int        = end - begin;
                var numStr : String = str.Substring( begin, length );
                var value : float       = parseFloat( numStr );

                cix = end;

                out( "Float: " + value );

                return value;
            }
            function ReadBoolean():boolean{

                var numbers : String    = "0123456789.-";
                var delimit : String    = " .\n}]";
                var begin : int         = str.IndexOfAny( numbers.ToCharArray(), cix );
                var end : int           = str.IndexOfAny( delimit.ToCharArray(), begin );
                var length : int        = end - begin;
                var value : String  = str.Substring( begin, length );

                switch (str){
                            case  "true" :
                            cix = end;
                            return true;
                    break;
                            case  "false" :
                            cix = end;
                            return false;
                    break;

                }


                out( "Float: " + value );


            }

            function ReadyAttribute()
            {       
                if ( NextIdentifier() == "," )
                    cix = str.IndexOf(",", cix) + 1;

                if ( NextIdentifier() == ":" )
                    return true;

                if ( NextIdentifier() == "}" )
                    return false;
            }

            function Error( msg : String )
            {
                    Debug.Log( "ERROR: " + msg + " at (" + cix + ") : " + str.Substring( cix, Mathf.Min( str.length - cix, 100) ).Trim() + "..." );
            }
            function Warning( msg : String )
            {
                    Debug.Log( "Warning: " + msg + " at (" + cix + ") : " + str.Substring( cix, Mathf.Min( str.length - cix, 100) ).Trim() + "..." );
            }
            function out(msg:String){
                if(debug){
                    Debug.Log( "MESSAGE: " + msg + " at (" + cix + ") : " + str.Substring( cix, Mathf.Min( str.length - cix, 100) ).Trim() + "..." );
                }
            }
}
more ▼

answered Sep 21 '10 at 06:10 AM

Jens T gravatar image

Jens T
138 6 7 17

Hi! can you please give me a sample of the Component (Comp) class??

Aug 29 '11 at 04:55 PM yuriythebest
(comments are locked)
10|3000 characters needed characters left

I've also written a simple parser, which I think might be easier to use. It's up on the UnifyCommunity Wiki. Check it out.

more ▼

answered Oct 15 '10 at 09:17 PM

scone gravatar image

scone
17 5

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3460
x256
x108
x66
x16

asked: Jul 20 '10 at 08:26 AM

Seen: 7385 times

Last Updated: Aug 29 '11 at 04:55 PM