simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

UnrealEngine4.12でAndroidアプリ作成とインストール

フィーリングで探すと File メニューからパッケージ化するというものが見つかります。

パッケージ化メニューからAndroid(すべて)を選べばインストールバッチファイルが作成されます。
これを実行すればAndroid端末にUnreal Engineのゲームがインストールされます。

やった、インストールできた!なんて喜んでいるあなた
はい、アウト~
実はすでに落とし穴x3にハマっていますので、一つずつ抜け出しましょう。

落とし穴1.スタートアップコンテンツ有りにしているとパッケージ化に時間を要します。(30~40分くらい?)
落とし穴2.ディフォルトのレベルを指定していないとブラックスクリーンになります。(エディタのアクティブなレベルは表示されないのですよ。)
落とし穴3.すべてのAndroidでパッケージ化すると、ファイルがデカ過ぎてゲームを実行できなくなります。

最初の落とし穴から抜け出すのは簡単ですね、プロジェクト作成時に余計なコンテンツを入れなければよいだけです。(コンテンツブラウザから削除してもよい)
二つ目の落とし穴から抜け出すのは難しいですね。Unityの感覚でシーンを指定していなくても、エディタでアクティブだったらそれが表示されると思っていたら大間違いです。
Unreal Engine は Blank プロジェクトを実行すると Black Screen になるのが正しい動作なのです。
適当なこと書いているブログだと Mobile HDR のチェックを外すとかありますが、そんな情報には惑わされないでください!

具体的な解決方法は次の図の通り、プロジェクト設定にてディフォルトのレベルを指定します。
f:id:simplestar_tech:20160703115846j:plain
これでゲーム起動時のブラックスクリーン問題は解決します。

最後の落とし穴もまた抜け出すのが難しい。
スタートアップコンテンツ有りですべてのAndroid向けにビルドすると2.3GBほどのファイルサイズになってしまい
Androidにインストールが成功しても、ストレージに余裕がないなどの理由でOBBファイルは一緒に入らず、ファイルにアクセスできずNo Google Play Store Keyのダイアログが出て先に進めなくなります。

同じような問題はこちらに示されています。
No Google Play Store Key - UE4 AnswerHub

具体的な解決方法としては Blank プロジェクトにして、スタートアップコンテンツは無しにして、パッケージ化の項目で Android(ETC1) を選びます。
パッケージ化も高速で終わり、OBBファイルも小さく(それでも50MBあったけど)インストールで入りきらないなんてこともなくなります。

はい、そんな落とし穴x3にハマったのは私です!
で、すべての落とし穴から抜け出すと次の図で示すように、お手持ちのAndroid端末にてUnreal Engineで作ったゲームが遊べるようになります。

f:id:simplestar_tech:20160703121445j:plain

ちなみに、fps は 60 出てました。
fps を表示したいときは指4本でタップして、コンソールコマンドに stat fps を打ち込むと表示されるようになります。

ゲームエンジン初心者が一番最初に行うだろう作業に
空のプロジェクトをビルドしてAndroid端末で動作チェックするという作業がありますが
Unreal Engineには、こんな落とし穴があるということをここに記録しておきましょう。

プラグイン作成中ですが、つい共有したくなったので書きました。
では、プラグイン作成の作業に戻ります。

UnrealEngine4.12のC++プラグイン機能を利用する

オブジェクト(UE4だとActor)のTransformをC++のコードから編集したいだけなんです。

私がどんな落とし穴にハマっていくか、記録していきます。

Visual Studio 2015 を Community からインストールしました。
あ、ここまでは大丈夫です。
C++がディフォルトで入っていないことは下調べして知っているので、ちゃんとC++の項目にチェックを入れてインストールしました。

7/2 追記:
公式ドキュメント入門書もバッチリ読んでます。
間違いようがないです。

そしてその作業フローを実行すると

コンパイル失敗」

Unreal Engine を 4.12, 4.11, 4.10 と試しても同じエラーが出ました。
これは…Visual Studio の Update に問題があるのかな?

と調べると、確かにそんな記述が数時間前から公式フォーラムにちらほら上がりだしてきた。

When i start UE4 with C++ it gives me compile failed every time - UE4 AnswerHub
Unreal Error "This project could not be compiled. Would you like to open it in Visual Studio?"
Compile Failed when creating Cpp project - UE4 AnswerHub

どうも、Unreal Engine 4 のビルドエラー祭りにナイスタイミングでハマったようだ。
4.12.4 の次期バージョンでは直る予定とのことで
お急ぎの方はひとまず Visual Studio 2015 の Update 3 を Update 2 に戻して使ってほしいとのことです。

めっちゃ時間がかかっていますが Visual Studio のバージョン差し戻し作業しています。
なんか…Visual Studioのバージョン戻しても同じエラーが起こりそうな予感はしているのだけど、とりあえずやってみます。

具体的には、先に Update 3 が適用された Visual Studio をアンインストールして
次のリンクから Update 2 のインストーラ(Visual Studio Community 2015 with Update 2)を取得してインストールするだけです。
Visual Studio Release Notes | Visual StudioVisual Studio 2015 Update 2 now available for download


追記:
ぎゃあぁあああ!
update-2 のインストーラでインストールしても update-3 になってしまった!
終わった。
どうやったら update-2 のまま使えるのか…戻す方法とか無いの!?
何よりここまで時間を無駄にしたことに腹が立っている

追記:
と、ここで転機がおとずれる
実はリンク先で取得した Visual Studio は英語版だったので、今までUE4が文字化けして表示していたエラー内容が表示されるようになった
そこをキーワードに検索をかけて解決策の提示にたどり着く

forums.unrealengine.com

具体的な解決方法は
C:\Program Files (x86)\Epic Games\4.12\Engine\Source\Runtime\Core\Public\Windows\WindowsPlatformCompilerSetup.h
ファイルの末尾に#pragma warning(disable : 4599)を追記して Unreal Engine 4.12 をC++で起動してみると良いとのこと。

うおぉおお!初めてコンパイルエラーが起きずにプロジェクトが立ち上がったぞ!
私の環境では解決した!
やっと入門書の通りに作業が開始できる。

できた!
f:id:simplestar_tech:20160702184120j:plain

Unity の MonoBehaviour を継承したスクリプトコンポーネントに感覚が似ていました。
Unreal Engine だと Actor の Location をいじることで Actor の位置を変えることができました。
以下は実装コードの一部です。

#include "GameFramework/Actor.h"
#include "FloatingAnimActor.generated.h"

UCLASS()
class HEADERREPLACEPROJECT_API AFloatingAnimActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AFloatingAnimActor();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	float RunningTime;
	
};

// 以下は実装ファイルの記述

// Called every frame
void AFloatingAnimActor::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	FVector NewLocation = GetActorLocation();
	float DeltaHeight = (FMath::Sin(RunningTime + DeltaTime) - FMath::Sin(RunningTime));
	NewLocation.Z += DeltaHeight * 20.0f;       //Scale our height by a factor of 20
	RunningTime += DeltaTime;
	SetActorLocation(NewLocation);
}

いや、驚きましたよ。
エディタのコンパイルボタンを押したら、即上記のコードの編集内容が反映されてゲームが実行できました。
エントリの目標達成はまだですが、ひとまず一行目に書いたやりたいことまでは確認できました。

リンクメモ

この記事は、無視してください!


まずここ
OpenGL+Objective-C編 - 勉強

理解したらここ
livedoor Techブログ : 猫でもわかるiPhoneで画像にフィルターをかける方法

あと、ここのオプティカルフローの説明良い
https://courses.engr.illinois.edu/cs543/sp2012/lectures/Lecture%2008%20-%20Feature%20Tracking%20and%20Optical%20Flow%20-%20Vision_Spring2012.pdf

うーむ、これ?
http://blog.negativemind.com/2015/05/15/point-cloud-for-unity/
からの
床井研究室 - シェーダで Point Sprite

ここ、いい
画像処理 — OpenCV-CookBook

ヒストグラム平坦化の原理について
ヒストグラム平坦化のアルゴリズム

関数の説明はここ
ヒストグラム — opencv 2.2 documentation


それでもうまくいかなかったら試す
ゴリラになる知識: ガンマ補正



これ試してみるか
【iOS】UIImageとNSString(Base64)の相互変換 - Qiita


まずは動くかみとけ
Unity C# JSONObjectを使って簡単なJSON文字列をパースする - Qiita

Windowsでキーボード割り当てを変更

先日、GPUが壊れてPCが起動できなくなったことがあり
問題の切り分けのためOSの再インストールを行いました。

そのため、使っている英字キーボードのカスタマイズ情報が無くなりました。
再度割り当てるので、次の記事を参考に再割り当てしました。

www.gigafree.net

設定はこちら
f:id:simplestar_tech:20170717140025j:plain

うまくいきました。
環境は Windows 10 64bit

あと、日本語キーボードを接続したのに、英字キーボードとして認識されたときの問題に直面
Windows 10 環境では 設定→地域と言語 からキーボード配列を設定する項目があるので、そこで英字→日本語にして
再起動すると期待通りに日本語キーボードで日本語を打てた(あたりまえだけど)

ナイーブベイズとは

基本から確かめてみたくなったので
もう一度ナイーブベイズについて確認します。

確率の加法定理と乗法定理の式を使うと、ベイズの定理が導けます。

確率の加法定理とは、ベン図を使うと次のイメージです。
f:id:simplestar_tech:20160424133626j:plain
 {
P(A \cup B) = P(A) + P(B) - P(A \cap B)}

確率の乗法定理とは、ベン図を使うと次のイメージです。
f:id:simplestar_tech:20160424134919j:plain
 {
P(A \cap B) = P(A) \times P(B)
}

ん?
これだけではベイズの式は導けませんね。

次の条件付き確率のイメージを使います。
f:id:simplestar_tech:20160424141831j:plain
 {
P(A \cap B) = P(A|B) \times P(B)
}
同様に、次のイメージも使って
f:id:simplestar_tech:20160424140248j:plain
 {
P(A \cap B) = P(B|A) \times P(A)
}

どちらも  {
P(A \cap B)} についての式なので

次の等式は組めます。
 {
P(A|B) \times P(B) = P(B|A) \times P(A)
}

式を変形すると
 {
P(A|B) = \frac{P(B|A) \times P(A)}{P(B)}
}
この式が出ます。
事後確率 {P(A|B)}の計算が、尤度 {P(B|A)}と事前確率 {P(A)}と周辺確率 {P(B)}で行えます。
これがベイズの定理です。

まだ、ナイーブベイズではないので、以降、注意して読んでいってください。

具体的な問題を扱います。

ここで、事象 A を、迷惑メールである、とします。( {P(A)}は迷惑メールである確率)
事象 B はメールタイトルに「hi」,「% off」が同時に含まれる、とします。( {P(B)}はメールタイトルに「hi」,「% off」が同時に含まれる確率)

ん?

事象 B は、二つの事象を含んでいますので、事象 B, C と分けないと文章が作れませんね。

するとベイズの式は次の形となります。

 {
P(A|B \cap C) = \frac{P(B \cap C|A) \times P(A)}{P(B \cap C)}
}

実際問題を解こうとすると、このベイズの式の尤度 {P(B \cap C|A)}の計算が現実時間で解けなくなります。(組み合わせ爆発により)

そこで、次の考え方を取り入れて問題を単純(ナイーブ)にします。

B, C の事象が本当は互いに独立じゃないのに、独立であるとみなす考え方(単純化、ナイーブにする)を使います。
すると、次の無意味な式が導けます。

 {
P(B \cap C|A) = P(B|A) \times P(C|A)
}

この式からは無意味な値しか得られないということを認識してください。
しかし、尤度の計算は極めて高速に終了します。

このような膨大な組み合わせ計算の単純化(ナイーブにする)手法をナイーブベイズと呼びます。

つまり、この問題は
迷惑メールにおけるメールタイトルに「hi」が含まれる確率 {P(B|A)}を集計によって求め
迷惑メールにおけるメールタイトルに「% off」が含まれる確率 {P(C|A)}を集計によって求め
その二つの確率をかけた値に、そもそもの迷惑メールが送られてくる確率 {P(A)}をかけて
メールタイトルに「hi」,「% off」が同時に含まれた時の、迷惑メールである確率 {P(A|B \cap C)}の分子の部分が求まります。

分子の部分?
分母の値が 1 ではない点に注意です。
つまり、次の迷惑メールではない確率も求めなければ、分類問題は解けません。

標準メールにおけるメールタイトルに「hi」が含まれる確率 {P(B|\bar{A})}を集計によって求め
標準メールにおけるメールタイトルに「% off」が含まれる確率 {P(C|\bar{A})}を集計によって求め
その二つの確率をかけた値に、そもそもの標準メールが送られてくる確率 {P(\bar{A})}をかけて
メールタイトルに「hi」,「% off」が同時に含まれた時の、標準メールである確率 {P(\bar{A}|B \cap C)}の分子の部分が求まります。

分母は共通の値であり、この二つの分子の合計値なので、迷惑メールなのか、標準メールなのかの判定は分子だけでも行えます。
分母を出して、迷惑メールである確率 {P(A|B \cap C)}を求めて、0.5以上かどうかを見るというのも、同じ判定結果を得ます。

これが最も単純な問題であり、似たような解説は他のサイトや記事でも多いです。
ナイーブベイズについて、理解が深まったのでこの記事を書いてよかったです。

以上。

人工知能:歴史から学んでみる 3

1950年代から、1990年代前半くらいまで見てきました。
その後の人工知能研究で注目されるようになった手法というものを見ていきたいと思います。

【決定ツリー(決定木)】
これだけだと、ただの木構造のグラフになってしまいますが、ここではID3 - Wikipediaのことを指します。
初出は1979年ころで、対象の分類を最もよく説明する条件分岐を、機械が自分で設計して、具体的な switch 構文を作る技術です。
情報理論エントロピーという尺度があるのですが、このエントロピーが最も小さくなるような条件分岐を探すアルゴリズム
理解しなければいけない所は、このエントロピーが対象の分類の尺度に使えるということです。
クロード・シャノンさんがこの情報理論を確立させたとのことです。
で、そのエントロピーってどうイメージしたらよいかについてですが、私はクラスの数と理解しています。
分類した時にそれぞれの集団内でクラス数が多い分け方だった場合はエントロピーが高く、逆にクラス数が一つまたは少ないとエントロピーが低くなります。
素早くエントロピーが小さくなる分岐を探しだして採用するのがこのID3アルゴリズムです。

そろそろ人工知能の歴史から外れ始めたので、以降は機械学習について一望してみたいと思います。

まずはキーワード拾いに
情報処理学会第78回全国大会
を視察(初めて行きました。論文集もゲット!)

そして、関連記事を読んでみます。

まずはここを読み

www.slideshare.net

今人気の10選を知り
d.hatena.ne.jp

どんなものがあるかを眺めてから
Category:分類アルゴリズム - Wikipedia

簡易説明を聞いて
postd.cc

腰を据えて読みふける
gihyo.jp

すると
どうなるか

少しずつ学んだことを書いていきます。

機械学習にはモデルが存在する】
モデルというのは、対象をモデル化したもので…
こうなっていたらうれしいな!とか、こういう風に説明できるだろうとか、勝手に人間が予測して与えるものがモデルです。
そのモデルにはパラメータが必ず付いていて、そのパラメータをデータから求めるのが「学習」や「推定」と呼ばれる処理です。

【確率の加法定理と乗法定理】
条件付き確率のすべての条件を足し合わせると、周辺確率になる、これが加法定理
同時確率は、条件付き確率と条件の周辺確率をかけたものと等しくなる、これが乗法定理
統計的機械学習はこの確率の加法定理と乗法定理を繰り返し用いることになる。

【確率に対するイメージを改める】
どれくらい起こりうるか、と習ったけど、一旦それを忘れて
どれくらいもっともらしいか、というイメージに置き換えて考えていく
そうすると、世の中の様々な不確かさが確率という形で表現できるようになります。
どれくらいもっともらしいか、このイメージがベイズの考え方だそうです。

【独立じゃないのに独立とみなす】
コインとサイコロのように、互いに独立であれば計算は簡単になるのに
基本的に世の中の出来事は宇宙の果てまで相関を持っています。(観測できないという事象自体からも影響を受けると考えれば、そもそも宇宙に果てなど定義できないという知見でいますが…)
完全に独立はあり得ません。
しかし、独立とみなします。
もう間違っている計算をすることが見え見えですが、現在の計算機パワーを考えると、独立とみなさなければ計算できないのです。
そう、間違っている前提を用いて、計算できることにフォーカスした研究が統計的機械学習なのです。

【ナイーブベイズ
確率の加法定理と乗法定理の式を使うと、ベイズの定理が導けるのですが
このベイズの定理と、独立じゃないのに独立とみなす考え方を使うと(この矛盾を導入しないといけないことを意識できなかったので、ずっと理解できなかったよ!)
例の事後確率の計算が、尤度と事前確率と周辺確率からできるわけですよ。
この手法がナイーブベイズと呼ばれるやり方で、この判定を使ったフィルタをベイジアンフィルタと呼びます。
おお、一度に2つの専門用語に概念が結びつきましたよ。

続きは、次の記事でまとめていきたいと思います。

人工知能の歴史について、今の自分の知識を確認するのに良いページを見つけたので、共有します。
blog.btrax.com