Raycasting problem

I was altering this script I got from another post on unity forums, but now upon editing it so that it raycasts from the mouse position instead of forward I get the errors:

ArgumentException: get_main can only
be called from the main thread.

Constructors and field initializers
will be executed from the loading
thread when loading a scene. Don’t use
this function in the constructor or
field initializers, instead move
initialization code to the Awake or
Start function. Gravitygun…ctor ()
(at Assets/Gravitygun.js:12)

And

UnityEngine.Camera:get_main()
Gravitygun:.ctor() (at
Assets\Gravitygun.js:12)

Here is the script

    var catchRange = 30.0;

var holdDistance = 4.0;

var minForce = 1000;

var maxForce = 10000;

var forceChargePerSec = 3000;

var layerMask : LayerMask = -1;



enum GravityGunState { Free, Catch, Occupied, Charge, Release};

private var gravityGunState : GravityGunState = 0;

private var rigid : Rigidbody = null;

private var currentForce = minForce;

private var ray = Camera.main.ScreenPointToRay (Input.mousePosition);



function FixedUpdate () {

	if(gravityGunState == GravityGunState.Free) {

		if(Input.GetButton("Fire1")) {

			var hit : RaycastHit;

			if (Physics.Raycast (ray, 100)) {

				if(hit.rigidbody) {

					rigid = hit.rigidbody;

					gravityGunState = GravityGunState.Catch;

					

					// for debuging, remove it

					print("force: " + currentForce);

				}

			}

		}

	}

	else if(gravityGunState == GravityGunState.Catch) {

		rigid.MovePosition(transform.position + transform.forward * holdDistance);

		if(!Input.GetButton("Fire1"))

			gravityGunState = GravityGunState.Occupied;

	}

	else if(gravityGunState == GravityGunState.Occupied) {

		rigid.MovePosition(transform.position + transform.forward * holdDistance);

		if(Input.GetButton("Fire1"))

			gravityGunState = GravityGunState.Charge;

	}

	else if(gravityGunState == GravityGunState.Charge) {

		rigid.MovePosition(transform.position + transform.forward * holdDistance);

		if(currentForce < maxForce) {

			currentForce += forceChargePerSec * Time.deltaTime;

		}

		else {

			currentForce = maxForce;

		}

		if(!Input.GetButton("Fire1"))

			gravityGunState = GravityGunState.Release;

			

		// for debuging, remove it

		print("force: " + currentForce);

	}

	else if(gravityGunState == GravityGunState.Release) {

		rigid.AddForce(transform.forward * currentForce);

		currentForce = minForce;

		gravityGunState = GravityGunState.Free;

		

		// for debuging, remove it

		print("");

	}

}

I can see how the error is a little intimidating for a beginner, but it should be pointing at this line:

private var ray = Camera.main.ScreenPointToRay (Input.mousePosition);

Unity doesn’t want you calling camera.ScreenPointToRay() from the field initializer and that makes sense strictly from a logical point. You don’t want the ray to point at the spot where the mouse was the moment the object was created. That doesn’t make a lot of sense for a gun.

You should probably move it to the FixedUpdate where it belongs. Delete that line and modify your FixedUpdate() to be more like this

function FixedUpdate () {

    if(gravityGunState == GravityGunState.Free) {

       if(Input.GetButton("Fire1")) {
            var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            var hit : RaycastHit;
            ///.........
            //The rest of your code.

This sounds kinda jank, but I have done it, and it works nicely. I used it for a moving crosshair… Create a gameobject that moves with the mouse position. Put the raycast on that object.