CosやSinをテーブル引きにする効果
-
-
- -
-
追記 2017/2/8 23:20
各所からツッコミを受けました。
テーブル引きの恩恵を受けるようなコードは、現在の実践環境ではあまりなく、普通に関数を使ったほうが有利というのが説が多いです。
以下のテストはキャッシュが効きやすい状態のテストなので一応、テーブル引きが勝っていますが、結構特殊な状況です。
ほんとうは、ちゃんと実際のゲーム中で計測するべきなんですけど、すいませんm(_ _)m
速度的なメリットは怪しいけどテーブル引きのメリットは、
通信量を落とせるとか(角度をfloatの32bitじゃなく8bitとか16bitで持ちたいとき)
値が実行環境に依存しないとか
というメリットがあると言われ、自分も納得しました。
-
-
- -
-
CosやSinをテーブル引きにする効果
ゲーム制作において、高速化のためにCosやSinといった関数をテーブル引きにするというのは、よくある話である。
自分のゲーム制作環境でも少しでも処理を軽くするためにテーブル引きSin,Cosを作ってみようかと思ったのだけれど、そもそもどれぐらい処理の高速化が見込めるのか、Unity上で試してみた。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { public int loopCount = 10000000; System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); public int tableSize = 360; public const float PI2 = Mathf.PI * 2.0f; float[] cosTable; void Start () { cosTable = new float[ tableSize ]; for( int i = 0; i < tableSize; ++i ) { float theta = (float)i / tableSize * PI2; cosTable[i] = Mathf.Cos( theta ); } } [ContextMenu("Test Mathf")] void TestMathf () { stopWatch.Reset(); stopWatch.Start(); float sum = 0.0f; for( int i = 0; i < loopCount; ++i ) { sum += Mathf.Cos( (float)i ); } stopWatch.Stop(); Debug.Log( "time : " + stopWatch.Elapsed + " sum, " + sum ); } [ContextMenu("Test Cos Table")] void TestCosTable () { stopWatch.Reset(); stopWatch.Start(); float sum = 0.0f; for( int i = 0; i < loopCount; ++i ) { sum += getCosFromTable( (float)i ); } stopWatch.Stop(); Debug.Log( "time : " + stopWatch.Elapsed + " sum, " + sum ); } int getCosTableIndex ( float theta ) { return (int)( theta / PI2 * tableSize ) % tableSize; } float getCosFromTable ( float theta ) { int index = getCosTableIndex( theta ); return cosTable[ index ]; } }
1000万回、Cosを計算して加算した結果、自分のMacbook Pro上で、Mathf.Cosは0.552秒、tableを使ったCosは0.453秒とTableを使ったほうが20%ぐらい高速だった。
もっと差が出るかと思っていたのだけど、そうでもなかった。
tableを使った方は精度がイマイチなのでご利用は計画的に。
UnityException: Unable to install APK! Installation failed. See the Console for details
UnityでAndroid版をBuild And Run しようとした時に、突如として表題の例外が発生するようになって困った。
こちらに解決策が↑
Player Settings -> Other Settingsで、Bundle Version Codeをあげたらインストールできた。
たまにUnityが落ちて、意図せずBundle Version Codeが下がっていることがあるので注意。
2017年、Vim周り見直し
半年に1回は見直しています。今回は結局大して変えませんでした。
世間では、Neovimに乗り換えましたとか、プラグイン管理をdein.vimに乗り換えましたという人が多いようですが、自分はNeovimは、まだ不安があるのと、そんなにメリットが分かっていないので、もうちょい様子見。
結局 最新のKaoriya版MacVimに。
dein.vimも設定ファイルを書き換えるのがめんどくさいのと、Neobundleでも速度に満足しているので、今回は見送り。
継続して使用するプラグイン
unite
インクリメンタルサーチで色々探して、色々出来る
unite help
全ヘルプ内をインクリメンタルサーチで探せて便利
vim-indent-guides
インデントに色を付けて見やすくする
vim-quickrun
コードをすぐに実行して確認
neco-look
lookを使って英単語保管機能
vim-bufonly
BufOnlyで自分以外のbufferを削除する
syntastic
syntax checkプラグイン
vimfiler
ファイラープラグイン。あまり使いこなせていない。
lightline
挿入モード、ヴぃジュアルモードなどのモードが見やすくなる
今回から入れてみたプラグイン
vim-colors-solarized
カラースキームsolarized。長いことdesertで固定されていたので、ちょっと気分を変えてみることに。
vim-closetag
tagを閉じてくれる
vim-quickhl
一度に複数の検索結果をそれぞれ異なる色でハイライトできる
yankround
ペースト時にyankの履歴を辿れる
使用を停止、もしくは一時停止するプラグイン
vim-trailing-whitespace
行末にあるスペースを可視化してくれる。
見えると、消したくなる。そして消すのがあまりにめんどくさいので、使わないことに。
unite-mark
マークした箇所をUniteで探して飛べる
結局、マークをあんまり使わなかった
vim-visualstar
ビジュアルモードで選択して、*を押したときに選択した内容で検索をできる。
結局、あんまり使わなかった
AnsiEsc.vim
ログファイルを色づけしてくれる
結局、あんまり使わなかった
ctrlp
yankroundと一緒に使うことでyankの履歴を表示して選択して、ペーストってできる。
自分の環境では何故かうまく動作しなかったのと、Unite yank で良いかなぁと。
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
起動するとバージョンが表示されて、しばらくするとフェードアウトするようになっています。