unityでのsendinput
- 評価
- クリップ 0
- VIEW 1,819
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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+2
wwbQzhMkhhgEmhUさんとのやりとりを聞いた限りでは、Unityでやる意味は無いように感じられます。
同じゲームではないかと思っているかもしれませんが、Unityは表示や当たり判定などの処理を行うものであり、マウスのマクロ機能(ですよね?)を作るのには、むしろ足枷になります。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
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
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.19%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
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
裸になれというのか