UnityException: Unable to install APK! Installation failed. See the Console for details

UnityでAndroid版をBuild And Run しようとした時に、突如として表題の例外が発生するようになって困った。

answers.unity3d.com

こちらに解決策が↑

Player Settings -> Other Settingsで、Bundle Version Codeをあげたらインストールできた。

たまにUnityが落ちて、意図せずBundle Version Codeが下がっていることがあるので注意。

use of undeclared identifier 'Unity' とか 'UI' のエラー

UnityでiOS版のビルド時に、Scripting BackendをMono2xにしてStriping Levelを何某かにしていると、以下のようにXCode側でエラーが出ることがあるもよう。

f:id:wkpn:20170116200832p:plain

とりあえずstripping levelをdisabledにすれば、一応回避できる。

Mono2xでのビルドは、基本デバッグ用途でしか無いので、とりあえずこれで良いかな。

XCodeでビルドした時に「Appの有効なaps-environmentエンタイトルメント文字列が見つかりません」というエラーが出る

XCodeでビルドした時に「Appの有効なaps-environmentエンタイトルメント文字列が見つかりません」というエラーが出た。

これは証明書にPush Notificationが無いかららしい。

最近のXCodeは「Automatically manage signing」にチェックを入れておくと証明書を勝手に作ってくれるので、Capabilityの設定部分でPush Notification項目をONにすれば勝手に証明書側も更新してくれる。

f:id:wkpn:20170116200204p:plain

2017年、Vim周り見直し

半年に1回は見直しています。今回は結局大して変えませんでした。

世間では、Neovimに乗り換えましたとか、プラグイン管理をdein.vimに乗り換えましたという人が多いようですが、自分はNeovimは、まだ不安があるのと、そんなにメリットが分かっていないので、もうちょい様子見。
結局 最新のKaoriya版MacVimに。

dein.vimも設定ファイルを書き換えるのがめんどくさいのと、Neobundleでも速度に満足しているので、今回は見送り。

継続して使用するプラグイン

Neobundle

プラグイン管理。dein.vimへの移行が推奨されていますが現状に満足しているのでそのまま。
半年後に再検討予定。

unite

インクリメンタルサーチで色々探して、色々出来る

unite help

全ヘルプ内をインクリメンタルサーチで探せて便利

machit

括弧の上で%を押すと対応する反対側の括弧に飛べるけど、それをいろんなものに拡張してくれる。
begin,endとか、とか。

vim-indent-guides

インデントに色を付けて見やすくする

vim-quickrun

コードをすぐに実行して確認

neco-look

lookを使って英単語保管機能

vim-bufonly

BufOnlyで自分以外のbufferを削除する

syntastic

syntax checkプラグイン

neosnippet.vim, neosnippet-snippets

スニペットプラグイン。あまり使いこなせていない。

vimfiler

ファイラープラグイン。あまり使いこなせていない。

Omnisharp, vim-dispatch

C#でインテリセンスを効かせるために。

vim-csharp

C#シンタックスハイライト

lightline

挿入モード、ヴぃジュアルモードなどのモードが見やすくなる

vim-easy-align

コード整形プラグイン

vim-textobj-indent, vim-textobj-user,

インデントが揃っている部分をテキストオブジェクトにしてくれる

vim-commentary

コメントアウトしたりコメントインしたりを簡単に

今回から入れてみたプラグイン

vim-colors-solarized

カラースキームsolarized。長いことdesertで固定されていたので、ちょっと気分を変えてみることに。

vim-endwise

Ruby向けにendを自動挿入してくれる。しかしRubyのコードを描く頻度は少ない。

vim-monster

Ruby用の補完。しかしRubyのコードを描く頻度は少ない。

ruby_hl_lvar

Ruby用のローカル変数ハイライト。しかしRubyのコードを描く頻度は少ない。

vim-closetag

tagを閉じてくれる

vim-gitgutter

Git管理下のファイルをVim上で変更内容を確認する

vim-fugitive

VimからGitを使いやすくしてくれる

vim-quickhl

一度に複数の検索結果をそれぞれ異なる色でハイライトできる

yankround

ペースト時にyankの履歴を辿れる

使用を停止、もしくは一時停止するプラグイン

vim-trailing-whitespace

行末にあるスペースを可視化してくれる。
見えると、消したくなる。そして消すのがあまりにめんどくさいので、使わないことに。

unite-mark

マークした箇所をUniteで探して飛べる
結局、マークをあんまり使わなかった

vimshell

VimからShellを起動するスクリプト
結局、あんまり使わなかった

vim-visualstar

ビジュアルモードで選択して、*を押したときに選択した内容で検索をできる。
結局、あんまり使わなかった

vim-ref

vimで辞書をみるプラグイン
結局、あんまり使わなかった

vim-surround

テキストを囲むことに特化したプラグイン シングルクオートとダブルクオートの入れ替えなど
結局、あんまり使わなかった

onedark

AtomのOne Darkを再現するためのカラースキーマ
c#ではイマイチな気が...

AnsiEsc.vim

ログファイルを色づけしてくれる
結局、あんまり使わなかった

ctrlp

yankroundと一緒に使うことでyankの履歴を表示して選択して、ペーストってできる。
自分の環境では何故かうまく動作しなかったのと、Unite yank で良いかなぁと。

vim-processing

processingとvimを連携するプラグイン。もうprocessingを使うことは、ほぼほぼないだろうということで。

AndroidManifest.xml:20: error: Error: No resource found that matches the given name (at 'theme' with value '@style/Theme.IAPTheme のエラー対応

UnityでAdMobを入れ直したからか、Android版をビルドするときに以下のようなエラーが出るようになっちゃいました。

CommandInvokationFailure: Failed to re-package resources.
/Users/wakepon/Library/Android/sdk/build-tools/23.0.2/aapt package --auto-add-overlay -v -f -m -J "gen" -M "AndroidManifest.xml" -S "res" -I "/Users/wakepon/Library/Android/sdk/platforms/android-24/android.jar" -F bin/resources.ap_ --extra-packages com.chartboost.sdk.unity:com.android.vending.billing:com.google.unity:com.unity.purchasing.googleplay:com.unity.purchasing -S "/Users/wakepon/projects/Solokus/Temp/StagingArea/android-libraries/GoogleAIDL/res" -S "/Users/wakepon/projects/Solokus/Temp/StagingArea/android-libraries/GooglePlay/res" -S "/Users/wakepon/projects/Solokus/Temp/StagingArea/android-libraries/common/res"

stderr[
AndroidManifest.xml:16: error: Error: No resource found that matches the given name (at 'value' with value '@integer/google_play_services_version').

AndroidManifest.xml:20: error: Error: No resource found that matches the given name (at 'theme' with value '@style/Theme.IAPTheme').

]
stdout[
Configurations:
 (default)

Files:
  AndroidManifest.xml
    Src: () AndroidManifest.xml

Resource Dirs:
Including resources from package: /Users/wakepon/Library/Android/sdk/platforms/android-24/android.jar
applyFileOverlay for drawable
trying overlaySet Key=app_banner.png
trying overlaySet Key=app_icon.png
applyFileOverlay for layout
applyFileOverlay for anim
applyFileOverlay for animator
applyFileOverlay for interpolator
applyFileOverlay for transition
applyFileOverlay for xml
applyFileOverlay for raw
applyFileOverlay for color
applyFileOverlay for menu
applyFileOverlay for mipmap
Processing image: res/drawable-xhdpi/app_banner.png
Processing image: res/drawable-ldpi/app_icon.png
Processing image: res/drawable-mdpi/app_icon.png
Processing image: res/drawable-hdpi/app_icon.png
    (processed image res/drawable-ldpi/app_icon.png: 97% size of source)
Processing image: res/drawable-xhdpi/app_icon.png
    (processed image res/drawable-mdpi/app_icon.png: 95% size of source)
Processing image: res/drawable-xxhdpi/app_icon.png
    (processed image res/drawable-hdpi/app_icon.png: 95% size of source)
Processing image: res/drawable-xxxhdpi/app_icon.png
    (processed image res/drawable-xhdpi/app_icon.png: 92% size of source)
    (processed image res/drawable-xhdpi/app_banner.png: 93% size of source)
    (processed image res/drawable-xxhdpi/app_icon.png: 93% size of source)
    (processed image res/drawable-xxxhdpi/app_icon.png: 91% size of source)
    (new resource id app_banner from xhdpi-v4/drawable/app_banner.png #generated)
    (new resource id app_icon from ldpi-v4/drawable/app_icon.png #generated)
    (new resource id app_icon from mdpi-v4/drawable/app_icon.png #generated)
    (new resource id app_icon from hdpi-v4/drawable/app_icon.png #generated)
    (new resource id app_icon from xhdpi-v4/drawable/app_icon.png #generated)
    (new resource id app_icon from xxhdpi-v4/drawable/app_icon.png #generated)
    (new resource id app_icon from xxxhdpi-v4/drawable/app_icon.png #generated)
]
exit code: 1
UnityEditor.Android.Command.Run (System.Diagnostics.ProcessStartInfo psi, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.PostProcessor.Tasks.TasksCommon.Exec (System.String command, System.String args, System.String workingdir, System.String errorMsg, Int32 retriesOnFailure)

対処

Plugins/Android/GoogleMobileAdsPlugin/AndroidManifest.xmlにある、

<!-- InAppPurchase Activity -->
<activity android:name="com.google.android.gms.ads.purchase.InAppPurchaseActivity"
    android:theme="@style/Theme.IAPTheme"/>

という部分をコメントアウトしたらビルドが通るようになりました。

AdMobで自社広告を出すときにアイテム課金に対する広告を入れられるとか、そんなんらしいので、その機能を使わないならコメントアウトしても大丈夫みたいです。

ゲーム中にバンドルバージョンを表示する

バグ報告を受けたときに「えっ、それどのバージョンのロムで発生したの?」って聞きたいときにタイトル画面などでバンドルバージョンを表示するようにしておくと便利だったりします。

バンドルバージョン自体はUnityEditor.PlayerSettings.bundleVersionで取得できるのですが、厄介なのは、これはUnityEditorで動かしている時以外は取得できないことです。

じゃあ、UnityEditor以外でバンドルバージョンを知るために、一旦ファイルに書き出しておこう!っていう発想になったりします。

Unityの中の人に質問したら、Stack Over Flowに、同様のことを質問しているのがありましたよーって教えてくれました。

これです↓
stackoverflow.com

実装説明

まず、最初にCurrentBundleVersion.csというファイルを作っておきます。

中身は、こんな感じです。

public static class CurrentBundleVersion
{
	public static readonly string version = "0.0";
}

次に、BundleVersionChecker.csという名前の以下のようなスクリプトをEditorフォルダ以下に置いておきます。

using UnityEngine;
using UnityEditor;
using System.IO;

[InitializeOnLoad]
public class BundleVersionChecker
{
    const string ClassName = "CurrentBundleVersion";
    const string TargetCodeFile = "Assets/" + ClassName + ".cs";

    static BundleVersionChecker () {
        string bundle_version = PlayerSettings.bundleVersion;

        string last_version = CurrentBundleVersion.version;
        if (last_version != bundle_version) {
            Debug.Log ("バージョンが新しくなりました!" + TargetCodeFile + "内に書かれたバージョンを" + last_version +"から" + bundle_version + "に変えます。" );
            CreateNewBuildVersionClassFile (bundle_version);
        }
    }

    static string CreateNewBuildVersionClassFile (string bundle_version) {
        using (StreamWriter writer = new StreamWriter (TargetCodeFile, false)) {
            try {
                string code = GenerateCode (bundle_version);
                writer.WriteLine ("{0}", code);
            } catch (System.Exception ex) {
                string msg = " threw:\n" + ex.ToString ();
                Debug.LogError (msg);
                EditorUtility.DisplayDialog ("Error クラスを作りなおし中にエラーが発生しました!", msg, "OK");
            }
        }
        return TargetCodeFile;
    }

    static string GenerateCode (string bundle_version) {
        string code = "public static class " + ClassName + "\n{\n";
        code += System.String.Format ("\tpublic static readonly string version = \"{0}\";", bundle_version);
        code += "\n}\n";
        return code;
    }
}

このBundleVersionChecker.csのstaticコンストラクタが起動すると、CurrentBundleVersion.cs内のversionを書き換わります。

BundleVersionChecker.csはEditorフォルダ以下に置かれているので、コンパイルが走るタイミングでスタティックコンストラクタが呼ばれて書き換えてくれます。


サンプルプロジェクトをgithubに置いておきます。
github.com

起動するとバージョンが表示されて、しばらくするとフェードアウトするようになっています。

OnTriggerEnter2DとOnCollisionEnter2Dの違い

OnTriggerEnter2DとOnCollisionEnter2Dの違いが分からん!

更に言うと、OnCollisionExit2DとOnTriggerExit2Dの違い、OnCollisionStay2DとOnTriggerStay2Dの違いも分からん!

っとなったので調べました。2Dについて書いていますが、基本3Dも一緒だと思います。

1.引数が違う

OnCollisionEnter2DとOnTriggerEnter2Dですが、よくよく見ると引数が違います。

void OnTriggerEnter2D( Collider2D other) { ... }
void OnCollisionEnter2D ( Collision2D other ) { ... }

1つ目の違いはここです。

綴りが似ているので最初気が付きませんでした。しかし、CollisionとColliderってどう違うんでしょう?

CollisionとColliderの違い

Collisionは衝突が発生した時の情報を受け渡しするためのクラスのようです。衝突時の衝突点や相対速度、衝撃の強さなどの情報が保持されています。

Unity - Scripting API: Collision


Colliderは、衝突判定をさせるためのコンポーネントでGameObjectにアタッチして使うクラスです。

Unity - Scripting API: Collider

2.使用する場面が違う。

実は使い分けは簡単で、ColliderのisTriggerがオンの時は、OnTrigger〜系のコールバック、オフの時はOnCollision〜系のコールバックを使えばOKです。

ちなみに同時に両方呼ばれることは無いみたいです。どちらかしか呼ばれません。

しかし、ColliderのisTriggerフラグって何なんでしょう?

トリガーってなに?

ColliderはisTriggerというフラグを持っています。これを有効にすると Rigidbody の衝突判定を行わなくなります。

分かりやすい例を挙げます。

f:id:wkpn:20161003120454p:plain

図で、青い四角も赤い四角も、どちらもBoxCollider2Dがついています。さらに青い方には、Rigidbody2Dもついているので、ゲームをスタートすると重力によって落下し始めます。

f:id:wkpn:20161003120504p:plain

isTriggerがオフのときには、下図のように赤い四角の上に青い四角が乗っかります。

f:id:wkpn:20161003120511p:plain

isTriggerをオンにすると、下図のように赤い四角に乗らずにスルーしまて落下し続けます。(OnTrigger系のCallbackは発生します。)

ちなみに、赤い四角、青い四角、どちらか一方だけでもisTriggerを有効にすれば、すり抜けるようになりTrigger系のコールバックが呼ばれるようになります。

まとめ

  1. 衝突して反射するような物理挙動をするオブジェクトに仕込むときはOnCollision〜系のコールバックを使う
  2. isTriggerフラグを立てて、触れたかどうかだけ判断したいようなオブジェクトに仕込むときはOnTrigger〜系のコールバックを使う
  3. それぞれ引数に入ってくる型が違うので注意