Pulling C# into Javascript.

Hi, first thing I should admit to is that my scripting skills are severely lacking, usually consisting of pulling from tutorials and tweaking here and there, while crossing my fingers.

What I am trying to achieve here is to have, the X and Y co-ordinates which are being pulled from the ‘WiiMote’(C#) script into the ‘shoot’(javascript). This defines the co-ordinates that my projectile are being shot to.

I have put the WiiMote script in to Standard Assets as instructed here: Unity - Scripting API:

but I think Im falling down at working out the correct way to write the lines in the Javascript, searched around on the forums and tried various different approaches but I’m not having any luck.

The first and relevant (I think) parts to the WiiMote script looks like:

and I am trying to pull out the ‘wiimote_getIrX’ and ‘wiimote_getIrY’ with the Javascript, which looks like:

Both scripts are on the same game object (“First Person Controller)”. I am getting "unknown identifier ‘wiimote_getIrX’ " and "unknown identifier ‘wiimote_getIrY’ " errors in the console.

Any advice or guidance would be greatly appreciated please.

little bump…

Been fiddling further but still failing.

Slightly worried that this doesn’t make sense to anyone hence the lack of response? :frowning:

All the WiiMote functions appear to be static, so you don’t need to use GetComponent, or even attach the script to an object. You just need to qualify them with the class name:-

var x: float = WiiMote.wiimote_getIrX(0);

Thanks, this sorted any scripting errors, though now I have the Javascript taking the data from the C# it doesn’t seem to update (i.e. it will just stay at -100, the default value).

I have instead try to access the cursor_x and cursor_y variables instead (initially they were private, though I changed them to public).

    private string display;
    public int cursor_x, cursor_y;
    private	Texture2D cursor_tex;
    private Vector3 oldVec;

this is giving me an error saying

in the javascript the variable is written as:

var IRx: int = WiiMote.cursor_x(0);
var IRy: int = WiiMote.cursor_y(0);

Any pointers would be greatly appreciated.

The error you’re gettign is because the JS can’t find the script, either because it’s not attached to an obj or you’re not letting the js know which object it’s on or that the cs script isn’t being compiled before the js.

Check that you have it attached to an object and that your js is finding it:

var scriptToaccess : Transform;
myX : int = 0;
myY : int = 0;
function somefunction();
{
Debug.Log("Cursor x = "+scriptToaccess.cursor_x+" Cursor y = "+scriptToaccess.cursor_x);
myX = scriptToaccess.cursor_x;
myY = scriptToaccess.cursor_y;
Debug.Log("myX = "+myX+" myY = "myY);
}

Using this method when you attach your js to an object, the inspector will let you choose which object has the cs attached to it and you can call functions, read and write variables from/to the cs to your heart’s delight.

I always place my js files in the project root and the cs ones in a scripts (usually \Assets\Standard Assets\Scripts) folder to ensure they get compiled first.

Ok, thanks very much! Think I’m following, my WiiMote script is definitely compiling first, I have it in standard Assets/scripts, and my bullet script is in the root.

I’ve just edited my code to look like:

//var projectile : Rigidbody;
//var speed = 20;
//var IRx: int = WiiMote.cursor_x(0);
//var IRy: int = WiiMote.cursor_y(0);

var WiiMote : PlayerGun.Transform; 
myX: int = 0; 
myY: int = 0; 


function Update() 
{ 
Debug.Log("Cursor x = "+WiiMote.cursor_x+" Cursor y = "+WiiMote.cursor_y); 
myX = WiiMote.cursor_x; 
myY = WiiMote.cursor_y; 
Debug.Log("myX = "+myX+" myY = "myY); 
} 

/*	
function Update ()
{
if( Input.GetButtonDown( "Fire1" ) )
		{		
		var instantiatedProjectile : Rigidbody = Instantiate(
				projectile, Vector3(myX, myY, transform.position.z), transform.rotation );
				
			instantiatedProjectile.velocity =
			transform.TransformDirection( Vector3( 0, 0, speed ) );

		Physics.IgnoreCollision( instantiatedProjectile. collider,
			transform.root.collider );
				
				}
}

*/

Most of it is commented out for now as you can see.

But I am getting an error saying “expecting EOF, found myX”.

I thought EOF = End of Function…

I’m guessing this is something glaringly obvious, and thank you for your patience with my incapable self.

could be a couple of things, add var infront of the myX: int and myY : int declarations…

The error is usually to do with missing } at the end of a function, yours all appear to be paired in this script however…

Ahh, just re-read through and you’ve put:

var WiiMote : PlayerGun.Transform;

change to:

var WiiMote : Transform;

Then in the inspector you’ll see a selection for WiiMote which you want to pick the PlayGun object for…

Then the rest of the script will know what

myX = WiiMote.cursor_x

is referenced in!

I’d still put var infront of the myX and myX declarations too…

So close…!

Ok, I don’t have the WiiMote option in the inspector (for the javascript) at the moment, I’m not too sure why…

var WiiMote : Transform; 
var myX: int = 0; 
var myY: int = 0; 


function Update() 
{ 
Debug.Log("Cursor x = "+WiiMote.cursor_x+" Cursor y = "+WiiMote.cursor_y); 
myX = WiiMote.cursor_x; 
myY = WiiMote.cursor_y; 
Debug.Log("myX = "+myX+" myY = "+myY); 
}

Is what I have, and the error it’s reading out is now:

‘cursor_x’ is not a member of ‘UnityEngine.Transform’
‘cursor_y’ is not a member of ‘UnityEngine.Transform’
‘cursor_x’ is not a member of ‘UnityEngine.Transform’
‘cursor_y’ is not a member of ‘UnityEngine.Transform’

(one error for each mention of cursor_x/cursor_y in the script.)

Is this because the transform variable isn’t connecting to the WiiMote script?

Right, select the object that has your menu js attached, and youll see the menujs script in the inspector… If you open that roolout (if its not already expanded) you’ll see a controller labelled WiiMote with an empty transform next to it…Select the dropdown and pick the object (PlayerGun) that has your wiimote script attached…

Now when you run your app in the editor your menuscript can find the wiimote script without doing gameobject.find as you’ve already told it which GO has the script on :slight_smile:

Ok, realised what I had done. I had two scripts with the same names (an older version, I thought I had deleted it) and it was this older version attached to the object.

Now however, I can’t attach the script due to a not finished compiling error.

(still reading out the not a member errors as before).

Once again, thanks for your help.

It shouldn’t be generating compiler errors before the editor is running, as those calls aren’t checked until the thing is run. Then you would just get the missing reference error.

If you want to send me your scripts I’ll have a look see if I can find where it’s falling over.

Ok, closed and opened unity, to see if it would “compile”.

“Can’t add script behaviour bullet. You need to fix all compile errors in all scripts first!”

263108–9469–$wiimote_834.cs (4.07 KB)
263108–9470–$bullet_133.js (259 Bytes)

Here you go:
Make sure you rename your wiimote.cs to WiiMote.cs (Won’t compile if the name is different to the class inside)

Here’s bullet.js, attach to whatever you like, click in the inspector and change the target to the object containing the wiimote script:

import System;
var myX: int=6; 
var myY: int=6; 
var target : Transform;

function Start() 
{ 
var wm = target.gameObject.GetComponent(WiiMote);


Debug.Log("Cursor x = "+wm.cursorX+" Cursor y = "+wm.cursorY); 
myX = wm.cursorX; 
myY = wm.cursorY;  
Debug.Log("myX = "+myX+" myY = "+myY);
wm.CommsTest();
}

I’ve put some confirmation debug info in there and I run a Dummy function that you can put into the wiimote cs to output that the js has found it… just replace the wiimote script with the following:

using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;

public class WiiMote : MonoBehaviour {

    [DllImport ("UniWii")]
    private static extern void wiimote_start();

    [DllImport ("UniWii")]
    private static extern void wiimote_stop();

    [DllImport ("UniWii")]
    private static extern int wiimote_count();

    [DllImport ("UniWii")]
    private static extern byte wiimote_getAccX(int which);
    [DllImport ("UniWii")]
    private static extern byte wiimote_getAccY(int which);
    [DllImport ("UniWii")]
    private static extern byte wiimote_getAccZ(int which);

    [DllImport ("UniWii")]
    public static extern float wiimote_getIrX(int which);
    [DllImport ("UniWii")]
    public static extern float wiimote_getIrY(int which);
    [DllImport ("UniWii")]
    private static extern float wiimote_getRoll(int which);
    [DllImport ("UniWii")]
    private static extern float wiimote_getPitch(int which);
    [DllImport ("UniWii")]
    private static extern float wiimote_getYaw(int which);

    private string display;
    public int cursorX =5;
	public int cursorY =5;

    private	Texture2D cursor_tex;
    private Vector3 oldVec;
    
    // Use this for initialization
    void Start () {
        wiimote_start();
        cursor_tex = (Texture2D) Resources.Load("crosshair");
    }

    // Update is called once per frame
    void FixedUpdate () {
        int c = wiimote_count();
        if (c>0) {
            display = "";
            for (int i=0; i<=c-1; i++) {
                int x = wiimote_getAccX(i);
                int y = wiimote_getAccY(i);
                int z = wiimote_getAccZ(i);
                float roll = Mathf.Round(wiimote_getRoll(i));
                float p = Mathf.Round(wiimote_getPitch(i));
                float yaw = Mathf.Round(wiimote_getYaw(i));
                float ir_x = wiimote_getIrX(i);
                float ir_y = wiimote_getIrY(i);
                display += "Wiimote " + i + " accX: " + x + " accY: " + y + " accZ: " + z + " roll: " + roll + " pitch: " + p + " yaw: " + yaw + " IR X: " + ir_x + " IR Y: " + ir_y + "\n";
                if (!float.IsNaN(roll)  !float.IsNaN(p)  (i==c-1)) {
                    Vector3 vec = new Vector3(p, 0 , -1 * roll);
                    vec = Vector3.Lerp(oldVec, vec, Time.deltaTime * 5);
                    oldVec = vec;
//                    GameObject.Find("wiiparent").transform.eulerAngles = vec;
                }
                if ( (i==c-1)  (ir_x != -100)  (ir_y != -100) ) {
                        //float temp_x = ((ir_x + (float) 1.0)/ (float)2.0) * (float) Screen.width;
                        //float temp_y = (float) Screen.height - (((ir_y + (float) 1.0)/ (float)2.0) * (float) Screen.height);
                        float temp_x = ( Screen.width / 2) + ir_x * (float) Screen.width / (float)2.0;
                        float temp_y = Screen.height - (ir_y * (float) Screen.height / (float)2.0);
                        cursorX = Mathf.RoundToInt(temp_x);
                        cursorY = Mathf.RoundToInt(temp_y);
                }
            }
        }
        else display = "Press the '1' and '2' buttons on your Wii Remote.";
    }
    
    void OnApplicationQuit() {
        wiimote_stop();
    }
    
    void OnGUI() {
        GUI.Label( new Rect(10,10, 500, 100), display);
        if ((cursorX != 0) || (cursorY != 0)) GUI.Box ( new Rect (cursorX, cursorY, 50, 50), cursor_tex); //"Pointing\nHere");
        int c = wiimote_count();
        for (int i=0; i<=c-1; i++) {
            float ir_x = wiimote_getIrX(i);
            float ir_y = wiimote_getIrY(i);
            if ( (ir_x != -100)  (ir_y != -100) ) {
                float temp_x = ((ir_x + (float) 1.0)/ (float)2.0) * (float) Screen.width;
                float temp_y = (float) Screen.height - (((ir_y + (float) 1.0)/ (float)2.0) * (float) Screen.height);
                temp_x = Mathf.RoundToInt(temp_x);
                temp_y = Mathf.RoundToInt(temp_y);
                //if ((cursor_x != 0) || (cursor_y != 0))
                GUI.Box ( new Rect (temp_x, temp_y, 64, 64), "Pointer " + i);
            }
			
        }
    }
	public void CommsTest(){
		Debug.Log("Vars recieved!");
		}
}

I’ve deliberately changed the cursor_x and _y for cursorX and cursorY just while I was testing, won’t make any difference to you calling them from elsewhere.

Now anytime you want to access WiiMote script from within bullet.js just use wm.functionname or wm.var to either read or wrtie the script :slight_smile:

I always find it a pain to set this up unless the scripts areon camera.main or the same object as each other, but this works (as long as you set which object has the script on it)

Oh and feel free to change myX and myY to 0 ditto for cursorX and Y (I did it to watch the values change in the inspector, since I don’t have a wiimote hooked up :lol:)

Once I changed the Function to Update in the Javascript that worked perfectly!

Thank you so much for your help!

this doesn’t work for me (on iphone, maybe it’s different?), I do always get the error “unknown identifier” on the C# class name inside the javascript.

anyway I’m just using gameObject.SendMessage to call the function that I need.

this will not work on unity iphone.

this is a standalone plugin, usable only in Unity Pro

Unity iphone plugin capabilities are bound to source files that correctly expose them. (bundles don’t work at all on the iphone)

also there is no good nor bad reason why a wiimote plugin should work on the iphone :wink:

Having not used the iPhone version, but assuming everything within the script is compatible the only thing to check is that you place the cs script is placed in /Assets/Standard Assets/Scripts (or somewhere that compiles first as shown here:

…Then keep the js file in /Assets

The cs needs to compile first before it is visible to the js, otherwise you get the null reference…

**Of course I’m referring to the method of js<->cs script interaction, not the WiiMote plugin as Dreamora has correctly stated that external plugins cannot be used on the iPhone version.

of course I didn’t need to use the wiimote on the iphone :smile:
after moving the cs file in one of those folders everything works just fine, thx!

Same can’t be said for me - I’m having issues.

I have a C# script in Standard Assets>Scripts called “SwipeControl”
I have a JS script in Assets folder.

There is a private var in C# for ‘Swiper’ (int).

I have an instance of the C# script in the scene on an empty GO.

This is the JS script:

GetComponent("SwipeControl"); //may not even need this.



function Update () {
	 
	
       if (SwipeControl.Swiper == -1)
	{
		Debug.Log("Working!");
	}
}

I get the error “An instance of type ‘SwipeControl’ is required to access non static member Swiper” that points to the line above : If (SwipeControl.Swiper == -1).

But i DO have an instance of this in the scene on an empty GO.][/code]

hello make the Swipe variable in the other script as the static.

Eg:
static var swipe : int = 0;
like this in the other script

thanks