UE4のWindowsにおけるマルチタッチについて
この記事は、Unreal Engine4(UE4) Advent Calendar 2015 その1の17日目の記事です。
前回の記事は、@tempkinder さんによる「CutomDepthを拡張して色も出力してみる」でした。
UE4で実装したモバイル端末において、マルチタッチは、ThirdPersonのテンプレートのThirdPersonCharacterのBPを見てもらえるとわかると思うのですが、InputTouchでタッチを
Press、Release,Move,Finger(指のインデックス)の情報をそれぞれ取れるようになっている
のが確認できると思います。
これをマルチタッチ対応のWindows機で実行してもらってDebugして驚愕の事実に
気づくと思うのですが、実は、Touch1以外の指に反応しないことがわかります。
このことについて、僕はハマったので、AnswerHubを検索してみると、
Windows 7/8 touch/ multi-touch supportと言う記事が見つかりました
InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("_WIN32_WINNT=0x0600");
InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0600");
を通るのですが、VisualStudioのWindowsのタッチの定義、実はWINVER=0x06001からになってます。
このあたりは互換性の問題でこうなってるのか、VisualStudio2013でしかコンパイル対応してないからなのか、その辺はわかりませんが、こういう理由でTouchが対応してない状況でコンパイルされています。
(ちなみに、4.10では、VisualStudio2015対応になってますが 、このあたりまだ対応してないようでした。)で、対応するために、
InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0601");
と書き換えてUnrealBuildToolをビルドし直して、UnrealEngine自体をビルドし直します。では、実際のプログラムに入っていきましょう。
実際のソースは、githubを見てもらうとして要点だけ説明します。コントーロールの操作なので、今回は、PlayerControllerを継承して実装します。BeginPlayで、アプリケーションハンドラを得て、アプリケーションに独自のメッセージハンドラを設定するようにします。このメッセージハンドラというのは、UE4用に定義されたWindowsのメッセージハンドラです。具体的に言うとWindowProcの部分のことと言っても間違いではないです。この部分の詳しいことは後で説明します。
メッセージハンドラは、IWindowsMessageHandlerを継承して、定義します。
ProcessMessageと言うのがWin32のアプリを作ったことがある方なら知ってるであろうWinProc関数です。ProcessMessageの中身の詳しいところは、githubのソースを読んでもらうとして、概要を説明するとTouchのメッセージをHookして、処理してUE4側に投げるようにします。
あとは、注意点だけ書いておきます。Touchなどのメッセージ定義などは、WindowsAPIのWinuser.hに定義されていますが、これをincludeしようとすると、DWORDなどのWindows特有の定義などでエラーになってしまいます。
これを回避するために、"AllowWindowsPlatformTypes.h"と"HideWindowsPlatformTypes.h"のincludeで括ります。こうすることで、Windows特有の定義のエラーを回避することができます。
あと、 FSlateApplicationとかは、Slateに入っているので、*.Build.csに、"Slate"を追加しておきます。
以上マルチタッチについて駆け足でしたが書いてみました。
読んでいただきありがとうございます。
最後にMultTouchを使ったサンプル動画を貼って終わりにしときます。
明日は @rarihomaさんの「UE4+FMOD」です。FMODは前回のぷちコンの時@rarihomaさんが使っていて便利というのを聞いて調べようと思っていたところなのでありがたいです。
前回の記事は、@tempkinder さんによる「CutomDepthを拡張して色も出力してみる」でした。
UE4で実装したモバイル端末において、マルチタッチは、ThirdPersonのテンプレートのThirdPersonCharacterのBPを見てもらえるとわかると思うのですが、InputTouchでタッチを
Press、Release,Move,Finger(指のインデックス)の情報をそれぞれ取れるようになっている
のが確認できると思います。
これをマルチタッチ対応のWindows機で実行してもらってDebugして驚愕の事実に
気づくと思うのですが、実は、Touch1以外の指に反応しないことがわかります。
このことについて、僕はハマったので、AnswerHubを検索してみると、
Windows 7/8 touch/ multi-touch supportと言う記事が見つかりました
読んでみると、Fingerの指の識別について、Windowsでは実装されてないとのこと。
iOSとかAndroidでは、実行してうまく指の認識をしてるのになんでWindowsでは
認識しないんだろうなーと思ってソースを読んでみようかなぁと思いながら、
4.9のUnrealBuildToolのコンパイルオプション的なところを調べていると、ちょっときになる記述を見つけました
if ((InBuildTarget.TargetType == TargetRules.TargetType.Program) && (GetCPPTargetPlatform(InBuildTarget.Platform) == CPPTargetPlatform.Win32)) { // Check if the target has requested XP support. if (String.Equals(InBuildTarget.Rules.PreferredSubPlatform, "WindowsXP", StringComparison.InvariantCultureIgnoreCase)) { SupportWindowsXP = true; } } if (WindowsPlatform.bUseWindowsSDK10 && WindowsPlatform.Compiler == WindowsCompiler.VisualStudio2015) { if (SupportWindowsXP) { throw new NotSupportedException("Windows XP support is not possible when targeting the Windows 10 SDK"); } // Windows 8 or higher required InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("_WIN32_WINNT=0x0602"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0602"); } else { if (SupportWindowsXP) { // Windows XP SP3 or higher required InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("_WIN32_WINNT=0x0502"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0502"); } else { // Windows Vista or higher required InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("_WIN32_WINNT=0x0600"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0600"); } }4.9は、VisualStudio2013でコンパイルされるはずなので、一番下の
InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("_WIN32_WINNT=0x0600");
InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0600");
を通るのですが、VisualStudioのWindowsのタッチの定義、実はWINVER=0x06001からになってます。
このあたりは互換性の問題でこうなってるのか、VisualStudio2013でしかコンパイル対応してないからなのか、その辺はわかりませんが、こういう理由でTouchが対応してない状況でコンパイルされています。
(ちなみに、4.10では、VisualStudio2015対応になってますが 、このあたりまだ対応してないようでした。)で、対応するために、
InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0601");
と書き換えてUnrealBuildToolをビルドし直して、UnrealEngine自体をビルドし直します。では、実際のプログラムに入っていきましょう。
実際のソースは、githubを見てもらうとして要点だけ説明します。コントーロールの操作なので、今回は、PlayerControllerを継承して実装します。BeginPlayで、アプリケーションハンドラを得て、アプリケーションに独自のメッセージハンドラを設定するようにします。このメッセージハンドラというのは、UE4用に定義されたWindowsのメッセージハンドラです。具体的に言うとWindowProcの部分のことと言っても間違いではないです。この部分の詳しいことは後で説明します。
void AMultiTouchPlayerController::BeginPlay(){ TSharedPtrGenericApplication = FSlateApplication::Get().GetPlatformApplication(); FWindowsApplication* WindowsApplication = (FWindowsApplication*)GenericApplication.Get(); WindowsApplication->AddMessageHandler(myMessageHandler); myMessageHandler.TouchController = this; myMessageHandler.InitVariable();
}
メッセージハンドラは、IWindowsMessageHandlerを継承して、定義します。
class GARDEN_API FMyWindowsMessageHandler : public IWindowsMessageHandler { public: void InitVariable(); virtual bool ProcessMessage(HWND hwnd, uint32 msg, WPARAM wParam, LPARAM lParam, int32& OutResult) override; AMultiTouchPlayerController *TouchController; bool isTouchInit; };
ProcessMessageと言うのがWin32のアプリを作ったことがある方なら知ってるであろうWinProc関数です。ProcessMessageの中身の詳しいところは、githubのソースを読んでもらうとして、概要を説明するとTouchのメッセージをHookして、処理してUE4側に投げるようにします。
あとは、注意点だけ書いておきます。Touchなどのメッセージ定義などは、WindowsAPIのWinuser.hに定義されていますが、これをincludeしようとすると、DWORDなどのWindows特有の定義などでエラーになってしまいます。
これを回避するために、"AllowWindowsPlatformTypes.h"と"HideWindowsPlatformTypes.h"のincludeで括ります。こうすることで、Windows特有の定義のエラーを回避することができます。
あと、 FSlateApplicationとかは、Slateに入っているので、*.Build.csに、"Slate"を追加しておきます。
以上マルチタッチについて駆け足でしたが書いてみました。
読んでいただきありがとうございます。
最後にMultTouchを使ったサンプル動画を貼って終わりにしときます。
明日は @rarihomaさんの「UE4+FMOD」です。FMODは前回のぷちコンの時@rarihomaさんが使っていて便利というのを聞いて調べようと思っていたところなのでありがたいです。
Dynamic Material(Texture)を試す
今回はDynamic Material(Texture)を紹介します、UE4はBlueprintでいろいろできますが、
テクスチャ自体を生成して、それを貼り付けたいというのをやろうとすると、
Blueprintだけではできなかったりします。
そこで、C++を使ってテクスチャを生成してしまおうという手法です
詳しくの解説については、
Procedual Material をみてもらうとして、
サンプルプロジェクトとかソースとかがなかったので
それだけ用意しました、
簡単に解説すると
実行まえは、上のように、テクスチャが黒いのに、実行すると
テクスチャ自体を書き換えて、赤色にできるという感じです、
これだけだと、Material Treeでもできるやろという感じなのですが、
たとえば、Displacement mapのテクスチャ自体を書き換えて、波のアニメーションを作ったりとかが
できるということなんです。
で、サンプルプロジェクトは以下になります
download (82MB)
テクスチャ自体を生成して、それを貼り付けたいというのをやろうとすると、
Blueprintだけではできなかったりします。
そこで、C++を使ってテクスチャを生成してしまおうという手法です
詳しくの解説については、
Procedual Material をみてもらうとして、
サンプルプロジェクトとかソースとかがなかったので
それだけ用意しました、
簡単に解説すると
実行まえは、上のように、テクスチャが黒いのに、実行すると
テクスチャ自体を書き換えて、赤色にできるという感じです、
これだけだと、Material Treeでもできるやろという感じなのですが、
たとえば、Displacement mapのテクスチャ自体を書き換えて、波のアニメーションを作ったりとかが
できるということなんです。
で、サンプルプロジェクトは以下になります
download (82MB)
Xperia Z Ultra 買いました
Xperia Z Ultra 買いました、使用感的には、仕事で、いろいろ今までいろんなAndroid端末
触ってきましたが、それと比べると、出来がものすごくいいです。iPhoneと比べるとAndroidって
動きのアニメーションがなぁっという人がいますが、はっきりいって、iPhoneよりも滑らかです
あと、Xperia Zのほうで電源関係のバグがありますが、これは、Sim Free 版のZ UltraのLTE版 ですが、
電源関係のバグはないです。 画面は発色がものすごくよいです。カメラについては、基本Xperia Zとかとほぼ同じなのでそんなに画質は変わりはないですが、厚さもiPad miniよりも薄いです。
薄さの感じ的には、iPad miniも板を持ってる感じがしたんですが、
Z Ultraはもっと板を持ってる感覚が強いです。
画面下の黒ふちの部分がちょっと長いかなと感じます。
上の画像は、iPad miniとの大きさの比較ですね。ちなみに、某店でマグネットの変換
アダプタ買ったんですがいまいちですね、端子がすぐはずれてしまいます。
買わない方がいいと思います。
Androidアプリの速度の最適化
今回は、アプリを作ったときに反応速度が気になるときの最適化というか、速度がかわる方法を2つほどかきたいと思います。特にDBまわりとスレッドまわりです。
まず、DBまわり。
ネットワークを通してえた情報などをオフラインでも使えるように、DBに蓄えたりすることがあると思います。大量のデータをDBHelperでsqlを使ってInsertするときに 次のように一回ずつDBをオープンして、クローズしたりしてませんか?
まず、DBまわり。
ネットワークを通してえた情報などをオフラインでも使えるように、DBに蓄えたりすることがあると思います。大量のデータをDBHelperでsqlを使ってInsertするときに 次のように一回ずつDBをオープンして、クローズしたりしてませんか?
public void insert(Data data) {
SQLiteDatabase db = getWritableDatabase();
String insertSql;
Date date = new Date();
long time=date.getTime();
insertSql = String.format(
"insert into log_table(insert_date,title,guid,category,description,public_date,vender_name,vender_code) "
+"values (?,?,?,?,?,?,?,?);");
Object arg[]={ String.valueOf(time),data.title,data.guid,data.category,data.description,
data.public_date,data.vender_name,data.vender_code};
data.public_date,data.vender_name,data.vender_code};
db.execSQL(insertSql, arg);
db.close();
}
渡すデータをArrayListにして、DBに書き込む方法を最適化してみましょう。
この方法を使うことで、実際アプリが5倍ほど早くなりました。
DB保存が遅いなと感じてる方はぜひ試してみましょう。
つぎに、スレッドです。
Asyncや、Threadを使うときにいつもPriorityをいじらずに使っているかたが、多いのではないでしょうか。PriorityをMIN_PRIORITYにするだけで、Galaxy系は2倍近く速度があがることが確認できました、
HTCの端末だと1.5倍ぐらいでした。Priorityを低くすると優先度が下がると思われますが、なぜか速度はあがります。いまのところ特にUI Threadが遅くなるとかもないようなので、設定するといいと思います。
Threadの場合は普通にsetPriorityで。
Asyncの場合は、doInBackgroundのなかで、
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
をすればいいです。
ぜひともお試しあれ。
渡すデータをArrayListにして、DBに書き込む方法を最適化してみましょう。
public void inserts(ArrayList<Data> data) {
SQLiteDatabase db = getWritableDatabase();
String insertSql;
Date date = new Date();
long time=date.getTime();
db.beginTransaction();
try{
insertSql = String.format(
"insert into log_table(insert_date,title,guid,category,description,public_date,vender_name,
vender_code) "
vender_code) "
+"values (?,?,?,?,?,?,?,?);");
SQLiteStatement stmt = db.compileStatement(insertSql);
for(int ncount=0;ncount<newsdata.size();ncount++){
if(results.get(ncount))continue;
String related_link = "";
String related_title="";
Data nwdata = data.get(ncount);
stmt.bindString(1,String.valueOf(time));
stmt.bindString(2,nwdata.title);
stmt.bindString(3,nwdata.guid);
stmt.bindString(4,nwdata.category);
stmt.bindString(5,nwdata.description);
stmt.bindString(6,nwdata.public_date);
stmt.bindString(7,nwdata.vender_name);
stmt.bindString(8,nwdata.vender_code);
stmt.executeInsert();
}
db.setTransactionSuccessful();
}finally {
db.endTransaction();
}
db.close();
}
この方法を使うことで、実際アプリが5倍ほど早くなりました。
DB保存が遅いなと感じてる方はぜひ試してみましょう。
つぎに、スレッドです。
Asyncや、Threadを使うときにいつもPriorityをいじらずに使っているかたが、多いのではないでしょうか。PriorityをMIN_PRIORITYにするだけで、Galaxy系は2倍近く速度があがることが確認できました、
HTCの端末だと1.5倍ぐらいでした。Priorityを低くすると優先度が下がると思われますが、なぜか速度はあがります。いまのところ特にUI Threadが遅くなるとかもないようなので、設定するといいと思います。
Threadの場合は普通にsetPriorityで。
Asyncの場合は、doInBackgroundのなかで、
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
をすればいいです。
ぜひともお試しあれ。
個人制作のアプリを公開しました
個人で作ったアプリがリリースされましたので、ここで紹介しておきます。YoutubeとSoundCloudのクライアントで、リスト表示し連続再生ができるアプリです。プレイリストなどを検索する機能もついているので、他の人が作ったリストや、自分が作ったリストを一気に聞くことができます。
アプリはこちらです。
https://play.google.com/store/apps/details?id=com.freeworks.android.musicflow
よろしくお願いします。
アプリはこちらです。
https://play.google.com/store/apps/details?id=com.freeworks.android.musicflow
よろしくお願いします。