eaglesakuraの技術ブログ

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

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を配置すれば良い
    • ただし、差分マージはしてくれなかった
    • フルで書く必要がある
      • カスタマイズという点では正しいのかもしれない
      • 手軽ではない

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

なぜDockerfileに記述するのか

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

モバイル / サーバーサイドエンジニアの開発環境のセットアップ 2018 Q2

ハードウェア

環境の使い分け

MSI Trident3(2018)

  • BIOSはDELキーで起動する
  • デュアルブートする場合、UEFIから Windows Fast Bootモード をOFFにする
    • デフォルトだとWindowsが起動するか、Legacy側からブートを行ってくれない
続きを読む

Android Studio 3.2 Preview18 所感

Kotlinアップデート

  • 1.2.50

ConstraintLayoutのpackage名がもとに戻っていた

  • 幻だったのだろうか

implementation/apiでbuild.gradleに記述した依存関係がビルドに反映されない

  • Jetifierが悪さをしている可能性がある
  • こいつらを gradle.properties から外すと正常に動作する
android.enableJetifier=true
android.useAndroidX=true
  • Windows版では問題が発生し、Dockerコンテナでビルドすると問題なくビルドできる
// こいつらを含めていろいろ反映されない
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch

Navigation Editor

  • ようやく動作するようになった for Linux
  • Windows版では↑の問題があって正常に動作しない

Unity学習の整理 Inputの基本

InputManager

  • Edit > Project Settings Input でInspectorが開ける
  • 各入力のデフォルトを指定できる
  • 項目名 Horizontal Vertical とか Fire とかの定義もここに入れられる

直近nフレームの入力を得る

  • UniRxで書くとこうなる

    • UniRx標準では Cache に相当する機能を見つけられなかったのでかんたんなOperatorを定義する
    • CacheObservable for UniRx
    • UniRxでは Buffer(n, 1) で 表現できると教えていただいた
  • ここでは直近2フレームをキャッシュする

    • データが A,B,C,D,E,F,G... と流れてくる場合
    • A,B > B,C > C,D... のように直近n個をキャッシュする
    • 入力を開始した瞬間 入力を終了した瞬間 直近の行動をチェックして格ゲーのコマンドのように扱う ようなことを行う
gameObject.UpdateAsObservable()
    .Select(_ => new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")))
    .ObserveOnMainThread(MainThreadDispatchType.FixedUpdate)
    .Buffer(2, 1)
    .Subscribe(Lifecycle, list => Walk(list[0], list[1]));

JetBrains Riderで適用されるCodeStyle

環境ごとのデフォルト

  • Ubuntu(Linux)とWindowsでデフォルトフォーマッタが異なる
  • 大きいところではブレス class Hoge { のブレスが K&R styleBSD style で異なる
  • 基本的にはC#の基本的なコードスタイルを使いたい
  • 改行コードはLinux, Windowsで異なる
    • LF を使いたい

C# の推奨するスタイル