Reputation: 28138
Unity has a new inputsystem where the old OnMouseDown() {}
no longer works.
In the migration guide they mention replacing this with Mouse.current.leftButton.isPressed
.
And in other forum posts they mention using an InputAction
.
The problem is that these options detect mouse clicks anywhere in the scene, instead of just on the object:
public InputAction clickAction;
void Awake() {
clickAction.performed += ctx => OnClickedTest();
}
void OnClickedTest(){
Debug.Log("You clicked anywhere on the screen!");
}
// this doesn't work anymore in the new system
void OnMouseDown(){
Debug.Log("You clicked on this specific object!");
}
How can I detect mouse clicks on a specific gameObject with the new input system in Unity?
Upvotes: 9
Views: 19190
Reputation: 300
For me, it seems the answer lies in the context type:
InputAction.CallbackContext
The way I did it was using the context "canceled" property. When it is false, that means the mouse press just occurred. When it is true, that means the mouse press has been caneceled (and then indicating a OnMouseUp event).
It seems it has a few properties to make this fit other use cases, such as a duration indicating how long the button was down etc.
Upvotes: 0
Reputation: 11
You can also just use
Mouse.current.leftButton.wasPressedThisFrame
With a Raycast and a object with a collider in world space it would look like this:
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
if (Physics.Raycast(ray, out hit) && hit.transform.name == "TargetObjName")
{
print("PointerOnObj");
if (Mouse.current.leftButton.wasPressedThisFrame)
{
print("clicked");
}
}
Upvotes: 1
Reputation: 2759
With this code somewhere in your scene:
using UnityEngine.InputSystem;
using UnityEngine;
public class MouseClicks : MonoBehaviour
{
[SerializeField]
private Camera gameCamera;
private InputAction click;
void Awake()
{
click = new InputAction(binding: "<Mouse>/leftButton");
click.performed += ctx => {
RaycastHit hit;
Vector3 coor = Mouse.current.position.ReadValue();
if (Physics.Raycast(gameCamera.ScreenPointToRay(coor), out hit))
{
hit.collider.GetComponent<IClickable>()?.OnClick();
}
};
click.Enable();
}
}
You can add an IClickable
Interface to all GameObjects that want to respond to clicks:
public interface IClickable
{
void OnClick();
}
and
using UnityEngine;
public class ClickableObject : MonoBehaviour, IClickable
{
public void OnClick()
{
Debug.Log("somebody clicked me");
}
}
Upvotes: 14
Reputation: 431
Make sure you have a an EventSystem
with an InputSystemUIInputModule
in the scene and a PhysicsRaycaster
or Physics2DRaycaster
on your Camera
, and then use the IPointerClickHandler
interface on the object with a collider on itself or its children:
using UnityEngine;
using UnityEngine.EventSystems;
public class MyClass : MonoBehaviour, IPointerClickHandler {
public void OnPointerClick (PointerEventData eventData)
{
Debug.Log ("clicked");
}
}
Upvotes: 4