Unityのメッシュ生成でへにょりレーザーを作ろう – 前編

ども、ゴコーです。

STG作ってたらへにょりレーザーが欲しくなりました。しかし、作る時に欲しい記事が見つからなかったので自分で書くことにしました。という訳で、動的なメッシュ生成から初めて、数回に分けてへにょりレーザーを作っていきましょう。

へにょりレーザーって?

へにょりレーザーってなんやねんという人もいると思います。へにょりレーザーとは シューティングゲームの東方シリーズにおける、うねうねと曲がるレーザー攻撃のことです。正式名称は決まっていないらしく通称です。今回のチュートリアルでは以下のようなものを作ります。

henyoridemo

スポンサーリンク

前提

  1. いきなりですが、メッシュ生成の基礎については他サイトさまが詳しいのでそちらを参考にしてください。下記の超基本編は終わらせてからチュートリアルを始めた方が良いと思います(その2以降は必須ではありません)。
    Unity 動的にメッシュを生成してゴニョゴニョする : 超基本編 – 渋谷ほととぎす通信
  2. 今回のチュートリアルは一部でゲームの作り方 Unityで覚える遊びのアルゴリズム の第10章 ナゾレバ・ハシレール(以下ナゾレバ)を参考にしており、Unity5.3.2に対応したソースコード(9/18現在)はサポートページからダウンロードすることができます。そのため、書籍で解説されている一部ソースコードへの解説は省略しています。より詳しく知りたい方は是非書籍を購入してください。オススメです。
  3. 本チュートリアルの対象読者は Unityの操作は一通り分かるくらいの初心者~を想定してます。そのため、初心者向けの補完知識をコラムとして各節の最後に載せています。読みたい方は コラム:… と書いてある部分をクリックしてください。
  4. さらに、本筋とはあまり関係ないけどやると良さげなものや、ちょっとディープな最適化などはへにょりレーザー完成後の追加項目として扱います。

このチュートリアルで学べるもの

本編

  • Unityでの四角メッシュポリゴン描画の基礎
  • Gizmoクラスによるプレビューの基礎
  • インターフェイスの使用例
  • コルーチンの使用例 等

追加項目

  • インデックスを取れるQueueの作成
  • Catmull-Rom Spline による補間 等

四角ポリゴンの生成について

基礎については上記の記事で十分確認できると思います。しかし今回は三角ポリゴンではなく四角ポリゴンを作る必要があるので、上記の知識を前提とした簡単な解説を挟みつつ作業を進めていきます。

さて、ポリゴンの生成に最低限必要なものは頂点座標と頂点インデックスです。そして三角ポリゴンと四角ポリゴンとの大きな違いは1つのポリゴンを作成するのに必要な頂点座標が3つから4つになることです。という訳で、次節からは四角ポリゴンに対応した頂点座標の登録を行います。

頂点座標の計算

以下のように、レーザーとナゾレバの道路生成は似ている点がかなり多いです。

  • 四角メッシュを作成している
  • メッシュの幅は一定
  • 進行方向という概念がある

という訳で、頂点座標の計算にはナゾレバの考え方を使います。めちゃくちゃ大雑把に書くと、レーザーの中心座標を1つ用意すれば良い感じにメッシュの頂点座標が2つ計算される仕組みを用意するというものです。
「良い感じの頂点座標計算」の流れは以下のような感じです。

  1.  中心点を設定
  2.  中心点の位置関係から進行方向のベクトルを計算
  3.  方向ベクトルに直交するベクトルを元に両脇の頂点を設定。中心からの距離は一定に。

この方法を用いて作成した頂点でメッシュを描画して、矢印などを書き足した画像がこちら。

2016-09-19_14h55_011

黒い点が中心点、青い矢印が進行方向、赤い矢印がメッシュの幅、青い点が頂点座標を表しています。これらの情報をひっくるめてセクションと呼称します。
そして、3つの中心点を設定すると3つのセクションを元に2つの四角メッシュが生成される、というように (中心点数 – 1) だけの四角メッシュを生成するようにします。

では、まずは必要なクラスと変数を用意しましょう。コンポーネント名は CurveLaserMaker です。

points は中心点、sections は points を元に必要な要素を入れるための構造体、laserWidth は生成するレーザーの幅です。

2016-09-19_14h55_011

この画像で言うと、黒い点が points、青い矢印が direction、赤い矢印が laserWidth、points から見て左の青い点が left、右が right です。

では次に、points を元に各種ベクトルを計算します。

以降、変更点はハイライトします。今回は大きく分けて2つのことをしています。

まず、前後のポイントかポイント自身を用いて方向ベクトルの計算を行います。
次に、方向ベクトルに直交するベクトルに幅を掛け合わせてセクションの両端を求める、というものです。

各ベクトル計算の詳細についてはゲームの作り方のナゾレバを参照してください。

コラム:RequireComponent

頂点のプレビュー

先ほどは中心点とポリゴン用の頂点座標を設定できるようにしました。シーンに CurveLaserMaker という空オブジェクトを作成し、CurveLaserMakerコンポーネントを張り付ければPointsを自由に変更することができますね。

しかし数字を変更しても見た目は何も変わらないためこのままではイメージがし辛いです。そこで、次は各座標をシーンビューでプレビューしてみましょう。

プレビューには Gizmo クラスを使います。コードは次のとおり。

中心は黒、両サイドは青色のスフィアを表示するようにしました。

henyori1-1

points の各要素を増やしたり位置を変更するとリアルタイムにその頂点の周辺のセクションも位置を変えているのが確認できると思います。

コラム:OnValidate
コラム:GizmosとOnDrawGizmos

メッシュの描画

次は設定した頂点を元にポリゴンメッシュを描画してみましょう。

画像多めで今回の頂点座標設定のおさらいからいきます。

2016-09-21_16h24_441

1つ前の節までで、中心座標を用意すると自動で頂点座標が用意される仕組みを作りました。上記の画像は、中心座標の1つ目(P[0])と2つ目(P[1])を表しています。とりあえず分かりやすくするため、2点だけ考えます。

2016-09-21_16h24_442

このようにセクションの中心座標を設定すると自動的に左右の頂点が表示されるようにしました。しかしメッシュ描画時に考慮するのは頂点座標だけなのでP[0]とP[1]は消します。

2016-09-21_16h24_46

この4つの頂点を元に四角のメッシュを作成します。次は四角メッシュは2つの三角メッシュの組み合わせで作ることも考慮して補助線を引いてみます。

2016-09-21_16h24_47

それではこの4点をメッシュ描画時に使えるようにコードに置き換えましょう。

このようになります。今のところ難しい話ではないですね。
メッシュの数が増えた場合もこちらのコードを元に改変すれば対応は難しくなさそうです。

さて、描画に必要な頂点座標はなんとなーく見えたと思うので、次は頂点インデックスを考慮してみましょう。最初に紹介した記事でも書かれていたとおり、頂点インデックスはその順番によって作成したメッシュの前面や、後々設定するUV座標などが決まるためかなり重要な情報です。

注意点は以下のような感じです。

  1. 頂点インデックスはメッシュの数 × 3(三角メッシュの頂点数) × 2(四角メッシュは2つの三角メッシュで構成される) だけ必要になる
  2. Unityは左手座標系なので時計回りに設定する

画像にするとこんな感じです。

2016-09-21_16h24_48

コードにすると以下のようになります。

右オペランドの 0 ~ 3 の数字は何かというと、先ほど頂点座標を割り当てた配列のインデックスです。先ほどのコード、頂点インデックスを示すための画像、このコードを見比べると意味が分かるかと思います。

次はここまでの説明を実際のコードに落とし込んでみます。

前に書いた通り、メッシュの数(meshCount)はポイント数 – 1になります。

実際にはメッシュ数が2つ以上あるため、座標設定とインデックス設定の内容を変更してメッシュの数だけfor文で回してます。

これでメッシュが生成されます。さっそく見てみましょう。

2016-09-23_11h45_05

うわあ…という感じのピンクが表示されたと思います。これはマテリアルが設定されてない状態などの警告色です。

マテリアルを作り、割り当ててみましょう。

2016-09-23_11h48_47Projectビューで右クリック、Create→Materialをクリックしてください。名前はCurveLaserMaterialとします。

できたマテリアルをCurveLaserMakerのMeshRendererのMaterials に割り当ててください。

2016-09-23_12h00_45

2016-09-23_11h52_06

できました!

さて、今回は頂点の設定からポリゴンメッシュの描画までを行いました。次回はインスペクター以外から頂点を追加し、テクスチャを設定してレーザーを作りましょう!

では、また。

Comments

comments

スポンサーリンク
336*280px