カテゴリーアーカイブ:チュートリアル

Blenderでゲームエンジン用のノーマルマップを生成

Blenderで作られたモデルをノーマル(法線)マップとして書き出す事ができます。細かいモデルをこのようにノーマルとして書き出すことによって、効率よくUnityやUnreal Engineでレンダリングする事ができます。しかし、Blenderが内部で扱っているノーマルの形式が一般的に使われるノーマルマップの形式と違うので、変換に注意が必要です。 まず、目指すノーマルマップはこんな感じです。 Blenderでいくつかのオブジェクトを並べて同様なシーンを用意しておきます。(もちろん、これはチュートリアル用のシーンです。) まず、出力フォーマットを確認しましょう。レンダーエンジンはeeveeでもCyclesでもいいです。 シーン設定で、解像度を2の累乗にします。1024、2048と4096が一般的です。 次は重要な設定があります。Blenderの標準設定で、色を「綺麗」に出力するようになっています。これでレンダリングの写実性がぐんとあがりますが、今回はその調整が邪魔です。 シーン設定の一番したにある「カレーマネジメント」で「ビュー変換」を「Raw」に変えます。 次は、ノーマル情報をレンダリングした時に書き出してもらうように設定します。 カメラはある程度自由ですが、平行投影のカメラで真正面から見るようにしておきます。 キーパッドの0でカメラ目線でシーンを見て、カメラ平行投影スケールパラメータを調整して、すべてのオブジェクトが映るようにします。 これで、準備ができたのでレンダリング(F12)を行います。レンダリングが完了したら、「Compositing」タブに移動します。 最初は何もないですが、「ノードを使用」にチェックを入れると、コンポジット用のノードが表示されます。 ここで書き出される画像を処理することができます。結果を見るために、下の領域に「画像エディタ」を表示します。 表示する画像を「Render Result」にします。 今はなにもせずに、レンダリングされた画像を書き出しますが、代わりにノーマルをコンポジットノードの「画像」入力に接続するとこうなります。 予想していた色と違いますね。ノーマルマップは法線ベクトルを画像のRGBで記録します。法線ベクトルのx、y、z値は必ず-1から1までに収まります。RGB画像はマイナス値がないので、-1を0%にして、1を100%にして記録します。 上 (R: 50%, G: 100%, B: 50%) 右 (R: 100%, G: 50%, B: 50%) 下 (R: 50%, G: 0%, B: 50%) 左 (R: 0%, G: 50%, B: 50%) 前 (R: 50%, G: 50%, B: 100%) しかし、Blenderではこうなります。 上 (R: […]

Unityで三人称視点のキャラクターコントローラを作ってみよう(第6弾)

以前のチュートリアルはこちらです: 第1弾:準備と入力の設定 第2弾:ジャンプと地面の検出 第3弾:移動 第4弾:カメラ 第5弾:アニメーション 細かい移動の演出 以前のチュートリアルでアイドリング状態から走りアニメーションを切り替えるシステムを作りました。しかし、走り出した時や止まった時は動きが不自然でした。ここでは、ブレンドツリーという機能を使って移動する動きをより細かく設定します。具体的に移動速度によって以下のパターンに切り替えます: アイドリング(静止) 歩き 小走り 走り 追加のアニメーションが必要ですので、Mixamoから適切な「歩き」と「小走り」アニメーションを探します。ダウンロード手順は前回のチュートリアル同様ですので、説明を省きます。 インポートしたアニメーションは前回同様に、リグ設定を変えてループ再生を有効にします。 ブレンドツリー 静止、歩き、小走りと走りの切り替えは前回のような遷移ではなく、よりパワフルなブレンドツリーを使います。ブレンドツリーは文字通りと複数のアニメーションをブレンドさせる方法です。つまり、歩き→小走りという明確なトランジションではなく、移動速度に合わせて演出を徐々に歩きから小走りにブレンドしていきます。 まず、アニメーターの「OnGround」サブステートマシンに「Locomotion」(移動)という新しいブレンドツリーを追加します。 インスペクターで「Blend Tree」と書かれているところをダブルクリックして、ブレンドツリーを編集します。 ブレンドツリーは1次元(1D)と2次元(2D)のツリーがあります。一次元のツリーは一つのパラメータだけで制御します。とりあえずこちらを使ってみます。ブレンドを制御するパラメータをMovementSpeedにします。そして、ブレンドするアニメーションクリップを追加します。 ブレンドをプレビューしたいので、インスペクターの下で再生を開始します。 プレビューしてみると、歩きと小走り、小走りと走りがブレンドされている状態だとキャラクターの走り方がおかしいのが分かると思います。 原因はダウンロードした小走りのアニメーションです。他のアニメーションは1サイクル(左右一歩ずつ)しかありませんが、小走りは何歩かがあります。Mixamoからダウンロードしなおさなくても直せます。プロジェクトウィンドウで街頭のクリップを選択して、インスペクターで編集します。 「Animation」タブで終了のフレームを調整します。 変更を適用して、ブレンドツリーの編集に戻ります。アイドリングから走りまでのブレンドが滑らかになったことが確認できます。 デフォルトで制御するパラメータの最高値が「1」になっていますが、MovementSpeedはキャラクターの最高速度まで上がります。 歩く速度と小走りの速度もThresholdパラメータで設定します。 細かい微調整が残っていますが、プレーして動作確認をしながら行いましょう。 ブレンドツリーの調整が一旦終わったので、アニメーターで繋げます。最初は、「Locomotion」をレイヤーのデフォルトアニメーションにします。 せっかく作りましたが、既存の「Idle」と「Run」を削除します。「Locomotion」がすべてその役割を果たしてくれるからです。 「Locomotion」から「(Up) Base Layer」への遷移を追加します。 動作確認します。 ここまで出来たら各モーションの再生速度やThresholdでさらに自然な動きを目指します。例えば、上の動画でアイドリングから歩きへの切り替えがまだイマイチですから、歩きの位置を調整しました。 2次元のブレンドツリー 移動をさらにリアルにしたいなら、曲がった時に曲がりながら走るアニメーションをブレンドツリーに追加しましょう。 これが使える前にアニメーターに新しいパラメーターを追加します。 このパラメーターをスクリプトで設定するので、Characterスクリプトにプライベートプロパティを追加します。 ApplyMotionでアバターの向きを変えるコードに曲がりの角度計算を追加します。 そして、Updateでこの結果をAnimatorに送ります。 一応、Animatorウィンドウを見ながら動作確認をしましょう。左右曲がる時に、Turnパラメーターが変わります。 ここまで出来たら、ブレンドツリーを選択して、タイプを1Dから「2D Freeform Cartesian」に変えます。 パラメータをMovementSpeedとTurnにします。 ブレンドするモーションがすべて同じ位置に配置されてしまうので、切り離します。 x軸がMovementSpeedですので、以前の1Dのブレンドツリーを再現します。 ここでもう一度動作確認をします。以前と同じ動きになっていることを確認します。 追加した曲がりながら走るモーションを2度追加します。 2つ目のアニメーションのミラー(左右反転)パラメータにチェックを入れます。これで右に曲がるモーションと左に曲がるモーションになります。 2つのモーションを走りと揃えて配置します。 動作確認してみると、曲がった時に確かに曲がるアニメーションが再生されますが、左右に移動方向を変えた時にアニメーションが急に切り替わってしまうのが気になります。滑らかにするためにコードを少し修正します。 この修正で動作確認をしてみると… 曲がりアニメーションがちゃんと切り替わります。

Unityで三人称視点のキャラクターコントローラを作ってみよう(第5弾)

以前のチュートリアルはこちらです: 第1弾:準備と入力の設定 第2弾:ジャンプと地面の検出 第3弾:移動 第4弾:カメラ アニメーション チュートリアルの最初にMixamoからキャラクターのモデルとアイドリングアニメーションをダウンロードして、使ってきました。歩き、走り、ジャンプができるようになりましたが、アニメーションが変わらず極めて不自然ですね。今回のチュートリアルで新しいアニメーションのパターンをダウンロードしてキャラクターの演出を改善していきます。 始める前に少し注意しておきたいのは、皆さんが普段遊んでいる三人称視点のゲームはキャラクターアニメーションのパターンが非常に多いことです。キャラクターがあらゆるシチュエーションにおいて自然に動いて、生きているように見えるのは、アニメーターの大変な作業のおかげです。例えば「歩く」動作でもこんなアニメーションのバリエーションを用意しなければならないかも知れません。 普通のスピードで歩く ゆっくり歩く 急いで歩く 曲がりながら歩く(普通、ゆっくり、早く) 慎重に歩く しゃがみながら歩く 崖っぷちでバランスを取りながら歩く ケガして歩く 武器を持って歩く 銃や弓で狙って歩く など、など、など。 数多くのアニメーションクリップを用意して、条件によって再生を切り替えるのが今も普通の方法ですが、アニメーションの動きを動的に生成するプロシージャルアニメーションという手法もあります。また、数年前から機械学習を使ってより高度な方法でキャラクターを動かしてさらに自然な歩き方をさせる研究が発表されていますが、市販のゲームでまだ普及していません。 プロシージャルアニメーションも機械学習アニメーションも非常に面白いですが、ここで説明するのは従来のアニメーションクリップの切り替えです。 アニメーションクリップの用意 チュートリアルを始めた時と同様にMixamoで必要なクリップをダウンロードします。使うクリップを徐々に増やしていきますが、とりあえずこの2つのクリップを用意しましょう。 移動 ジャンプ 移動アニメーションはキャラクターの移動速度によって「Walk」か「Run」で検索しましょう。私は少し早めの移動のキャラクターにしたいので「Run」でさがしました。 いいアニメーションクリップを見つけたら、設定で「In Place」を有効にします。キャラクターの実際の移動はスクリプトが行うので、キャラクターが静止して走る様子を確認したいです。 では、気に入るアニメーションクリップを見つけたらダウンロードします。 ダウンロード設定で必ず「Format」を「FBX for Unity」にして、「Skin」を「Without Skin」にします。ここの「Skin」はキャラクターのモデルデータです。すでにあるので、アニメーションデータだけをダウンロードします。 歩きのアニメーションのダウンロードが終わったら次はよさそうな「Jump」のアニメーションを探します。様々なジャンプがありますが、一応静止した状態のジャンプをしておきます。 ダウンロードフォルダーに2つのFBXファイルが追加されました。 これから使うアニメーションのアセットがどんどん増えるのでUnityの方でアニメーション用のフォルダーを作成します。 このフォルダーの中にダウンロードしたFBXファイルを移動します。 両方のアニメーションを選択して、インスペクターで読み込み設定を修正します。 「Rig」のアニメーションタイプを「ヒューマノイド」にします。次は最初に用意したモデルのアバター定義(リグの設定)を使用するように設定します。そうしないと姿勢が少しおかしくなります。 「適用する」ボタンを押して再読み込みをします。 デフォルトでは読み込んだアニメーションがループ再生されないので、この設定も変えなければなりませんが、個別にアセットを編集しないとその設定が表示されません。一つずつ歩きのアニメーションクリップと走りのアニメーションクリップを選択して、インスペクターのアニメーションタブで「時間をループ」を有効にして、変更を適用します。 これから他のアニメーションクリップを追加しますが、同じ手順でダウンロードして読み込んでください。 アニメーターの準備 Unityでアニメーションクリップの切り替えはアニメーターが行います。プレーヤーキャラクターのインスペクターでAnimatorコンポーネントの「コントローラ」をダブルクリックしてアニメーター画面を表示します。 これはアニメーションクリップの遷移図になっています。最初(Entry)はデフォルトのアニメーションクリップ(オレンジ色の)である「Idle」が再生されるようになっています。追加した2つのクリップをこの画面に追加しますが、その前にあらかじめ整理しておきましょう。アニメーションのクリップが結構多くなるとこの遷移図がスパゲッティ状態になってしまわないように、サブステートマシンを作成します。「ステートマシン」とは様々な状態を条件によって切り替える遷移図のことでゲームアニメーション以外にゲームAIでよく使われます。 サブステートマシンの名称を「OnGround」と「InAir」にします。 これは、地面に立っている時と立っていない時のアニメーションクリップを入れておきます。 次に、遷移を追加します。最初は「Entry」を右クリックして、「遷移を作成」オプションを選びます。 出てくる線を「OnGround」に繋げます。同様に「OnGround」から「InAir」へ、そして「InAir」から「OnGround」へ遷移を作成します。 「Idle」をサブステートマシンに移動したいので右クリックして、「コピー」しておきます。 「OnGround」をダブルクリックして中の遷移図を表示して、そこに「Idle」を貼り付けます。 張り付けた「Idle」アニメーションをデフォルトに設定したいので、右クリックして、「レイヤーデフォルトステートとして設定する」を選択します。 空いているところを右クリックして空のステートを追加します。 インスペクターで名称を「Run」にして、「Motion]を先ほどダウンロードした走りのアニメーションにします。 「Idle」と「Run」をこういう風に繋げておきます。 […]

UnityでOculusコントローラのセンサーデータを取得する

このチュートリアルでOculusコントローラの速度や加速度データを取得して、ボールを投げるシーンを作ってみましょう。 Input Systemを準備する 以前のチュートリアルでOculusコントローラ用にUnityのInput Systemの設定を説明しました。今回はこれをベースに「投げる」アクションを追加したいと思います。前のチュートリアルでは入力設定がこんな感じでした。 今回は、「Drop」アクションが要らないので右クリックして、削除を選んでも構いませんが、前のチュートリアルで作ったシーンが正しく動作しなくなります。もし「Drop」アクションを残したいなら、これから作るアクションと操作がかぶらないように修正してください。 以前のチュートリアルで説明した通り、「Throw」という新しいアクションを追加しましょう。 ボタンを離した時にボールを投げたいので、ここでPressインタラクションを追加して「Release Only」にしました。Oculusコントローラの右トリガーにバインドします。 入力設定を忘れずに保存してウィンドウを閉じます。 ボールのプレハブを作る 投げ方を変えて様々な種類のボールを投げたいので、球を2種類用意します。分かりやすくするためにそれぞれに違う色を付けます。 新しシーンにスフィアを追加して、スケールを変えて大きさを調整します。 SphereにRigidbodyコンポーネントを追加して、名称を「Ball」に変えて、用意したマテリアルを付けます。 ボールはゲームの弾と同様に永遠に持続せず、一定の時間が過ぎたら自動的に消えるようにしたいですね。「Lifetime」という新しいスクリプトを作っておきましょう。 このスクリプトはUnityのコルーチンを使っています。書き方が少し分かりにくいかも知れませんが、Unityで「〇〇秒待ってからこれをやれ」という指示の最も標準的な書き方です。 LifetimeスクリプトをBallに付けて、寿命を調整します。 これで球が完成したのでプロジェクトウィンドウにドラッグしてプレハブとして保存します。その後、シーンから削除します。 Ballプレハブを選択して、複製(Windows: Ctrl+D、macOS: command+D)します。複製されたプレハブの名称を変えて、もう一つのマテリアルを付けます。 シーンを準備する 新しいシーンを作成して、最初のOculusチュートリアルで作成したXRRigのプレハブを追加します。ボールを投げるターゲットとして適当にキューブなどを配置します。 ボールを投げた時にボールが出る位置を調整できるようにしたいので、XRRigを少し修正します。ここでは右手で投げますが、入力設定で指定した手を展開してその中に空のオブジェクトを追加します。名称を「Anchor」にします。 Anchorはボールが出る位置になって、ハンドル表示を「ローカル」に設定した時に表示される青の矢印を手の「前」方向になります。 Oculusコントローラのセンサーデータを取得する これはチュートリアルの最も肝心な作業ですね。しかし、Unityの公式ドキュメントを調べても分かりやすい説明がなかなか出てきません。試したところ、次で方法で何とかセンサーデータを取得できました。 他のところで使えるために、その機能を独立したコンポーネントで実装します。「VRController」という新しいスクリプトを作成して、XRRigのRightController又はLeftControllerに付けます。 UnityのXR機能を使うのでスクリプトの冒頭に「using UnityEngine.XR」を指定します。 追跡可能な「ノード」がいくつもあります。 LeftEye 左目 RightEye 右目 CenterEye 両目の中央点 Head 頭 LeftHand 左手 RightHand 右手 GameController ゲームコントローラ TrackingReference トラッキング用のリファレンス HardwareTracker トラッキング用のハードウェア装置 初代のOculus Riftは専用のコントローラがなくて、通常のXboxコントローラを使用していたので、ここにゲームコントローラがあります。また、初代Riftは外部の「カメラ」という装置を使ってユーザーの頭の位置を追跡していました。これが「トラッキング用のリファレンス」です。最後の「ハードウェア装置」は追加の未定のデバイスです(だと思います)。 使用するノードを切り替えたいので、スクリプトに以下のパラメータを追加します。 インスペクターでこれを「Right Hand」または「Left Hand」にします。 ノードから取得したデータを他のスクリプトで簡単に使えるようにしたいので、以下のパラメータをスクリプトに追加します。 角速度と角加速度はコントローラの向きの回転の速さと加速を表しています。 […]

Unityで三人称視点のキャラクターコントローラを作ってみよう(第3弾)

前回のチュートリアルでキャラクターのジャンプを実装しました。次に前後左右の移動を実装しましょう。 検証用にシーンを準備する キャラクターの動きを検証する時に、坂と段に対する反応が大事になるので、検証用にシーンにいくつかのオブジェクトを配置したいですね。シーンにキューブを2個追加して、高さが異なる段を作るように配置します。一つの段は「登れる段」にして、もう一つは「登れない段」にします。高さはこれから調整できますが、登れる段は高さを地面から0.1ユニットにして、登れない段は地面から0.2ユニット高くなるようにします。 同様に「登れる坂」と「登れない坂」を作ります。 登れる坂の傾斜はこれからスクリプトのパラメータになりますが、とりあえずの閾値として、45度にします。 まだカメラの追跡を実装していないので、ゲーム画面ですべてが見渡せるようにカメラを動かします。 移動スクリプトの基本 これからCharacterスクリプトを編集して、キャラクターが動くようにします。まず、以下のパラメータを追加します。 前のチュートリアルでプレーヤー入力を受け取るメソッドを作りました。 これを修正しますが、キャラクターを移動させるのはこのMoveメソッドの中ではありません。プレーヤーの入力が変わった時だけ呼び出されるからです。プレーヤーを動かすのはFixedUpdateの中で、毎フレーム動きを更新します。このため、Moveで行うのは入力をFixedUpdateで使えるようにプライベートプロパティで記憶するだけです。 FixedUpdateの方でキャラクターを動かします。この処理は必ず、地面検出の判定をお行ってからでなければなりません。地面に立って、且つジャンプを開始していない時だけキャラクターを移動させます。(ゲームによって空中移動がありますが、とりあえず空中移動なしにします。) ApplyMotionというメソッドで動きに関する実装をまとめます。キャラクターが地面に立って、ジャンプを開始していなければこのメソッドを実行します。 Rigidbodyに力を加えて入力の方向に加速します。加速度はインスペクターで調整できるようになっています。最後の「ForceMode.Acceleration」で最初の引数が絶対値の加速度を表していることを示します。加速度は入力のy値が3次元のz値になるので注意してください。 これで試してみるとキャラクターが動いているのが確認できます。しかしこの単純な実装は問題だらけです。まず、移動がカメラの視点を考慮していません。カメラの位置と角度が固定なら問題はないですが、多くの三人称視点ゲームではカメラが動いて、移動方向は世界の座標に対してではなく、カメラの視点に対して動く必要があります。 もう一つの問題は地面の傾斜を計算に入れていません。というか、地面の傾斜が現状のスクリプトでは分かりません。しかし、キャラクターが正しく移動するには、地面の傾斜に合わせて動く必要があります。 さらに現状では永遠に加速して速度が全く制限されていません。歩く速度、走る速度、二つの制限値を用意しましたが、これで加速を止める必要があります。これは一見簡単にできそうですが、意外と厄介ですよ。まず、この速度は絶対的な速度ではなく、地面に対する速度です。つまりここも地面の傾斜を計算にいれないといけません。これだけじゃないですよ!ゲームによってリフトなど地面となるオブジェクトが移動している場合もあります。そうすると、地面も動いていれば、速度制限は世界の座標に対してではなく、動くかも知れない地面に対して計算します。 これらの計算を助けてくれるのはゲームプログラムの親友の一人:ベクトル演算です。皆さん、高校の数学Bをちゃんと受けていますよね? 地面の傾斜を取得する 地面の傾斜を取得するのは簡単です。地面検出メソッドを少し修正すればUnityがすでに計算してくれた値を取得するだけで済みます。 元々あったこのメソッドを修正します。 まず、戻り値をboolからRaycastHitという型に変えます。これはUnityが衝突について様々な情報をまとめたクラスです。SphereCastでRaycastHitのオブジェクトを使って詳細を返すように指定しますが、こういう時にC#の「out」キーワードを使います。これは、引数として渡してオブジェクトがメソッドの実行によって変わる可能性があることをしめします。SphereCastが返すboolは使わずに代わりにRaycastHitを返します。 RaycastHitの情報を記憶したいのでCharacterクラスに以下のプライベートプロパティを追加します。 FixedUpdateでRaycastHitの情報をこれらのプロパティで記憶しておきます。 これで地面の傾斜だけでなく、地面と接触している点の座標と(あれば)地面に付いているRigibodyコンポーネントも取得できます。傾斜は法線(ノーマル)として表されています。ゲームも含めて、CGでは面の向きを法線で表します。法線は面から直立するように長さが1のベクトルです。 法線の重要な特徴は面の表面のすべての座標と法線ベクトルが必ず90度の角度を形成する事です。この特徴が様々な計算を楽にしてくれます。 カメラの視点に対する移動を計算する カメラ目線で移動を制御する時に、プレーヤーが「右」を押したらキャラクターが画面の右側に向かって移動して、プレーヤーが「上」を押せば、キャラクターがカメラの向いている方向に向かうのが普通です。「カメラの右」と「カメラの前」というベクトルが必要なので、インスペクターで使用するカメラを設定できるパラメータを追加します。 Unityでこれをちゃんと設定しておきましょう。 カメラの参照があれば、カメラに対する「前」と「右」の方向を取得する事ができます。以下の画像の青矢印と赤矢印です。 これで問題は解決しているように見えるかも知れませんが、そうでもないです。地面の傾斜に対して動きたいならカメラの前と右ベクトルを地面に射影しなければなりません。数学の出番です。 ベクトルの射影 ここでいうベクトルを面に射影するというのは、俗に説明すれば、面の上にベクトル(線)を引いて、法線の真上からその面を見れば射影するベクトルと引いた線がぴったりと重ねあうように見えます。 この例では青いベクトルがカメラの「前」なら、キャラクターが前進する実際の方向はピンクの矢印になります。そうでないと、キャラクターが地面に沿って歩かずに変に飛び上がったりしてしまいます。 ベクトルの射影は他に出番があるのでメソッドを用意しておきます。 上の画像でいえば、青い矢印と緑の矢印を渡して、ピンクの矢印を返してくれるメソッドです。 ベクトル演算を勉強していないとこの問題を三角関数を使うことを思いつくかも知れません。これは正気を失うのでやめておきましょう。代わりにベクトルの外積を使いましょう。 ベクトルの外積(ベクトル積、クロス積とも呼ばれています)は2つのベクトルからもう一つのベクトルを返す計算です。3つのベクトルの角度が90度になります。 では、上の画像の緑のベクトルが地面の法線で、緑の面が地面だとして、青のベクトルがカメラの向いている方向にします。そうすると、地面の法線の真上から見て地面上カメラのベクトルがどれほど伸びているかを知りたいです。 外積を計算して、地面上のベクトルを取得します。 このベクトルは法線ベクトルとカメラ方向ベクトルとも90度の角度を構成します。射影するには90度回転させてカメラ方向ベクトルと合わせる必要があります。この新しいベクトルと法線でもう一度外積を計算すれば求められます。 説明は長かったですが、全体の数式はこうなります。 Unityにベクトルの外積を計算してくれるメソッドが用意されているので、簡単にできます。 外積は非可換です。つまり、計算の順番によって結果が違います。上のメソッドで引数に渡している値の順番を変えないように書きましょう。 ProjectOnPlaneがあれば、やっとカメラの視線も地面の傾きにも対応する動きが実装できます。 これで試してみるとカメラを動かしたり、回転させたり、地面の傾斜を変えてみてもキャラクターが正しく動きます。 キャラクターの向きを変える キャラクターの細かな演出はアニメーションで行いますが、向きはスクリプトから変えます。最も簡単な方法はこうです。 キャラクターは常に直立しているので、向きを変える時に移動方向からy軸の成分をなくします。そして、動きが少ない時、静止している時に向きを変えないのもポイントです。この処理を加速を設定する前に挿入します。キャラクターを走らせてみると、確かに向きが変わりますが、不自然ですね。 向きを滑らかに変えたい場合、回転を徐々に変えてくれる補完を使います。Unityではオブジェクトの回転を四元数(Quaternion)として扱います。現在の角度と向かおうとしている角度の中間の角度に回転して、少しずつ正しい向きに近づけます。Unityなどでその補完をLerp(Liniear Interpolation)と言います。動きの滑らかさを調整するパラメータをクラスの冒頭に追加します。 そして、回転のコードを修正します。 回転がよくなります。 速度を制限する 速度を制限する時に2つの問題があります。 地面の向きによって速度を計算する必要がある […]

Unityで三人称視点のキャラクターコントローラを作ってみよう(第4弾)

以前のチュートリアルはこちらです: 第1弾:準備と入力の設定 第2弾:ジャンプと地面の検出 第3弾:移動 三人称視点のカメラ 一人称視点は、主人公目線でゲームの世界を見ています。1990年代は一人称視点のシューティングゲーム(FPS)の人気で、特に欧米では一時PCゲームの標準になったと言ってもいいです。今も一人称視点のゲームの他に、ゲームエンジンを利用した建築ビジュアライゼーションなどで採用されます。VRコンテンツもほとんどのコンテンツがほぼ必然的に一人称視点になっています。 二人称視点というのをあまり耳にする機会がありませんが、主人公を相手の視点で見ることです。デジタルゲームでは、数少ない実験的なタイトル以外にほとんど使われることがないようです。しかし、小説などで、「あなたは…」という口調で書かれている話は二人称視点になります。私が小学校のころ愛読していた「きみはどうする?」シリーズのゲームブックが典型的な二人称視点です。 このチュートリアルで作っている三人称視点のカメラは、中立的な位置から主人公やゲームの世界を写します。「私は」でも、「あなたは」でもなく、「彼女は、彼は」で始まるストーリーです。今は3Dゲームで最もよく使われるシステムです。因みに、現在の三人称視点ゲームの原型となっているのは任天堂の「スーパーマリオ64」ですが、ストーリーでは、ジュゲムブラザーズ目線でマリオを見ているので、厳密にいえば二人称視点のゲームになるかも知れません。 三人称視点カメラの種類 三人称視点と言っても、一人称視点と違って見せ方がいろいろあります。 完全固定カメラ このカメラは位置も回転も固定で世界を写しています。もちろん、技術的に最も簡単で、今までのチュートリアルではカメラになんの工夫もしていないので、完全固定カメラになっています。完全固定カメラは「スペースインベーダー」や「パックマン」など、初期の2Dゲームで採用されていましたが、現在はカメラを全く動かさないゲームがほとんどありません。 固定角度カメラ このカメラは、プレーヤーキャラクターなどを追跡しながら世界を常に同じ角度から移しています。 自動操縦カメラ このカメラはプレーヤーが直接操作するのではなく、ゲームが最適な角度を計算して自動的にカメラを動かして回転させます。この類のカメラはレーシングゲームでよく使われます。また、カットシーンもカメラの操作をプレーヤーにさせずに、予め決められた動きをします。 自由回転カメラ カメラはプレーヤーキャラクターを追跡しながら、プレーヤーがキャラクターを中心にカメラを回転させます。地面に潜らないようにカメラの回転が制限されることが多いです。 半自由回転カメラ 基本的にプレーヤーはカメラを操作する事ができますが、キャラクターの後ろに戻ったり、敵に向かったりして同時に自動化された動きもあります。 Nier:Automata 「Nier:Automata」は2017年にリリースされたゲームです。基本的にオープンワールドのゲームで、典型的な三人称視点の自由回転カメラを採用していますが、最初のステージではカメラの制御方法が度々変わります。このゲームはある意味で「ゲームについてのゲーム」で、このイントロでカメラの操作を変えるだけで三人称視点の戦闘ゲームから、横スクロールのアスレチック系のゲームに、さらに弾幕ゲームに変わります。カメラ操作の可能性を最大限生かしたゲームとして非常に参考になります。 Cinemachine 三人称視点のカメラの実装がかなり複雑になります。幸いにUnityにCinemachineという協力な助っ人がいます。このパッケージを使用すれば、カメラの主な機能が用意されて、プログラムをほとんど書かずに済みます。 一人称視点のゲームはプレーヤーキャラクター目線で世界を見ているのでカメラの動きはプレーヤーの動きになるので比較的単純です。二人称視点とは、プレーヤーキャラクター以外のキャラクター目線で世界を見ることです。ゲームでは相当珍しいです。三人称視点のカメラはゲームのキャラクターから離れた位置から世界を見ています。 Cinemachineは基本的に通常のUnityのカメラの設定を記憶したバーチャルカメラを通して使います。異なる角度、位置だけでなく、異なる操作方法も別々のバーチャルカメラで設定します。一つのシーンに複数のバーチャルカメラが存在してもいいですが、画面を写すUnityのカメラは基本的に1つだけです。 Cinemachineの準備 パッケージマネージャからCinemachineをプロジェクトに追加します。 このチュートリアルはバーチャルカメラを一つだけ使います。Cinemachineをインストールして現れたメニューから「Create Virtual Camera」を選択します。 プレーヤーキャラクターの修正 今まで使っていたキャラクターの構造を少し変える必要があります。Cinemachineで自由回転のカメラを実装するために、カメラのターゲットとなるオブジェクトを追加します。このターゲットは単純にカメラが見る点です。通常キャラクターの肩あたりに付けますが、位置を自由に調整できます。大事なのはこのターゲットとメッシュを分離する事ですが、移動したときにターゲットがメッシュと一緒に回転してしまうとCinemachineの動作がおかしくなります。 プレーヤーの修正は最初のチュートリアルで作成した「Character」プレハブを編集して行います。 Characterの中に「AimTarget」という空のオブジェクトを追加します。カメラが狙う位置になるので、次は型の辺りに移動します。カメラが狙う位置を左右動かしたい場合、Cinemachineでは他の方法があるので、AimTargetは基本的にキャラクターの背骨に沿って上下に動かします。 次はこのAimTargetとメッシュの回転を切り離すために、AimTarget以外、Characterの中にあるすべてのゲームオブジェクトを「Avatar」という新しいゲームオブジェクトの中に入れます。 スクリプトの修正も少し必要です。Characterスクリプトを開いて、「avatar」という新しいパラメータを追加します。 プレハブを編集しているまま、インスペクターでavatarを指定します。 最後にキャラクターの向きを変えていたところはAvatarだけを回転させるように修正します。 この部分: をこれに変えます。 プレーヤーの追跡 プレハブの編集が終わったので、シーンに戻ります。Cinemachineのバーチャルカメラを作った時に「CM vcam 1」というオブジェクトがヒエラルキーに追加されました。これがバーチャルカメラです。 追加される「CM vcam1」というオブジェクトを選択して、インスペクターでプレーヤーキャラクターを追跡するように修正します。 「Follow」設定は追跡するオブジェクトで、Playerではなく、その中にある「AimTarget」を選びます。 バーチャルカメラの追跡方法(Body)を「Transposer」から「3rd Person Follow」に変えます。 Aim設定を「Composer」から「Do Nothing」に変えます。 この時点で動作を確認するとキャラクターがこういう風に正しく追跡されることが確認できます。 もし動かなければ、CharacterスクリプトのカメラとAvatarが正しく設定されていることを確認してください。 […]

Unityで三人称視点のキャラクターコントローラを作ってみよう(第2弾)

前のチュートリアルで三人称視点ゲームのキャラクターの準備を行いました。ここではそのキャラクターに追加した「Character」スクリプトの編集をして簡単に操作できるようにします。 スクリプトの準備 Unityのスクリプトを書くときによくある工程ですが、必要なコンポーネントの参照を取得します。 これでは問題はないですが、念のためにこの3つコンポーネントを「必須」にしたいです。クラス宣言の上に記述を追加します。 アクションを受け取る UnityのInput Systemではプレーヤーのアクションを受け取る方法がいろいろあります。Player Inputコンポーネントの「Behavior」でその方法を変えますが、ここではデフォルトの「Send Messages」にします。 「Send Messages」にすると、入力設定アセットで登録されているアクションが起こると、Player Inputが付いているオブジェクトのすべてのスクリプトが特定のメソッドを実装することによってそのアクションに反応することができます。 ここにそのメソッド名が表示されます。すべて、「On」+アクション名になっています。キャラクターコントローラで実装が必要なのは「OnMove」と「OnJump」です。(「OnFire」もゲームによって必要ですが、このチュートリアルでは実装しません。) これらに反応する前に、スクリプトにInput Systemの機能を読み込む必要があります。スクリプトの冒頭にusing宣言を追加します。 Characterクラスに二つの新しいメソッドを追加します。引数の型は「InputValue」になります。 このスクリプトはAIキャラクターも使えるようにしたいですが、独自のInputValueを生成することができないので、InputValueから必要な情報だけを取り出して、AIからも呼び出せるメソッドに渡します。 ジャンプの実装 移動よりもジャンプの実装が簡単なので、先に行いましょう。先ほど作った「Jump」メソッドはプレーヤーまたはAIがボタンを押したか離したか、state引数で分かります。ジャンプする時は、Rigidbodyのy速度を一瞬で上に上げます。このジャンプの勢いを調整するためにパラメータを追加します。 Jumpメソッドの実装はこうなります。 動作を確認してみるとキャラクターが見事にジャンプしてくれます。 が、ダブルジャンプどころか、空中でも何回でもジャンプできてしまいます。まあ、こういうゲームはありかも知れませんが、普通なら地面に立っていなければジャンプはできません。 地面のチェック 2Dでも3Dでもキャラクターを制御するスクリプトを書く時は、キャラクターが地面に立っているかどうかのチェックが極めて重要です。ゲームの種類によって判定方法も若干違います。例えば、1ピクセル単位の細かな操作を要するアスレチック系のプラットフォーマーゲームなら非常に慎重に判定しなければなりません。しかし、足元が見えない一人称視点ゲームならもう少し簡単に処理してもいいでしょう。 まあ、方法は基本的に同じです。キャラクターの足元からレイキャストを行って、一定の短い距離以内なら何かに衝突すれば地面に立っていると判定します。「レイキャスト」は、ある点からレーザー光線のようにゲーム空間で直線を引いて、どこかのコライダに当たるかどうかを確認する計算です。 この判定は毎フレーム行う必要がありますが、Updateを使いません。衝突判定は物理演算の一種で、Unityでは物理演算をすべて「FixedUpdate」というメソッドで行わなければなりません。こういう風に準備します。 CheckForGroundメソッドで地面をレイキャストで探しますが、足元の位置を計算する必要があります。ここでは、カプセルコライダーの下の位置を足元に定義します。正しい計算方法はこうです。 「capsuleBottom」はオブジェクトに対して、相対的な足元の位置です。これを世界の絶対的な位置の「feetPosition」に変換します。この位置から地面を探しますが、閾値をパラメータとして追加しましょう。 レイキャストはこう行います。 しかし、これでうまくいきません。誤差があるので、レイキャストは足元よりも少し上の位置から始める必要があります。Unityではレイキャストの開始点がコライダの中に入っているならそのコライダが無視されます。これで、自分自身を地面として間違えることはありません。 地面に立っているかどうかが分かれば、Jumpを開始する条件を工夫する事が出来ます。 試してみると、ダブルジャンプができなくなります。キャラクターが地面に立っている時だけジャンプを開始する事ができます。 次の工夫は、地面として認識しないコライダの設定を可能にすることです。Unityのレイヤーを使えば簡単にできます。まず、LayerMaskパラメータを追加します。 ここの「~0」は「全てのレイヤー」を意味します。 インスペクタではこうなります。 チェックが入っているレイヤーは地面として判定されます。オブジェクトのレイヤーの設定はインスペクタの上部で行います。必要に応じて新しいレイヤーを追加する事もできます。 LayerMaskを使うようにレイキャストを少し修正します。 多くのゲームはこの単純なレイキャストで地面検出を行っても大丈夫ですが、アスレチック系のゲームなどでこういうシチュエーションが問題になる可能性もあります。 こういう問題が起こりそうなレベルデザインでは、別の方法で地面を検出しなければなりません。直線のレイキャストは計算が比較的軽いのでゲーム開発でよく使いますが、直線以外の形状で衝突判定を行うことができます。ここで便利なのは球体を使って判定するスフィアキャストです。レイキャストと同様に足元より少し高い位置から球体を下へ移動したら何かにぶつかるかという計算です。レイキャスト同様に、最初から重なるコライダが無視され、自分自身を地面として誤認しません。 地面判定のコードがこういう風に変わります。 ジャンプの高さを調整する ジャンプの高さが固定の3Dゲームが多いですが、細かなジャンプの操作が必要な場合、2Dゲームでよく採用される仕組みを実装すると便利です。これは元々「スーカーマリオブラザーズ」で登場した賢いアプローチです。プレーヤーがジャンプボタンを押し続ける間、重力を軽減します。現実世界ではありえない現象ですが、これでプレーヤーがボタンを強く押した時に高くジャンプするという感覚になります。実際はボタンを押す強さを感知していませんが、強く押すと必然的に押す時間が長くなります。 この機能を実装するために、地面に立っているかどうかだけでなく、ジャンプしているかどうかというプライベートのプロパティが必要になります。この機能がいらない場合も、ジャンプしているかどうかの判定がアニメーションの演出に必要ですので、追加してください。 ジャンプをしているかどうかの判定はこうです: ジャンプを開始する時にtrueに設定する プレーヤーがジャンプボタンを離した時にfalseにする キャラクターが下へ移動したら(落下している時)falseにする まず、Jumpメソッドがこうなります。 FixedUpdateは: ジャンプしている間の重力の変更を調整できるパラメータを追加します。 ここでは、ジャンプボタンを押し続けると重力が0.6倍になります。 FixedUpdateでは、ジャンプしている場合、重力と反対側の力を加えます。Rigidbodyの重量を忘れずに計算に入れておきましょう。 これで一度動作を確認して、ジャンプの高さが調整できるかどうかを確かめます。もし、ゲームでジャンプの高さ調節が不要ならjumpGravityScaleを1にします。 次のチュートリアルでキャラクターを動かします。

Unityで三人称視点のキャラクターコントローラを作ってみよう(第1弾)

Unityのアセットストアを検索すれば、三人称視点のゲームでキャラクターを動かすアセットがたくさん出てきます。これらを使うと確かに便利ですが、自分で実装するとその仕組みを理解することもできて、細かくカスタマイズすることができます。 必要なアセットを入手 このチュートリアルはプログラムに重点を置きたいので、3Dモデルとアニメーションは有り物を使います。Mixamoを利用すればゲームで使える多くのアニメーションシーケンスが手に入るのでこのチュートリアルでも使います。 キャラクターの演出はとりあえず最低限の静止(アイドリング)アニメーションにします。Mixamoで「Idle」と検索してよさそうなアニメーションを探します。 アセットをダウンロードする時にフォーマットを「FBX for Unity」にして、スキン設定を「With Skin」にします。これでアニメーションだけでなくモデルもダウンロードに含まれます。 ファイルを保存しておいて、作業がUnityに移ります。(Mixamoは今後も使います。) Unityの準備をする Unityでこれから作るアセットのために新しいフォルダーを作ります。(整理整頓!)ここでは名称を「ThirdPersonController」にしておきます。 MixamoからダウンロードしたFBXファイルをここに追加します。 このモデルは人間型ですので、読み込み設定を調整しておく必要があります。プロジェクトウィンドウで追加したアセットを選択して、インスペクタの「リグ」タブでモデルの「アニメーションタイプ」を「ヒューマノイド」に変えます。 リグの種類をヒューマノイドにすると、関節の限界など細かな調整ができますが、ここではでデフォルトのままにしておきます。 キャラクターを立たせるために平面を追加します。分かりやすく座標を(0,0,0)にして、スケールで大きくします。 MixamoからダウンロードしたFBXをシーンに追加します。 アニメーターコントローラ このままではポーズが正しいですがアニメーションが再生されません。これからの作業で非常に重要な部品となるアニメーターコントローラを用意しなければなりません。プロジェクトウィンドウで右クリックして、作成します。 名称は「ThirdPersonAnimator」にしておきます。このアセットが様々なアニメーションクリップの複雑な切り替えを行ってくれます。このアセットをダブルクリックするとアニメーターウィンドウが表示されます。ここにアニメーションクリップを追加していきます。ダウンロードしたFBXに「Idle」というクリップが含まれています。(アイコンでアニメーションクリップが分かります。)これをアニメーターウィンドウにドラッグします。 そうすると、このようにオレンジ色で表示されて、「Entry」と繋げられます。これはデフォルトのアニメーションパターンになっていることを意味します。 次はフィールドに追加キャラクターがこのアニメーターコントローラを使うようにします。ヒエラルキー画面でキャラクターを選択して、インスペクタでAnimatorコンポーネントのコントローラを設定します。 ゲームをプレーしてみるとアイドリングアニメーションが再生されることが確認できます。(キャラクターをカメラの近くに置かないと!) 物理シミュレーション 3Dゲームのキャラクターはおそらく世界の物理シミュレーションの影響を受けるでしょう。PlayerオブジェクトにRigidbodyとカプセルコライダーを追加しましょう。 カプセルコライダーは形状をキャラクターに合わせます。操作が可能になったらテストプレーして大きさなどを調整するといいですが、今はこの程度でいいです。 このままプレーしてみるとキャラクターが風船のように飛んでいきます。原因はアニメーターの「ルートモーションを適用」設定です。これを外して、アニメーションが手や足を動かして、キャラクター全体を動かさないようにします。 これで風船じゃなくなりますが、恰好悪く転倒してしまいます。Rigidbodyで回転を制御しないようにしておきましょう。 コントローラスクリプト これからの作業のほとんどがスクリプトで行われます。スクリプトの書き方についてこのチュートリアルの第2弾以降紹介しますが、アセットだけ用意しておきます。「Character」というC#スクリプトを作成して、Playerオブジェクトに付与します。 プレハブ化 作るキャラクターをプレハブとして保存して、どこでも簡単に追加できるようにします。ここで設定がすべて終わる前に一旦プレハブを作ります。なぜなら、プレーヤーが操作するキャラクター以外に同じスクリプトと設定をAIが操作するキャラクターに使用したいからです。ここで保存するプレハブはこの2つのキャラクター(プレーヤーとAI)のベースとなります。 キャラクターオブジェクトの名称を「Character」に変えておきます。 この「Character」をプロジェクトウィンドウにドラッグして原型プレハブとして保存します。 また名称を「Character」から「Player」に変更します。そして、またPlayerをプレハブとして保存しますが、今回はプレハブバリアントにします。バリアントにするとCharacterを編集したらその変更がPlayerにも適用されます。 プレーヤー入力 プレーヤー入力システムは新旧、Unityに全く違う方法があります。ここでは新しいInput Systemを使用します。パッケージマネージャで追加する必要があります。 インストールするとこのような警告が表示されます。必ず「Yes」を選択してください。 Unityが再起動しますが、正常な動作です。 Playerオブジェクトに「Player Input」コンポーネントを追加します。 Player Inputは入力設定を指定するアセットが必要です。まだ作っていないので用意しなければなりません。ゼロから作ることができますが、Unityに標準的なアクションを準備してもらうことも可能です。Player Inputの「Create Actions…」を押して、そのアセットを作成します。 ファイルの保存先を「ThirdPersonController」フォルダー内にしておきましょう。ファイル名は自由ですが、ここでは「ThirdPerson」にしました。 アセットは作成しましたが、Player Inputにこのアセットを使用するように設定しなければなりません。 これからは、このようにPlayerに新しいコンポーネントを追加したり、コンポーネントの設定を変えたりするときにその変更をプレハブに適用しなければなりません。この手順をこれから省きますが、忘れずに行ってください。少し分かりにくいですが、インスペクタ上部の「オーバーライド」をクリックして、「すべてを適用する」を選択してください。 Unityはキャラクターの移動と発射アクションを用意してくれましたが、ジャンプアクションがありません。追加しておきましょう。先ほど作成した入力設定アセットをダブルクリックして、編集画面を表示します。 「Player」のAction Mapに「Jump」というアクションを追加します。ここは綴りと大文字・小文字を間違えずに設定してください。 デフォルトでJumpがボタン入力として追加されます。合ってはいますが、何もしないとボタンが押された時だけ通知がスクリプトに送信されます。これから作るプログラムではボタンを離した時も反応したいので、Interactionsの「+」ボタンを押して「Press」を選択します。 Trigger Behaviorを「Press Only」から「Press And Release」に変えます。 […]

UnityでOculus Questの開発を始める

以前の投稿でOculus Rift S向けのコンテンツ制作の準備を説明しました。Oculus Rift Sは有線端末で、PCに依存しますが、Oculus Questは単体で動きます。PCも不要で、邪魔なコードもありませんが、処理をすべて端末で行っているため、表示できるコンテンツに制限があります。とはいえ、十分に楽しめる品質のVR体験が作れます。 Unityの準備 Unityの準備についてOculus Rift Sのチュートリアルで説明しましたが、Oculus Questを利用したい場合、重要な注意点があります。Oculus QuestはAndroid端末ですので、基本的にスマートフォンと同様に開発を行います。そのために、Unityをインストールする時にAndroid開発に必要なモジュールを必ずインストールしなければなりません。 もし「Android Build Support」モジュールを選択せずにUnityをインストールしていれば、Unity Hubで簡単に追加することができます。 Android関連のモジュールをインストールする時に利用規約に同意しなければなりません。 これでUnityの準備が終わります。 Oculus Questの準備 Oculus QuestはPCを使わないので、設定をスマートフォンの「コンパニオンアプリ」で行います。 iPhone版はこちらでAndroid版はここからダウンロードしてください。 Oculusアプリを利用するためOculusアカウントまたはFacebookアカウントが必要ですが、新規のOculusアカウントを作成することができなくなりました。 Oculusアプリをスマートフォンで立ち上げて、ログインが終わるとデバイスタブで新しいデバイスを追加します。 追加したい端末を選択すれば、スマートフォンで非常にわかりやすい説明が流れるのでここでは省きます。 OculusアプリとOculus Quest本体の準備が終わったら、Oculusアプリで重要な設定を追加で行います。デバイス一覧からQuestを選択して、「開発者モード」設定をタップします。 開発者モードを有効にして、Unityで作ったアプリを動かせるようにします。 これでOculusアプリでの設定が終わりますが、USB接続で開発PCとつなげられるようにしなければなりません。この設定では開発PCにもOculusアプリのインストールが必要です。Oculus Rift S開発と同様に公式サイトからダウンロードしてインストールしておいてください。 開発者モードを有効にして、PCにOculusソフトウェアをインストールしてからOculus Questの付属のUSBケーブル(兼充電ケーブル)でOculus Questと開発PCを接続します。(ケーブルはUSB Cなので、USB C対応のポートがあるのを確認しましょう。) Oculus Questを装着するとこのような画面がVR空間で表示されます。 Oculus Linkを有効にするかと聞かれます。Oculus Linkは通常単独で動くOculus QuestをOculus Rift SのようにPCに接続して使うモードです。Unityで開発する時に有効にしましょう。 PC側ではOculusアプリが自動的に起動するはずです。 画面に表示される指示に従ってすすみます。 端子がUSB-Cでもポートの速度が遅すぎる場合もあります。他のUSB-Cポートがあれば接続しなおしてみてもいいです。ここで設定が完了するとUnityに移りましょう。 UnityでOculus Quest用のプロジェクトを準備する Oculus Rift Sとまた同様にUnity Hubで新しいプロジェクトを作成して、VRテンプレートを選択します。 VRテンプレートを初めて立ち上げる時に英語で警告が表示されます。 […]

Unityの新しいInput SystemでOculusを使用する

以前のチュートリアルでUnityで作成したコンテンツをOculus Riftで表示できるところまで進みました。Oculus RiftでもOculus Questでも便利なOculusコントローラーを使います。Unityの従来の入力システムが、なんといえばいいでしょうか、まあ、あまりよくないです。そのために全く新しいInput Systemが導入されました。パワフルで柔軟性がありますが、その分、複雑になりました。ドキュメントもまだ不十分で使いにくい印象を与えてしまいますが、基本を理解すれば、むしろ従来のシステムより非常に使い勝手がいいです。 Input Systemの準備 新しいInput Systemは標準でプロジェクトに追加されないので、パッケージマネージャでインストールする必要があります。 最初はプロジェクトに追加されているパッケージしか表示されないので、「Unityレジストリ」を選択して、インストール可能な標準パッケージを表示します。 「Input System」をインストールします。 そこで、重要なお知らせが表示されます。旧入力システムから新システムに移行するためにプロジェクトの設定を変える必要がありますとの事です。必ず、絶対に「Yes」を押してください。 そうするとなんとUnityが再起動します。クラッシュではなく正常の動作です。 アクションの登録 新しいInput Systemは同じゲームがさまざまなデバイスで、さまざまなコントローラで遊べるように設計されています。設定を簡単に切り替えるためにアセットとして保存されます。シンプルなコンテンツなら一つのインプット設定ファイルで十分です。 アセットメニューから新規の「Input Actions」ファイルを作成します。(Input Systemパッケージがインストールされていないと表示されません。) 「DefaultActions」など、分かりやすい名称を付けます。 このアセットをダブルクリックして編集します。 プレーヤーが引き起こすイベントをアクション(Action)といいます。アクションは基本的に自分で必要に応じて追加して定義します。Move(移動)、Jump(ジャンプ)、Fire(撃つ)などなど。複雑なゲームので、操作方法を切り替えたい場合、アクションを複数のアクションマップ(Action Map)でまとめる事ができます。例えば、戦闘の時のアクション、会話の時のアクション、メニューの時のアクションなどを別々のアクションマップで設定することができます。 今回は単純なゲームを作るので一つだけのアクションマップを使います。新しいアクションマップを追加して、「Oculus Actions」という名称を付けます。(アクションマップの名称は自由です。) 次は新しいアクションを追加します。今回は動作確認のためにキューブを落下させたいですので、「Drop」アクションを追加します。 デフォルトのアクションの「New action」の名称を変えるだけでいいです。 アクションをもっと追加したい時は「+」ボタンを押して追加していきます。 次の重要な概念はバインドです。分かりにくいプログラミング用語ですが、単純にこのアクションを引き起こす時にプレーヤーはどうすればいいのかという設定です。一つのアクションに複数のバインドを登録する事ができます。例えば、「弾を撃つ」というアクションはキーボードのCtrlキー、エンターキー、マウスの左ボタン、ゲームコントローラーのトリガーボタンなど、いくつもの操作方法を登録することができます。今回はプレーヤーが右手のOculusコントローラーのトリガーボタンを押したらキューブが落下するという風に登録します。 「Drop」アクションの表示を展開して、「<No Binding>」を選択します。 「Binding」の「Path」でプレーヤーの操作を選びます。「XR Controller」でAR・VRコントローラーを選択します。 「Oculus Touch Controller」を選ぶと… 左手(LeftHand)と右手(RightHand)のどちらかを選びます。 ここにいくつもの操作がリストアップされます。「Button」で終わる操作はボタンが押された時を意味します。「Touched」で終わる操作はプレーヤーが該当の入力を触れるだけで反応します。スティックだけ押す操作が「Clicked」になっています。コントローラーの入力デバイスの名称とそのバインドはこちらです。 「triggerPressed」を選択しますが、他の操作でも登録してもいいです。 入力設定の編集が終わったら忘れずに設定を保存します。 保存すれば設定画面を閉じます。 アクションを受け取る 登録したアクションに反応してほしいゲームオブジェクトに「PlayerInput」というコンポーネントを追加します。今回のチュートリアルではCubeになります。 PlayerInputコンポーネントに使用する設定を指定しないと動作しません。Actionsパラメータで先ほど作成した設定アセットを選択します。 初期値になっているので変更する必要はありませんが、Behaviorパラメータを必ず「Send Messages」をしておきましょう。アクションが起きた時に様々な形で通知を受け取る事ができますが、「メッセージを送信」という方法から説明します。この方法ではC#のスクリプトで通知を受け取ります。 プロジェクトでスクリプト用のフォルダーを用意します。(整理整頓!) この中に「ObjectDrop」というスクリプトを作成します。 この「ObjectDrop」をCubeに追加します。まだ書いていませんが、ObjectDropスクリプトはPlayerInputと連動するので必ずセットで使います。 スクリプトをダブルクリックしてコード編集ソフトウェアで必要なスクリプトを書きます。 void OnDrop()から始まる部分だけを追加します。このOnDropというのは「On」(起きた時に)と自分で設定したアクション名で構成されています。波括弧の中にアクションが起きた時に実行するコードを書きます。ここは自分自身のゲームオブジェクト(gameObject)に「Rigidbody」という種類のコンポーネントを追加する指示をします。Rigidbodyは物理演算を影響を受けるようにするので、追加することで重力で落下します。 Unityに戻って、再生ボタンを押すと右手のトリガーボタンを押したらキューブが落下します。 […]