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

时间:2017-09-13 13:06:37

标签: c# unity3d google-cardboard

这是我的剧本:

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

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

2 个答案:

答案 0 :(得分:0)

虽然这通常是不好的做法(你应该设计系统,以便只有你点击鼠标时调用的功能,然后你可以在任何地方调用该功能,所以你不需要模拟一个)可以在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只是窗口,因此它不能移植到其他操作系统。这是你应该避免这样做的主要原因。

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

在Windows上操作系统0,0是屏幕的左上角,坐标不会缩放到屏幕大小,所以如果你想获得每个分辨率的屏幕中心你必须使用Screen类来获取显示大小。

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

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;
        }

    }

}

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

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

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

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

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

答案 1 :(得分:0)

使用此脚本(用于2D游戏),您可以从屏幕中用鼠标单击的点创建一个RayCast,并检查您击中的游戏对象。我建议您首先标记要单击的任何GameObject

private void sacoFotoIngresoLocal() {

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File

        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this,"com.example.android.fileprovider",  photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUERIMEINTO_TOMAR_FOTO);

        }
    }
}