在显示的任何位置生成 ClickMouseButton(0)

Generate ClickMouseButton(0) anywhere on display

这是我的脚本:

void Update () {
    public float clickTimer = 2f;
    clickTimer -= Time.deltaTime;
    if(clickTimer <= 0){
        //"Generate Click" I try: Input.GetMouseButtonDown(0);
        clickTimer = 2f;
    }
}

我不想点击任何特定对象,因为我有 RayCastHit,我想在显示的任何地方生成点击。

虽然这通常是不好的做法(您应该以一种方式设计系统,以便只有一个函数可以在鼠标单击时调用,然后您可以在任何地方调用该函数,这样您就不需要模拟一个)它可以在C# .net.

中的某个位置模拟鼠标点击

第一步是将鼠标光标移动到想要的位置(我知道你不想这样做,你可以将后面的一些步骤设置为只产生鼠标点击,这只是为了未来参考),Unity 本身没有任何方法来控制鼠标光标。这意味着我将在此处展示的示例只能在 windows 机器上运行,您必须实现不同的代码才能使其在 OSX 上运行。首先,我们必须首先包括:

using System.Runtime.InteropServices;

在我们的脚本中,这一行允许我们导入 user32.dll 以便我们可以将鼠标重新定位到我们想要的位置。那么下一步就是导入允许我们移动鼠标的函数,这样做是这样的

[DllImport("user32.dll")]
public static extern bool SetCursorPos(int X, int Y);

我们现在可以在我们的代码中使用这个函数来设置鼠标光标的位置,现在记住 user32.dll 只是 windows,因此它不能移植到其他操作系统。这是你应该避免这样做的主要原因。

public void Start()
{
    SetCursorPos(50, 50);
}

在 windows 操作系统上 0,0 是屏幕的左上角,坐标不会缩放到屏幕大小,所以如果你想获得屏幕的中心对于每种分辨率,您都必须使用 Screen class.

获得显示尺寸

正确定位鼠标后,我们需要做的就是执行鼠标单击,不幸的是,这非常棘手,.net 并没有任何内置方法来执行此操作。此时最好的选择就是这个可以为我们进行鼠标操作的class:

public class MouseOperations
{
    [Flags]
    public enum MouseEventFlags
    {
        LeftDown = 0x00000002,
        LeftUp = 0x00000004,
        MiddleDown = 0x00000020,
        MiddleUp = 0x00000040,
        Move = 0x00000001,
        Absolute = 0x00008000,
        RightDown = 0x00000008,
        RightUp = 0x00000010
    }

    [DllImport("user32.dll", EntryPoint = "SetCursorPos")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetCursorPos(int X, int Y);      

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetCursorPos(out MousePoint lpMousePoint);

    [DllImport("user32.dll")]
    private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

    public static void SetCursorPosition(int X, int Y) 
    {
        SetCursorPos(X, Y);
    }

    public static void SetCursorPosition(MousePoint point)
    {
        SetCursorPos(point.X, point.Y);
    }

    public static MousePoint GetCursorPosition()
    {
        MousePoint currentMousePoint;
        var gotPoint = GetCursorPos(out currentMousePoint);
        if (!gotPoint) { currentMousePoint = new MousePoint(0, 0); }
        return currentMousePoint;
    }

    public static void MouseEvent(MouseEventFlags value)
    {
        MousePoint position = GetCursorPosition();

        mouse_event
            ((int)value,
            position.X,
             position.Y,
             0,
             0)
             ;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MousePoint
    {
        public int X;
        public int Y;

        public MousePoint(int x, int y)
        {
            X = x;
            Y = y;
        }

    }

}

将其添加到项目中后,我们就可以使用这个class来模拟鼠标操作,可以这样做:

MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.LeftDown | MouseOperations.MouseEventFlags.LeftUp);

那一行将执行左键单击,鼠标事件函数接受可以执行不同鼠标功能的预制标志。如果您只传递了 LeftDown 标志,那么它将保持鼠标左键按下并执行左键单击保持。这就是为什么您还必须传递左上标记才能获得点击的原因。

Here's the code I used that worked flawlessly on my test project.

再次强调这一点,你不应该这样做。这是一个笨拙且不可靠的黑客攻击。正确和好的方法是让正常的左键单击简单地调用一个函数,而每当你想要左键单击发生时,你可以调用该函数,而不必通过复杂的步骤来模拟一个函数。

使用此脚本(适用于 2D 游戏),您可以从屏幕上用鼠标单击的位置创建 RayCast,并检查您点击了哪些游戏对象。我建议你先标记任何你想被点击的游戏对象

void Update () {

    clickTimer -= Time.deltaTime;

    if(clickTimer <= 0){

        if(Input.GetMouseButtonDown(0)) {

            //What point was pressed
            Vector3 worldPoint = Camera.main.ScreenToWorldPoint( Input.mousePosition );
            worldPoint.z = Camera.main.transform.position.z;
            //Generate a Ray from the position you clicked in the screen
            Ray ray = new Ray( worldPoint, new Vector3( 0, 0, 1 ) );
            //Cast the ray to hit elements in your scene
            RaycastHit2D hit = Physics2D.GetRayIntersection( ray );

            if(hit.collider != null) {
                 Debug.Log("I hit: "+hit.gameObject.tag);
                //And here you can check what GameObject was hit

                if(hit.gameObject.tag == "AnyTag"){
                     //Here you can do whatever you need for AnyTag objects
                }
            }
        }   

        clickTimer = 2f;
    }
}