eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

Android Emulator(KVM/Ubuntu)でサウンドを有効にするとノイズが乗ることに対する対策

問題点

コマンドラインからサウンド無効で起動する

# ついでにCold Bootしたければ -no-snapshot オプションでできる
emulator @your_avd_name -no-audio -no-snapshot

Desktop Entryにすることで簡単に起動

[Desktop Entry]
Name=Android Emulator
Exec=/path/to/emulator @Default -no-audio -no-snapshot
Terminal=false
Type=Application
Icon=/path/to/icon/android-emulator.png
Categories=Development;Android;Emulator
StartupNotify=false

Android エミュレータのAMD CPU(Hyper-V)サポートの所感

公式情報

android-developers.googleblog.com

  • 書いてあるとおり、 Windows Hypervisor Platform を有効化しないと起動できない
  • Hyper-Vを有効化しているだけだと、Hypervisorは有効化してない場合があるので注意

動作の感想

  • ちゃんとDocker for Windows環境と共存できる
  • Trident3(i7-8700, RAM32GB、Windows10 Pro)で動作した
  • 動作が緩慢
    • 正直、 HAXM とか KVM(Linux) で動作したほうがキビキビ動く
    • 無理して使うようなものでは無いが、あると便利という感じ

システムレイヤーにOpenGL対応Viewを追加する

Manifest設定

  • システムレイヤーへの描画は専用のPermissionがある
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

WindowManagerでViewを登録

  • レンダリング用のViewとタップ用のViewを分けると設計が楽になる場合がある
    • SurfaceViewは軽量だが、View移動ができない
      • OpenGL側でViewportを調整してあげると良い
    • Viewを移動するならTextureViewが良い
// レンダリング用のフラグ
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        // レイアウトの幅 / 高さ設定
        WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT,
        // レイアウトの挿入位置設定
        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
        // ウィンドウ属性
        // TextureViewを利用するには、FLAG_HARDWARE_ACCELERATED が必至となる。
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                //
                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_FULLSCREEN
        ,
        // 透過属性を持たなければならないため、TRANSLUCENTを利用する
        PixelFormat.TRANSLUCENT);
// Viewの位置はmarginで調整する
params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;


windowManager.addView(hogeView, params);
// システムレイヤーのView位置を移動する
WindowManager.LayoutParams params = (WindowManager.LayoutParams) hogeView.getLayoutParams();
synchronized (updateRunner) {
    params.x = reqX;
    params.y = reqY;
    params.width = reqW;
    params.height = reqH;
}
windowManager.updateViewLayout(hogeView, params);

Android Studio 3.2-Beta1 導入

Experimental設定が追加

  • Navigation Editorが標準で無効化された
  • 新たに Settings > Experimental が追加された
    • そこで有効化できる

旧バージョンからアップデートしてビルドが通らない

  • ~/.gradle/ を削除することで復旧できる
  • ASの場合は Invalidate Caches / Restart

Windows版でビルドが通らなかった問題

  • 今回から改善された
  • cygwinから assemble が行えるようになった
    • 2バージョンぶりの成功
  • ASでビルドが通らない問題が発生した
    • Settings > Compiler でgradleオプションを変更した
    • parallel にチェックと -PdevBuild -Dorg.gradle.caching=true を追加してリビルド

Emulator

  • フリーズする問題が発生した
    • 久々に起動したからいつからかは不明
  • Emulatorを作り直して対処

Unity学習 よくあるJoystickの移動系を再現する

よくある入力系とは

  • 左スティックで移動する
    1. スティックを上(奥)に倒すと画面奥方向に移動
    2. スティックを下(手前)に倒すと画面手前方向に移動
    3. スティックを左に倒すと画面左方向に移動
    4. スティックを右に倒すと画面右方向に移動
  • よくある入力系なので、アセットも充実している
    • だが、久々に自分で実装してみよう
    • 実に8年ぶりの実装である

移動方向を計算する

  • カメラからみた自キャラの方向を計算する
  • 自キャラの方向に、ジョイスティックの方向を加算する
    • カメラがグローバル座標に対して45度のとき、ジョイスティックを上(0度)に倒すと、グローバル座標45度方向に移動する
    • カメラがグローバル座標に対して45度のとき、ジョイスティックを下(180度)に倒すと、グローバル座標225度方向に移動する
    • XZ平面上で動作する場合に有効な制御
      • 人間はXZ平面で概ね生きているので、だいたい問題ない
  • キャラを移動方向に向ける
    • つまり、キャラの向きと移動方向は独立している
    • アクションゲームでよく見る
      • FF13は急旋回すると、キャラが一度立ち止まるモーションが入る
        • リアルだけど、好みが分かれると思う
  • カメラがキャラ真上にあると死ぬ
    • atan2の限界である

カメラ設定

  • カメラもジョイスティックで移動できるようにする
  • データとして プレイヤーからの距離 Global Yaw Global Pitch をもたせる
  • プレイヤーを囲む球面上をカメラ位置が移動し、LookAtはプレイヤーの周辺に固定することになる
    • AtはEmpty Objectをターゲットにする
  • 右JoystickはコントローラーによってUnity側のバインドが異なる
    • 一つのコントローラーだけ使ってると、別なコントローラーで痛い目を見る

Animator追加

  • 歩く 止まる でモーション制御が必要である
  • 単純な遷移制御のみで良いため、 Animator.CrossFadeInFixedTime(StateName, Duration) で遷移させる
    • 名前指定できる、遷移時間設定できるので、多くの場面で事足りそう
    • 参考URL
    • 毎フレーム、必要なStateをSubjectに流し続けて、変化したらObserverがハンドリングする
private Subject<string> _stateName = new Subject<string>();
protected override void Awake()
{
    base.Awake();
    _stateName.DistinctUntilChanged()
        .Subscribe(state => Animator.CrossFadeInFixedTime(state, AnimationTransitionDurationSec));
}    

private void WalkByUserInput(Vector2 beforeInputAxis, Vector2 currentInputAxis)
{
    // Move User
    if (!currentInputAxis.IsZero())
    {
        _stateName.OnNext("Run");
    }
    else
    {
        _stateName.OnNext("Idle");
    }
}

移動速度とフレームレート

  • FixedUpdate で位置更新を行う
  • フレームレート固定でいどうするので、システムから値を取得する
    • 参考URL
    • 前フレームから経過時間取得 Time.deltaTime
    • ターゲットフレームレート取得 Application.targetFramerate でSet/Get

所感

  • ターゲットロックなしだと、 カメラ移動 + ジョイスティック上 で好きな方向に移動できてしまう
    • ちょっと気持ち悪い
    • アホの子っぽい
  • カメラと移動を独立させる
    • ある程度緩和されるけど、カメラを移動させすぎるとやっぱり気持ち悪い動きになる
  • カメラロックオンは偉大である

ARCore for Unityの事始め

ARCoreのサポート端末

  • 少し前にサポート端末が拡充された
    • Nexus5X, Nexus6Pがサポートされた
    • Xperia XZ1Compactもサポートされた
  • 一般的に使うには辛い
    • ARKitのほうは手軽で強い

コアライブラリ

  • ARCore by Google
  • コアライブラリ
    • これがないと始まらない
    • アプリ単体で動かないので、ちょっと気になるところではある
  • たまにアップデートされている

ARCore for Unity

  • Unity用のSDKがある
    • HelloARが付属している
    • Unity画面でプレビューするためのapkも付属している
      • しかし動作しない
  • Hello ARCoreを実行するとプレビューサポート用APKをインストールできる
    • しかし正常動作しない
    • Camera Permissionを取得しようとしないので、自分でON
      • しかし動作しない
      • なにかが抜けてそう
    • ARcoreライブラリが入っていない場合
      • インストール画面が出る
      • Google IOで発表されてたやつ
      • 便利
    • Unity+ARCoreのアプリをいくつかPlay Storeからインストール
      • 落ちるか、カメラが起動しない

Player > Android > XR Settings

アプリにCamera permissionを付与する

  • Plugins/Android 配下にカスタマイズしたAndroidManifest.xmlを配置すれば良い
    • ただし、差分マージはしてくれなかった
    • フルで書く必要がある
      • カスタマイズという点では正しいのかもしれない
      • 手軽ではない

動作OK/NG

Unity EditorとSDKと端末の組み合わせによって、動作する・しないが異なった

  • Unity2017 LTS
    • Xperia XZ1Compact / OK
    • Pixel2 / NG
  • Unity2018
    • Xperia XZ1Compact / NG
    • Pixel2 / NG

Dockerで開発環境をポータブルにする

なぜDockerfileに記述するのか

  • pullするだけでセットアップが終わる
    • 手軽に再現できる
  • 複数OSの上で同じ環境を使える
    • WindowsMacで作業中にLinux環境が必要になる場合がある
    • OSや環境固有の問題なのか、別な問題なのかの切り分けを行いたい
  • 開発環境のバージョン管理を行える
    • 古い環境や、特定用途に特化した内容等を構築しておける
  • 環境を壊すことを恐れずにコマンド実行が行える
    • 壊れても再度コンテナを起動すれば良い
続きを読む