unity3d | scripting | getting started questions - JS and XML

hi @all,

I have a few guetting started questions, that I wasn’t able to answer on the fly.
(I really did try my best. :))

  1. Is there another way of executing (triggering) scripts, in addition than linking it to a specific object?

  2. Is there a manual way to trigger the “Code-Debugger” for Javascript?

  3. Do I include a Class file by creating a script and then replacing the Update-Function?
    Or how do I include a JS-Class the right way?

  4. For Javascript, are all of the DOM-Functions avaliable, or where can I find a function manual?

  5. I’m trying to read from an XML-File. For this I found a great Thread:
    http://forum.unity3d.com/threads/25352-Loading-an-XML-file
    But the Code in there is not working. I used the Code posted by HiggyB (xml_662.zip)
    I get the following error-message: "Cannot convert ‘System.Array’ to ‘System.Collections.Hashtable
    Am I implenting the Class the wrong way or is it a Bug due to Engine-Update or something like that?

Please Help! :slight_smile:

You can call functions from scripts/classes that aren’t linked to anything. (But the script doing the call needs to be linked to something, such as an empty ‘gameController’ object).

Filename needs to be same as class name:

class Hello{
    var mytext = "Hello World";
    function log(){
        Debug.Log(mytext);
    }
}

In another script (attached to an object):

var hello = Hello();
hello.log();

Probably not, since Unity ‘javascript’ is not true javascript. It’s closer to .NET JSCRIPT, so search for some documentation on that.

It sounds like you’re trying to convert an array to a hashtable, which you can’t do, unless the array contains nested or staggered key/value pairs and you’re taking that into account when you parse them into a hashtable.

Thanks. :slight_smile:

I’m trying another Code (Parser) from the post.
the one from this site: http://www.roguishness.com/unity/

I’m trying to open an XML like this:

function Update () {
    
    var tWWW = new WWW("http://files.unity3d.com/tom/orbitsim/XML/SolarSystem.xml");
    yield tWWW;
    
    if (tWWW.error != null)  {
        Debug.Log( "error: could not retrieve xml data from url given" );
    } 
    else {
        parser         = new XMLParser(); 
        var node    = parser.Parse( tWWW.text ); 
        Debug.Log( "hello" );
    }
}

This codes outputs the following error: Update() can not be a coroutine.
? I don’t get it. It’s a new error message. What am I doing wrong?

You can’t use ‘yield’ during an Update call. It must be used in a coroutine:

http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html

thx!

what i’m trying to do as first “application” or “game”.
read values from an xml file and create an easy 3d-bar-chart.

so my first test-application has nothing to do with a game directly.
but maybe an similar approach someone would do, if the user-game
settings where stored in a xml-file.

i will post my code, as soon as it is finished.
(probably will take some time. ;))

questions that i would like to ask:

  1. wich class do I need if I wanted to create a cube interactively per script?
    (do you have some hints or small examples?)

  2. how do i implement the “sleep” function (yield) the right way? (I’m still trying to make it work…)
    problems that i’m confronting:
    the 3d bar chart should look like an animation, i just can’t say cube, your that big and that’s it!

greetings

ok. so i got the sleep-yield thing working.

just didn’t get the whole update/main function thinggie at first.
here’s the code i’ve got so far,
it’s not finished and polished, and xml is still not working!
(and it has a bug i think… but it works. ^^)

is there someone with experience in with the xml-parser from this site?:
http://www.roguishness.com/unity/
i’m trying to get the values from this xml fie:
http://files.unity3d.com/tom/orbitsim/XML/SolarSystem.xml

static var values = new Array();
MainG();

/* MainG */
/*************************************************************************************************/
function MainG () {
	Debug.Log( "1. getXMLValues" );
	getXMLValues();
	Debug.Log( "2. sleep" );
	yield WaitForSeconds (2);
	Debug.Log( "3. doIt" );
	yield doIt();
	Debug.Log( "4. this is the end." );
}

/* getXMLValues */
/*************************************************************************************************/
function getXMLValues () {
	
    var xml = new WWW("http://files.unity3d.com/tom/orbitsim/XML/SolarSystem.xml");
	yield xml;
	
    if (xml.error != null)  {
        Debug.Log( "error: could not retrieve xml data from url given" );
    }
    else {
        parser 		= new XMLParser();
        var node 	= parser.Parse( xml.text );
		var val 		= node["system"][0]["body"][1]["mass"];
		Debug.Log( val );
    }
	
	values[0] = 1.9891;
	values[1] = 3.3022;
	values[2] = 4.8685;
	values[3] = 5.9736;
	values[4] = 6.4185;
	values[5] = 7.1235;
}

/* doIt */
/*************************************************************************************************/
function doIt () 
{
	Debug.Log( "Cube1: " + values[0] );
	resizeCube( "Cube1", values[0] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube2: " + values[1] );
	resizeCube( "Cube2", values[1] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube3: " + values[2] );
	resizeCube( "Cube3", values[2] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube4: " + values[3] );
	resizeCube( "Cube4", values[3] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube5: " + values[4] );
	resizeCube( "Cube5", values[4] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube6: " + values[5] );
	resizeCube( "Cube6", values[5] );
	yield WaitForSeconds(0.5);
}

/* resizeCube */
/*************************************************************************************************/
function resizeCube( objectName, value ) {
	
	var oldScale = 1;
	var newTarget;
	var newPos;
	
	newTarget 	= GameObject.Find( objectName ).transform;
	newTarget.localScale = new Vector3( newTarget.transform.localScale.x, value, newTarget.transform.localScale.z );
	
	newPos = ( ( oldScale - ( oldScale * value ) ) / 2);
	if( newPos < 0 ) newPos = newPos * -1;
	newTarget.position = new Vector3( newTarget.position.x, newPos, newTarget.position.z );
}

greetz

… so, here’s my first test-app! thx very much!!
the script is not fully dynamic, because i couldn’t really find some good examples or approaches regarding this issue.

install/scene setup:

create 5 cubes.
rename meshes: Cube1, Cube2, Cube3, Cube4, Cube5
create JavaScript and paste following code.
attach script to scene camera or something.

static var values = new Array();
MainG();

/* MainG */
/*************************************************************************************************/
function MainG () {
	
	Debug.Log( "1. getXMLValues" );
	getXMLValues();
	
	Debug.Log( "2. sleep" );
	yield WaitForSeconds (2);
	
	Debug.Log( "3. doIt" );
	yield doIt();
	
	Debug.Log( "4. this is the end. my only friend. the end." );
}

/* getXMLValues */
/*************************************************************************************************/
function getXMLValues () {
	
    var xml = new WWW("http://files.unity3d.com/tom/orbitsim/XML/SolarSystem.xml");
	yield xml;
	
    if (xml.error != null)  {
        Debug.Log( "error: could not retrieve xml data from url given" );
    }
    else {
		
        parser 		= new XMLParser();
        var node 	= parser.Parse( xml.text );
		var temp;
		
		//if( !isNaN( node["system"][0]["body"][0]["@mass"] ) )
		temp = node["system"][0]["body"][0]["@mass"];
		values[0] = parseFloat( temp.Substring( 0, temp.LastIndexOf("e") ) );
		
		temp = node["system"][0]["body"][1]["@mass"];
		values[1] = parseFloat( temp.Substring( 0, temp.LastIndexOf("e") ) );
		
		temp = node["system"][0]["body"][2]["@mass"];
		values[2] = parseFloat( temp.Substring( 0, temp.LastIndexOf("e") ) );
		
		temp = node["system"][0]["body"][3]["@mass"];
		values[3] = parseFloat( temp.Substring( 0, temp.LastIndexOf("e") ) );
		
		temp = node["system"][0]["body"][4]["@mass"];
		values[4] = parseFloat( temp.Substring( 0, temp.LastIndexOf("e") ) );
    }
}

/* doIt */
/*************************************************************************************************/
function doIt () 
{
	Debug.Log( "Cube1: " + values[0] );
	resizeCube( "Cube1", values[0] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube2: " + values[1] );
	resizeCube( "Cube2", values[1] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube3: " + values[2] );
	resizeCube( "Cube3", values[2] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube4: " + values[3] );
	resizeCube( "Cube4", values[3] );
	yield WaitForSeconds(0.5);
	
	Debug.Log( "Cube5: " + values[4] );
	resizeCube( "Cube5", values[4] );
	yield WaitForSeconds(0.5);
}

/* resizeCube */
/*************************************************************************************************/
function resizeCube( objectName, value ) {
	
	var oldScale = 1;
	var newTarget;
	var newPos;
	
	newTarget 	= GameObject.Find( objectName ).transform;
	newTarget.localScale = new Vector3( newTarget.transform.localScale.x, value, newTarget.transform.localScale.z );
	
	newPos = ( ( oldScale - ( oldScale * value ) ) / 2);
	if( newPos < 0 ) newPos = newPos * -1;
	newTarget.position = new Vector3( newTarget.position.x, newPos, newTarget.position.z );
}

todo:
edit resizeCube so the resizing looks like an animation. (non-linear)

links that helped:

XML
http://forum.unity3d.com/threads/25352-Loading-an-XML-file

Yield
http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html

Dynamic Mesh Creation Approaches-Reference
http://forum.unity3d.com/threads/43421-Create-a-dynamic-mesh-%28cube%29
http://forum.unity3d.com/threads/11112-Splitting-a-Mesh?p=413802
http://unity3d.com/support/documentation/ScriptReference/Mesh.html
http://unity3d.com/support/documentation/ScriptReference/Mesh-bounds.html
http://unity3d.com/support/documentation/ScriptReference/Mesh-uv.html

JavaScript questions that remained:

  1. how can i easily debug an array (vector, etc.)?
  2. how can i create a dynamic mesh? or how do i easily debug the uv’s, vertices, etc. of an existing object?
  3. what are the typecast functions available (specifically, how can i typecast an exponential value)?

thx
regards

You might find it easiest to use MonoDevelop to debug your code. It has a source level debugger, so you can see the values of variables when you pause the code.

The Mesh class (which you’ve already found) is what you use to create a new mesh. The doc page has several examples of how to do this and there is also some code in the procedural examples project. I’ve found that a useful quick way to check out the vertex positions before the geometry is added is simply to draw lines between each pair of vertices (as if there is a single length of stiff wire bent around all of them):-

function SingleWireView() {
	var mf = GetComponent(MeshFilter);
	var verts = mf.mesh.vertices;
	
	var prevPoint = transform.TransformPoint(verts[0]);
	
	for (i = 1; i < verts.Length; i++) {
		var currPoint = transform.TransformPoint(verts[i]);
		Debug.DrawLine(currPoint, prevPoint);
		prevPoint = currPoint;
	}
}

I don’t really know what you mean by an exponential value. Do you mean a float? There are a few ways to convert a float to an integer, depending on what you want to do. Check out the functions of the Mathf class that look like XXXToInt (eg, FloorToInt).

@andeeee: thx very much!!

with exponential value, i meant such a value: 3.3022e23.0.
(http://files.unity3d.com/tom/orbitsim/XML/SolarSystem.xml)

but not that important… i found a way to still make it work. :slight_smile: