- Home /
Custom Script issue from PC to Mac (NOT IOS)
Hi all,
I'm trying to build a for a Mac that will allow me to collect some data on each mouse click. The script I have (JavaScript) exports the value of a vector and writes it to a text file.
This all works fine on a Windows 7 (which is also the OS I'm using for the Unity Editor), but when I try to build it for a Mac, I get a NullReferenceException for an object that I'm trying to change. (It's a GUIText Object that calls a random element from a list, the name of a building, and displays it). The default GuiText is all that displays when I run it on a Mac. Everything else works fine, so I'm guessing it's just an issue with the script.
I don't have a Unity Editor for the Mac, is there any way to debug it in Windows? Also, I'm pretty sure I DON'T need to use #pragma strict, as this is a standalone build, not an iOS build. But someone correct me if I'm wrong?
I'm happy to post the full code if that'll help.
EDIT:
It appears like it might be a #pragma strict problem after all. I think this is the line of code I need to alter:
GetComponent(CharacterController).transform.position = diamonds[startLandmarkIndex].transform.position;
diamonds, startLandmarkIndex are both declared (Array and int, respectively). And it's throwing a BCE0019: 'transform' is not a member of 'Object'.
The rest of the code:
#pragma strict
import System;
import System.IO;
var diamonds = List.<GameObject>();
var names = List.<String>();
var pointingDiamondIndex : int;
var facingDiamondIndex : int;
var targetBuildingIndex : int;
var targetBuildingIndicesRemaining : Array;
var targetBuildingIndicesRemainingIndex : int;
var pointingPromptObject : GameObject;
var waitingForClick : String;
var mainCamera : Camera;
var screenRay : Ray;
var currentPosition : Vector3;
var facingDiamondPosition : Vector3;
var pointingAngle : float;
static var dataDirectory : DirectoryInfo;
function Start() {
//load file-location
dataDirectory = new DirectoryInfo("C:");
WriteFile("out.txt","pointingDiamondIndex facingDiamondIndex targetBuildingIndex pointingAngle\n");
pointingPromptObject = GameObject.Find("PointingPrompt");
mainCamera = Camera.main;
// populate arrays
diamonds.Add(GameObject.Find("Batty diamond"));
names.Add("Batty House");
diamonds.Add(GameObject.Find("Lynch diamond"));
names.Add("Lynch Station");
diamonds.Add(GameObject.Find("Harvey diamond"));
names.Add("Harvey House");
diamonds.Add(GameObject.Find("Golledge diamond"));
names.Add("Golledge Hall");
diamonds.Add(GameObject.Find("Sauer diamond"));
names.Add("Sauer Center");
diamonds.Add(GameObject.Find("Tobler diamond"));
names.Add("Tobler Museum");
startPointingSet(0);
}
function startPointingSet(startLandmarkIndex:int) {
if (startLandmarkIndex <= 5) {
pointingDiamondIndex = startLandmarkIndex;
var cc : CharacterController = GetComponent(CharacterController) as CharacterController;
// move to diamond
GetComponent(CharacterController).transform.position = diamonds[startLandmarkIndex].transform.position;
if (startLandmarkIndex == 0) facingDiamondIndex = 1;
else if (startLandmarkIndex == 1) facingDiamondIndex = 2;
else if (startLandmarkIndex == 2) facingDiamondIndex = 1;
else if (startLandmarkIndex == 3) facingDiamondIndex = 4;
else if (startLandmarkIndex == 4) facingDiamondIndex = 5;
else if (startLandmarkIndex == 5) facingDiamondIndex = 4;
targetBuildingIndicesRemaining = [0,1,2,3,4,5];
targetBuildingIndicesRemaining.RemoveAt(startLandmarkIndex);
Debug.Log("startPointingSet() targetBuildingIndicesRemaining: " + targetBuildingIndicesRemaining.join(","));
targetBuildingIndicesRemaining = shuffle(targetBuildingIndicesRemaining);
showPointingQuestion();
}
else {
// all done -- return to browser
Debug.Log("all done -- return to browser");
Application.ExternalCall("doneWithPointing");
}
}
function showPointingQuestion() {
if (targetBuildingIndicesRemaining.length > 0) {
targetBuildingIndex = targetBuildingIndicesRemaining[0];
// show instructions
pointingPromptObject.guiText.text = "Point to " + names[targetBuildingIndex];
}
else {
startPointingSet(pointingDiamondIndex + 1);
}
}
function Update() {
screenRay = mainCamera.ScreenPointToRay(Vector3((mainCamera.pixelWidth / 2), (mainCamera.pixelHeight / 2), 0));
Debug.DrawRay(screenRay.origin, screenRay.direction * 2000, Color.red);
Debug.DrawLine(screenRay.origin, diamonds[facingDiamondIndex].transform.position, Color.blue);
if (Input.GetKey ("escape")) {
Application.Quit();
}
}
function OnGUI() {
if (Input.GetButton ("Fire1")) {
if(targetBuildingIndicesRemaining.Count>0){
targetBuildingIndicesRemaining.RemoveAt(0);
Debug.Log("OnGUI() targetBuildingIndicesRemaining: " + targetBuildingIndicesRemaining.join(","));
screenRay = mainCamera.ScreenPointToRay(Vector3((mainCamera.pixelWidth / 2), (mainCamera.pixelHeight / 2), 0));
currentPosition = GetComponent(CharacterController).transform.position;
facingDiamondPosition = diamonds[facingDiamondIndex].transform.position;
pointingAngle = Vector3.Angle((facingDiamondPosition-currentPosition), screenRay.direction);
Debug.Log("pointing angle: " + pointingAngle);
// send pointing angle to the browser
Application.ExternalCall("recordPointingQuestion", pointingDiamondIndex, facingDiamondIndex, targetBuildingIndex, pointingAngle);
WriteFile("out.txt",pointingDiamondIndex+" "+ facingDiamondIndex+" "+targetBuildingIndex+" "+pointingAngle+"\n");
Input.ResetInputAxes(); // we don't want this repeated multiple times
showPointingQuestion();
} else{
Application.Quit();
}
}
}
//new function for saving into file on disk
static public function WriteFile(fileName : String, data : String) {
var writer : StreamWriter;
var t : FileInfo = new FileInfo(dataDirectory.FullName + '/' + fileName);
writer = t.AppendText();
writer.Write(data);
writer.Close();
}
function shuffle(array : Array) {
var temp : int;
for (var i : int = 0; i < array.length; i++) {
temp = array[i];
var swapIndex : int = UnityEngine.Random.Range(0, array.length - 1);
array[i] = array[swapIndex];
array[swapIndex] = temp;
}
return array;
}
What is diamonds
? Is it an Array()
? If so, you're relying on dynamic typing every time you pull an object out of it, because Array()
does not save any type information.
Dynamic typing is potentially powerful, but has a performance penalty and isn't supported on all Unity platforms. It's the most important feature that's turned off by using #pragma strict
.
You've set up a scenario where the interpreter isn't able to infer a specific type for your diamond, so it's assu$$anonymous$$g it's a basic Object
(because it's the safest guess). Since the class Object
doesn't have a field named transform
, you're getting that error.
You could try an explicit cast:
//NOTE: assumes 'diamond' is a GameObject!
var diamond = diamonds[startLandmarkIndex] as GameObject;
GetComponent(CharacterController).transform.position = diamond.transform.position;
See below - this has fixed the diamonds and characterController issues, but I'm still having trouble with targetBuildingIndicesRemaining. I can't get it to do both things - be a list of integers (declared as integers), and allow methods like join, add, removeat, etc.
Any further suggestions on that front?
Answer by Graham-Dunnett · May 07, 2014 at 09:21 PM
// javascript
var cc : CharacterController = GetComponent(CharacterController) as CharacterController;
cc.transform.position = diamond.transform.position;
This comment seems to have fixed my pragma strict issue, but I am having issues now with an Obj downcasting to int. I'm not sure how to amend the script to change Array methods in javascript to list methods that function the same way. I've posted the entire code, to hopefully get some help.
Errors pop up on lines 140, and 79.
Your answer
Follow this Question
Related Questions
Setting Scroll View Width GUILayout 1 Answer
JDK home issue (Mac to android) 0 Answers
Can someone help me fix my Javascript for Flickering Light? 6 Answers
Text To Speech? 0 Answers