質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.19%

unityでのsendinput

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,819

matukazekun

score 3

unityでの、sendinputが上手に動作しません。unityのexeファイルを作成し、 exeを起動してwindowsへキーストローク出力がしたい。 できるだけ簡単に実装したい。

keybd_eventではスクリプトでのキーストロークの検知はできたが、exeに落とし込んでキーストロークの出力を試したが反応なし。

keybd_eventでの使用は推奨されていないのでsendinputでの実装を考えたが、
exeファイルの作り方がおかしかったのでkeybd_eventの出力ができなかったのかなとも未だにわだかまりが。
今回はunityでのsendinputの実装を可能にしたい。
unityでの参考書物があれば教えていただきたい。unity以外は読みつくしたと思う。 回答お願いします。

できれば完全に動くコードが欲しい。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;

public class check1 : MonoBehaviour
{
     [DllImport("user32.dll")]
    private extern static void SendInput(uint nInputs, ref INKey pInputs , int cbsize);

    [StructLayout(LayoutKind.Sequential)]
    private struct KEYBDINPUT
    {

        public byte wVk;
        public short wScan;
        public int dwFlags;
        public int time;
        public int dwExtraInfo;



    };

    [StructLayout(LayoutKind.Sequential)]
    struct INKey
    {
        public int type;
        // 0 = INPUT_MOUSE,
        // 1 = INPUT_KEYBOARD,
        // 2 = INPUT_HARDWARE
        public KeyIN ks;
    }


    [StructLayout(LayoutKind.Explicit)]
    private struct KeyIN
    {



        [FieldOffset(0)] public KEYBDINPUT ki;

    };

    private const int INPUT_KEYBOARD = 0x1;


    [DllImport("user32.dll", EntryPoint = "MapVirtualKeyA")]
    private extern static int MapVirtualKey(
       int wCode, int wMapType);




    // Start is called before the first frame update
    void Start()
    {




    }




    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.K))
        {
            Debug.Log("押した");

            const int num = 2;

            INKey[] ingo = new INKey[num];


            ingo[0].type = INPUT_KEYBOARD;
            ingo[0].ks.ki.wVk = 0x41;
            ingo[0].ks.ki.wScan = 0x4;

            ingo[0].ks.ki.dwFlags = 0x1 | 0x0;


            SendInput(num, ref ingo[0], Marshal.SizeOf(ingo[0]));

            if (Input.GetKey(KeyCode.A))
            {

                Debug.Log("記念日");

                ingo[1].type = INPUT_KEYBOARD;
                ingo[1].ks.ki.wVk = 0x41;
                ingo[1].ks.ki.wScan = 0x4;

                ingo[1].ks.ki.dwFlags = 0x1 | 0x2;


                SendInput(num, ref ingo[0], Marshal.SizeOf(ingo[0]));

            }
        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • bochan2

    2019/03/03 22:36

    質問頂きありがとうございます!
    出来れば全ソースのファイル構成も分かるようにgithubやGoogleDrive等のダウンロードリンクを用意していただけると解決の役に立つと思います。

    キャンセル

  • matukazekun

    2019/03/03 22:57

    現在ここに掲載しているものが全てです。

    キャンセル

  • matukazekun

    2019/03/03 22:57

    全ソースって俺のすべてやんけ

    キャンセル

  • matukazekun

    2019/03/03 22:58

    裸になれというのか

    キャンセル

回答 2

+2

wwbQzhMkhhgEmhUさんとのやりとりを聞いた限りでは、Unityでやる意味は無いように感じられます。
同じゲームではないかと思っているかもしれませんが、Unityは表示や当たり判定などの処理を行うものであり、マウスのマクロ機能(ですよね?)を作るのには、むしろ足枷になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/03 22:56

    ゲームパッドにまで対応できるのはunityしか知らないもので・・
    自分ではunityがベストだったんですが・・・。

    キャンセル

  • 2019/03/03 23:10

    Unity製ではないゲームでも、ゲームパッドを使えるソフトはたくさんあるので、やり方はいくらでもあると思いますが…。

    以下のように、Win32APIにもゲームパッドの入力を取得する関数はあるようです。
    http://7ujm.net/C++/joypad.html

    キャンセル

  • 2019/03/03 23:22

    ありがとy。もう寝ます。もし私のプロジェクトが気になるようでしたらふぁぼってください。
    これツイアカです

    キャンセル

  • 2019/03/04 22:13

    >これツイアカです
    リンク載ってませんよ

    キャンセル

checkベストアンサー

+1

原因は32bitと64bitの構造体アラインの違いみたいです。
細かく見てないですが、WIN32API呼び出し系はpinvoke.netのをパクると手堅いです。

定義例

[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
    public int dx;
    public int dy;
    public uint mouseData;
    public uint dwFlags;
    public uint time;
    public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
    public ushort wVk;
    public ushort wScan;
    public uint dwFlags;
    public uint time;
    public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
    public int uMsg;
    public short wParamL;
    public short wParamH;
}

[StructLayout(LayoutKind.Explicit)]
struct MouseKeybdHardwareInputUnion
{
    [FieldOffset(0)]
    public MOUSEINPUT mi;

    [FieldOffset(0)]
    public KEYBDINPUT ki;

    [FieldOffset(0)]
    public HARDWAREINPUT hi;
}

[StructLayout(LayoutKind.Sequential)]
struct INPUT
{
    public uint type;
    public MouseKeybdHardwareInputUnion mkhi;
}

/// <summary>
/// Synthesizes keystrokes, mouse motions, and button clicks.
/// </summary>
[DllImport("user32.dll")]
static extern uint SendInput(uint nInputs,
   [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs,
   int cbSize);

'A'を押して離す使用例

keyInput.type = 1;

keyInput.mkhi.ki.wScan = 0;
keyInput.mkhi.ki.time = 0;
keyInput.mkhi.ki.dwFlags = (int)1; // KEYDOWN相当
keyInput.mkhi.ki.dwExtraInfo = (IntPtr)0; // 面倒だったので適当。本当はGetMessageExtraInfo();
keyInput.mkhi.ki.wVk = (ushort)65; // 仮想キーコードA

InputList[0] = keyInput;

keyInput.mkhi.ki.dwFlags = (int)3; // KEYUP相当

InputList[1] = keyInput;

SendInput((uint)2, InputList, Marshal.SizeOf(InputList[0]));

参考リンク
https://stackoverflow.com/questions/6830651/sendinput-and-64bits

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/04 17:24

    うんちっちうんちっちうんちっち できたァ・・・

    キャンセル

  • 2019/03/04 19:05

    おめでとw
    好きなゲームでBANされるような悲しいことはしないでね

    キャンセル

  • 2019/03/04 22:01

    でも、自分が欲しかった機能じゃなかった(笑)(´;ω;`)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.19%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る