OnMouseDown on Prefab Instance not working

I want to get OnMouseDown() events from Prefab instances while re-using the same script across different prefabs. I have two prefabs that I can instantiate like this:

var prefab : GameObject;
prefab = Resources.Load(instantiateName); // name pre-set elsewhere
var pos = Vector3(0, 0, 0);
instanceObj = Instantiate(prefab, pos, Quaternion.identity);
instanceObj.GetComponent(ItemInstanceScript).instanceRef = instanceObj;

Each Prefab has a Script component attached called “ItemInstanceScript”, as follows:

var instanceRef : GameObject;

function Start () {
    Debug.Log("New instance created: " + instanceRef);
}

function OnMouseDown() {
    Debug.Log("Prefab instance clicked.")
}

Each prefab also has a Box collider attached. In total, the prefabs have totally three components: “Transform”, “Script” (ItemInstanceScript) and “Box Collider”.

The Start() function is called on instantiation and it says “New instance created: UnityEngine.GameObject”, thus, the script is properly linked up. But the OnMouseDown event is not called when I click on the instance. And yes, I’ve already disabled any elements that may interfere with the raycast by putting them in the “Ignore Raycast” layer. But even if there’s no element in-between, the event is never raised.

I tried the other OnMouse events like OnMouseUp, stil doesn’t work.

[/code]

Did you check for the OnMouseDown() function with an instance of the prefab that you place manually in the scene?

Try adding a rigid body to the prefab… It’s not really necessary, and it should work without it, but I’m curious if it will help or not. I seem to recall an instance I needed to do this, but don’t remember why.

Thank you for the suggestion. Yes, this works (although I get UnassignedReferenceException on the variable instanceRef on ‘ItemInstanceScript’, although that’s just due to the specific design of the script here).

However, it seems that this problem of the event not being raised is intermittent. After restarting Unity, the event may suddenly work again. The only thing that has happened between testing is a restart of the Unity editor, nothing else (all files opened exactly as saved). No error messages are shown, the event just isn’t raised. I’ve noticed that after this event stops being raised, Unity will likely crash (although I haven’t seen it happen enough times to make a minimum repro). This is happening on the new PC version, 2.5.0f5. But there’s no crash or error message in the log when the event is not raised. Perhaps this should have been a bug report instead.

Weird… Check them in the inspector when this happens, or add more Debug.Log statements to see if they really do have colliders.

Also, if this happens, try to disable other objects that are in the way. I know you said you put them in the IgnoreRaycast layer, but still… Doesn’t hurt to double check. Pause the game, disable everything that doesn’t involve the objects (and I mean everything. Resume the game and see if it helps. Maybe you missed a huge transparent collider on one of your other objects and just don’t know it).

I was just wondering (non-related) - why did you add this line?:

instanceObj.GetComponent(ItemInstanceScript).instanceRef = instanceObj;

You could just use:

function Start () 
{
    instanceRef = gameObject; 
    Debug.Log("New instance created: " + instanceRef); 
}

I thinks that this code is redundancy…
if you need the reference of the game object (the script is attached on) into the same script… just type “gameObject” and have fun :smile:

bye bye Luigi :smile:

Well, no. There IS a reason to keep the reference to the gameObject inside the script.
Everytime you use “transform”, “gameObject” or “renderer” or any other keyword that will return another component - Unity has to actually look for that component. If you store a reference to it - it will be mich more efficient. Especially if you use it a lot in your code.

I just meant the assignment when he instantiates the prefab… Was there a special reason he did that there and not inside the script on the prefab itself…

That’s true, I tried, this code:

instanceObj.GetComponent(ItemInstanceScript).instanceRef = instanceObj;

It’s equivalent to this code in the Start() override:

instanceRef = gameObject;

The purpose was only to initialize the instance member. At least it’s good there is more than one way of doing it. The other approach could be left to times where the caller has exclusive scope access to some useful variable that we can’t find as a member of the script component itself.

As I’m from a C# background but find most samples in JavaScript, I tend to be a defensive coder when it comes to handling types. The thinking process here was that I just wanted to make 100% sure I got whatever type that Instantiate() returned, as I was looking at another sample code and didn’t bother to check what type it actually was - a particular kind of laziness encouraged by dynamic typing, I presume.

I was not able to get OnMouseDown() called as well on prefabs, restarting Unity fixed the issue. This looks like a bug.

It’s possible, but:

Quite an old message, but maybe this helps other people:

I had a problem with OnMouseDown event too, but I found a reason for that on my GUI code.

I had a routine in my GUI, which deletes a current event after it was used on GUI…

The problem was: Event.current.Use(); (Look Event.Use() from manual http://docs.unity3d.com/ScriptReference/Event.Use.html)

When I removed that line from my GUI code, everything starts work as I wanted.