Hi guys. This is my first post and I’m still new to Unity but I’ve run into my first [apparently] unsolvable problem (at least unsolvable by myself).
The basic idea is this: I want to select a gui item and be able to instantiate an object (with the same name) on a point that I click on. I also want to disable the instantiation functionality whenever a gui item is not selected. The reason for this is because once the item is created, I can’t click on it - the raycast function that I use to place the instance where the mouse click is seems to override the OnMouseDown function of the instantiated object.
I have a script called TrackMouse that reads as follows:
function OnMouseDown()
{
if (isActive == true)
{
// cast a ray from camera to mouse position
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (collider.Raycast (ray, hit, 10000.0)) // ignore all colliders except this one
{
if (SelectObject.selected) // if GUI object is selected
{
setObject();
Instantiate(object, transform.position, transform.rotation);
SelectObject.selected = false;
print(hit.collider);
}
}
}
}
and a static boolean variable isActive that is read by another script.
static var isActive : boolean = false;
My other script (which reads and changes the the isActive variable in the other one) is as follows:
function OnMouseDown ()
{
// check to see if item is already selected
if (currentSelection == name)
{
currentSelection = "null";
selected = false;
// TrackMouse.isActive = false;
}
else
{
currentSelection = name;
selected = true;
// TrackMouse.isActive = true;
}
print(currentSelection);
}
Now, as it is the script runs fine - the object is placed exactly where I want it to. but when I uncomment the TrackMouse.isActive lines above, I get this error when I try to use the OnMouseDown function.
MissingMethodException: Method not found: ‘UnityEngine.BoxCollider.Raycast’.
I can’t wrap my head around what’s wrong and would appreciate any help to point me in the right direction.
if (collider.Raycast (ray, hit, 10000.0)) // ignore all colliders except this one
If collider.Raycast requires explicit type casting before it will work. I am a C# guy myself, not really familiar with JS, but you should be able to say something like:
if ((collider as Collider).Raycast(ray, hit, 10000.0))
Kyle: I tried changing the bit you mentioned to no avail.
Maybe it would help if I posted both scripts in their entirety. So here we go.
TrackMouse.js
#pragma strict // pragma is needed due to a UnityJS issue
private var object : Rigidbody;
var object1 : Rigidbody;
var object2 : Rigidbody;
//static var isActive : boolean = true;
function Update()
{
}
function OnMouseDown()
{
// if (isActive == true)
// {
// cast a ray from camera to mouse position
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (collider.Raycast (ray, hit, 10000.0)) // ignore all colliders except this one
{
if (SelectObject.selected) // if GUI object is selected
{
setObject();
Instantiate(object, Vector3(transform.position.x, 5, transform.position.z), transform.rotation);
SelectObject.selected = false;
print(hit.collider);
}
}
// }
}
function setObject()
{
if (SelectObject.selected)
{
switch (SelectObject.currentSelection)
{
case "g_spawn1":
object = object1;
break;
case "g_spawn2":
object = object2;
break;
}
}
}
and SelectObject.js
static var currentSelection : String;
static var selected : boolean = false;
function OnMouseDown ()
{
// check to see if item is already selected
if (currentSelection == name)
{
currentSelection = "null";
selected = false;
// TrackMouse.isActive = false;
}
else
{
currentSelection = name;
selected = true;
// TrackMouse.isActive = true;
}
}
function Update()
{
switch (currentSelection)
{
case "g_spawn1":
guiText.material.color = Color.white;
GameObject.Find("g_spawn1").guiText.material.color = Color.yellow;
break;
case "g_spawn2":
guiText.material.color = Color.white;
GameObject.Find("g_spawn2").guiText.material.color = Color.yellow;
break;
case "null":
guiText.material.color = Color.white;
break;
}
if (selected == false)
{
currentSelection = "null";
}
}
I’ve fixed the “instantiated object not clickable” problem by creating it a little above the transform.position but I’m still getting the error if I click anywhere else.
This is actually a bug in Unity 2.6 that is believed to be fixed in 3.0. The workaround I would recommend is to swap the collider.Raycast call for Physics.Raycast. You can use the layer mask parameter (or place objects on the Ignore Raycast layer) to stop the wrong objects being detected.