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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

4453閲覧

Unityでユーザーにて差し込まれたUSBメモリにデータを書き込みたい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/02/21 05:27

編集2019/02/21 06:09

#したいこと
Unityでアーケード型ゲームを作成しているのですが、各ユーザーのデータをUSBメモリに保存しておきたいと思っています。

画面に「USBを差し込んでください」と表示し、USBメモリが差し込まれたらUnityで認識して、USBメモリのドライブ番号等を取得したいと思います。

#調べてみたこと(初心者なので調べ方が甘かったらご指摘ください。)
今は方法を模索中ですが、現時点でわかっていることを記しました。

① USBの差し込み検知は、Windowメッセージで取得できる。
(Unityでしている人もいたが、複雑すぎてあまりわからなかった。)

② USB情報の取得はWIN32APIでできる。が、UnityではWIN32APIは使えないのでネイティブプラグインを使って取得する。

色々調べた結果上のような感じになったのですが、この方法しかないのでしょうか?
もっとスマートな方法があるのであれば教えていただけると嬉しいです。

また、上記の方法が適当な場合、具体的にどのようにすればよいのか参考サイトでもいいので教えてほしいです。

お願いします。

#環境
Windows10 Pro
Unity 2.13f1

Windowsで動かすため、マルチプラットフォームには対応しなくても大丈夫です。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/02/21 05:48

そのあなたのいう、できる、という方法を提示してください。 で、現状、なにができてなにができてないか、どうしたいのかを説明しましょう #それと、USBといってるのは、USBメモリ、のことですよね
退会済みユーザー

退会済みユーザー

2019/02/21 06:06

すみません。いろいろと情報が足りませんでした。 USBとは、USBメモリのことです。 現状は何もできていません。どのように取得すればよいのかを模索している途中でしたので、その途中経過を書き記しました。
stdio

2019/02/21 06:23

その模索している途中のコードを投稿して下さいと、y_waiwaiさんはおっしゃっているのだと思いますよ。
退会済みユーザー

退会済みユーザー

2019/02/22 02:03

忙しくてコードを書いている暇があまりないので、実際にコードを書いて試すということはまだしていません。 スマホなどで時間が空いた時に調べているという意味で模索という言葉を使っています。 Windowメッセージ+ネイティブプラグインの方法が最適ならば、その方法で頑張ってみようと思っているのですが、もっと効率の良い方法があるのならば、そちらを実装したいと思っています。
stdio

2019/02/22 02:42

スマホなどで時間が空いた時に調べているだけでしたら、こちらといたしましても教える事はできません。 一度、コードを書いて試作を行ってから質問してきて下さい。それならこちら側もより効率が良いなどの情報共有を行えるようになります。Teratailはプログラマが集まる場なので、コードが全てです。 コードがなくスマホなど調べただけでは、やる気がない知りたがりの人間と判断されてしまいます。 「やってほしいことだけを記載した丸投げの質問」として評価して欲しくないのであれば一度試作して下さい。
退会済みユーザー

退会済みユーザー

2019/02/22 02:50

stdioさん、y_waiwaiさん。ありがとうございます。 私の力不足ですみません。一度自分で試作してみようと思います。
guest

回答2

0

誤って回答を押してしまったので削除します

投稿2019/02/22 10:27

編集2019/02/22 10:46
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

自分にて試行錯誤したところ、windowメッセージを取得することで欲しい機能を実装することができました。

下記に実装したコードを記しておきます。

C#

1class test : EditorWindow 2{ 3 [DllImport("user32.dll", EntryPoint = "SetWindowLong")] 4 private static extern int SetWindowLong32(HandleRef hWnd, int nIndex, int dwNewLong); 5 [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] 6 private static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, IntPtr dwNewLong); 7 8 9 10 [DllImport("user32.dll", EntryPoint = "DefWindowProcA")] 11 private static extern IntPtr DefWindowProc(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam); 12 13 [DllImport("user32.dll")] 14 private static extern System.IntPtr GetActiveWindow(); 15 16 private HandleRef hMainWindow; 17 private IntPtr oldWndProcPtr; 18 private IntPtr newWndProcPtr; 19 private WndProcDelegate newWndProc; 20 21 // P/Invokeの定義 (pinvoke.net参照) 22 public static IntPtr SetWindowLongPtr(HandleRef hWnd, int nIndex, IntPtr dwNewLong) 23 { 24 if (IntPtr.Size == 8) 25 return SetWindowLongPtr64(hWnd, nIndex, dwNewLong); 26 else 27 { 28 return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32())); 29 } 30 } 31 32 const int WM_DEVICECHANGE = 0x0219; 33 34 [StructLayout(LayoutKind.Sequential)] 35 struct DEV_BROADCAST_VOLUME 36 { 37 public uint dbch_Size; 38 public uint dbch_Devicetype; 39 public uint dbch_Reserved; 40 public uint dbch_Unitmask; 41 public ushort dbch_Flags; 42 } 43 44 private IntPtr wndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) 45 { 46 if (msg == WM_DEVICECHANGE) 47 { 48 switch ((int)wParam) 49 { 50 case 0x8000: 51 Debug.Log("デバイスが挿入され利用可能になりました。"); 52 DEV_BROADCAST_VOLUME device = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_VOLUME)); 53 uint deviceNum = device.dbch_Unitmask; 54 char deviceLet = (char)0; 55 for (int i = 0;i < 26; i++) 56 { 57 if (deviceNum == 0x01) deviceLet = (char)(i + 0x41); 58 deviceNum >>= 1; 59 } 60 Debug.Log(deviceLet.ToString()); 61 62 break; 63 case 0x0007: 64 //Debug.Log("デバイスが追加または削除されました。"); 65 break; 66 case 0x8004: 67 //Debug.Log("デバイスが削除されました。"); 68 break; 69 default: 70 //Debug.Log("wndProc msg:0x" + msg.ToString("x4") + " wParam:0x" + wParam.ToString("x4") + " lParam:0x" + lParam.ToString("x4")); 71 break; 72 } 73 74 } 75 return DefWindowProc(hWnd, msg, wParam, lParam); 76 } 77 78 /// 終了 79 ~test() 80 { 81 Term(); 82 } 83 84 /// 初期化(EditorWindowをShowした後にコール) 85 public void Init() 86 { 87 // ウインドウプロシージャをフックする 88 hMainWindow = new HandleRef(null, GetActiveWindow()); 89 newWndProc = new WndProcDelegate(wndProc); 90 newWndProcPtr = Marshal.GetFunctionPointerForDelegate(newWndProc); 91 oldWndProcPtr = SetWindowLongPtr(hMainWindow, -4, newWndProcPtr); 92 93 } 94 public void Term() 95 { 96 SetWindowLongPtr(hMainWindow, -4, oldWndProcPtr); 97 hMainWindow = new HandleRef(null, IntPtr.Zero); 98 oldWndProcPtr = IntPtr.Zero; 99 newWndProcPtr = IntPtr.Zero; 100 newWndProc = null; 101 } 102 103 void OnGUI() 104 { 105 // ウィンドウハンドルが切り替わったので初期化 106 if (hMainWindow.Handle == IntPtr.Zero) 107 { 108 Init(); 109 } 110 } 111}

上記のようにクラスを宣言し、Start関数内で下記のように呼ぶとウィンドウメッセージを取得できました。
私の力不足でお騒がせしました。

c#

1void Start() 2{ 3 parent = ScriptableObject.CreateInstance<test>(); 4 parent.Init(); 5}

投稿2019/02/22 02:51

編集2019/02/22 13:59
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問