3rd term 6th week - dsuz/unity-game-dev1-3d-2019 GitHub Wiki

今回のテーマ

  1. 操作系 - カメラに合わせた方向に移動する
  2. アニメーションイベント - 攻撃の当たり判定を発生させる
  3. Particle System
  4. 武器を持たせる

以上を使って以下を作る。

先週の授業終了状態にするには

先週休んだり、プロジェクトが失われてしまった人は以下の要領で先週の授業終了時の状態のプロジェクトを準備してください。

  1. 新たに Unity のプロジェクトを作る
    1. テンプレートは 3D を選ぶ
  2. Asset Store から Basic Motions Pack をプロジェクトにインポートする
  3. SDユニティちゃん 3DモデルデータVer 1.01 をダウンロードし、インポートする
    • このデータをインポートすると以下のコンパイル エラーが出るので、該当行をコメントアウトもしくは削除する
    • Assets\UnityChan\Scripts\AutoBlinkforSD.cs(8,23): error CS0234: The type or namespace name 'Policy' does not exist in the namespace 'System.Security' (are you missing an assembly reference?)
  4. 3rd_week_completed.unitypackage をダウンロードし、インポートする
  5. 4th_week_asset.unitypackage をダウンロードし、インポートする
  6. 5th_week_assets.unitypackage をダウンロードし、インポートする

今週の準備

  1. 6th_week_assets.unitypackage をダウンロードし、先週のプロジェクトにインポートする
  2. ControlScheme シーンを開いて実行し、WASD, Space で操作できることを確認する

キャラクター操作

実践的なキャラクター移動の実装について学ぶ。まず、以下の手順で挙動が変わることを確認する。

  1. WASD で Capsule を操作する
  2. PlayerController コンポーネントの設定 Control Type を Turn > Move に切り替えて、WASD による挙動が変わることを確認する
  3. Control Type を Move にしたままで Main Camera を様々な位置に動かし、W を押すと常に画面の奥に移動することを確認する

前回までのキャラクター操作処理では、空間の絶対座標系に対してキャラクターを動かしていた。しかし、そのような処理ではカメラの位置が変わった時に移動する方向が一定せず、キャラクターを操作しづらい。そのため、今回は「カメラを基準として」上下の入力があった時に奥・手前方向、左右の入力があった時に手前方向に移動するように座標系を変換している。これは Main Camera の transform に対して Transform.TransformDirection() 関数を実行することでできる。今回は PlayerController.cs:58 でそれを行っている。

昔のゲームではカメラの位置が変わることに対応するために左右の入力でキャラクターを回転させていたが、現在のゲームではカメラを基準にした入力方向にキャラクターを移動させるものがほとんどである。

試してみよう

ControlScheme シーンのカメラを Cinemachine の Virtual Camera にしてみましょう。Free Look Camera がよいでしょう。こうすることで、カメラを基準にした移動のメリットがよくわかります。

Free Look Camera の使い方については以下を参考にするとよいでしょう。

アニメーション イベント

アニメーション イベントは、アニメーション クリップの途中で関数を呼ぶ機能である。これを使うことによって、アニメーション中の任意のタイミングで処理を実行することができる。今回は、「攻撃モーションの途中で攻撃の当たり判定を発生させ、攻撃モーションの再生が終わる前に攻撃の当たり判定を無効にする」ことを例にとってアニメーション イベントについて学ぶ。

  1. シーン AnimationEvent を開く
  2. 左クリックまたは左 Ctrl でパンチをすることを確認する
  3. パンチを青いブロックに当てるとブロックが破壊されることを確認する
    • この「パンチによる当たり判定」をどのように発生させているかを学ぶ
  4. Hierarchy から Player オブジェクト(このオブジェクトは元々は Capsule で、先週と同じやり方でモデルを関連付けている)の子オブジェクトである SD_unitychan_humanoid を選び、Animation ウィンドウから Punch のクリップを選ぶ
  5. 以下のようにしてプレビューを再生したり、Animation Event の設定内容を Inspector で確認する
  6. Animation Event を選択すると、以下のように Inspector から呼び出し可能な関数を選択することができる
    • この時に選択可能な関数は「Animator コンポーネントと同じ GameObject に追加されたスクリプトコンポーネントの関数」のみであることに注意すること
    • ここでは関数名でしか選ぶことができないことに注意すること
      • 該当の GameObject に複数のスクリプトコンポーネントが追加されていて、それらが同じ名前の関数を実装している場合、区別することができないため誤動作の可能性があることに注意すること
      • このことは Dummy というコンポーネントをモデルの GameObject に追加し、Animation Event の関数を選ぼうとするとわかるでしょう
  7. Animation ウィンドウのコマ送り機能やジャンプ機能を使って「ちょうどよいところ」で BeginAttack()/EndAttack() が呼ばれているか確認し、調整したい場合は Animation Event をドラッグして調整する

注意事項

Punch の他に使われている Idle/Run/Jump の Animation は Read-Only となっており、Animation Event/Keyframe の追加、編集に使う UI がグレーアウトされており、操作することができない。

これは Animation Clip が FBX ファイルの中に統合されているためで、Unity では FBX に含まれたアニメーションを編集・保存することができないためである。このような場合は Animation Clip のみを Duplicate して単体の .anim ファイルに分離することで、編集可能になる。

参照

上記の注意事項は FAQ であり、以下のページ等で説明されている。

BeginAttack/EndAttack でやっていること

これらの関数は Animator コンポーネントと同じ GameObject に追加されている AttackController コンポーネントに実装されていて、コンポーネントに指定されたコライダーを有効/無効に切り替えている。以下の手順で当たり判定の範囲を調整する方法を学ぶ。

  1. Attack Controller コンポーネントの Attack Range にアサインされている AttackRange オブジェクトを特定する

  2. この AttackRange オブジェクトに追加されているコライダー(トリガー)の範囲に攻撃判定を発生させている

  3. AttackRange オブジェクトを選択した状態でシーンを再生し、攻撃をしてみると、当たり判定の有効/無効が切り替わっていることがわかる

    • 見づらい場合は AttackRange オブジェクトの Mesh Renderer コンポーネントを有効にしたり、位置や大きさを見やすいように調整するとよい
    • 以下のように当たり判定の発生タイミングを調べられる

参考

Particle System

BreakableBlock に攻撃を加えた時に破片が散らばるエフェクトは Particle System を使っている。これの扱い方について学ぶ。まずは以下の手順でプレビューを再生する。

  1. BreakableBlock の GameObject をダブルクリックして Scene ウィンドウの中央に表示する
  2. Particle System コンポーネントが追加された GameObject を選択していると、Scene ウィンドウに Particle Effect のプレビュー操作パネルが表示される
  3. Particle System コンポーネントを確認する
  4. 設定項目が多いため細かい説明は後(次回以降)にする

BreakableBlockController コンポーネント

BreakableBlockController では、以下のことを行っている。

  • 攻撃判定のトリガーに接触した時に以下のことを行う
    1. ブロックのコライダーを無効にする
    2. 描画を無効にして、画面からブロックを消す
    3. Particle System を再生する
    4. Particle System の再生が終わったらオブジェクトを破棄する

以前は「エフェクトとなるオブジェクトを生成して自分自身を破棄する」という実装をしたが、このようなやり方もあることを知っておくとよい。

参考

Particle System のパラメータは大量にあり、Particle を重ねたりなど練習が必要になる。以下の書籍がわかりやすい。

Web 上でなら、以前の授業で使ったものがあるため参考にするとよい。

武器を持たせる

オブジェクトを子オブジェクトとして配置すると、親オブジェクトの Transform の設定を継承することを利用して、モデルに武器を持たせたりすることができる。

  1. 3D Object > Cylinder のオブジェクトを新しく作成する
    • まずは親子関係を持たせずに設定する
  2. Cylinder オブジェクトのコライダーを無効にする
  3. Cylinder オブジェクトの Transform コンポーネントを以下のように設定する
    • Scale X: 0.02, Y: 0.4, Z: 0.02
    • これでオブジェクトが棒状になる
  4. Cylinder オブジェクトをモデルの子オブジェクトにある Character1_RightHandMiddle1 オブジェクトの子オブジェクトとして設定し、Transform を以下の値に設定する
  5. シーンを実行し、攻撃すると「武器を振る」動きになることを確認する

モデルの子オブジェクトには Character_Reference というオブジェクトがあるが、これはキャラクターの体の部位にいろいろなものを取り付けたりするための目印(参照)として使うことができる。

参考

課題

モデル及び攻撃アニメーションを差し替えよ。モデル・アニメーションは以下を推奨する。自分の好きなものでもよいが、ダウンロードサイズに注意すること。攻撃アニメーションだけでなく、走る・ジャンプ・アイドルのアニメーションを差し替えてもよい。

ヒント

  1. AnimationEvent シーンを Duplicate してそこで作業するとよい
  2. Player の子オブジェクトである SD_unitychan_humanoid オブジェクトを無効にして作業を開始するとよい
  3. 攻撃アニメーションには Animation Event を設定し、攻撃判定を有効にすること
    • Animation が Read-Only の場合は上の「注意事項」を参照して Animation Clip を Duplicate する