次のようなスプライン上の移動経路をスクリプトから管理したいの。
SplinePathクラスを使えば比較的楽に実現できるわ。
スプライン(Splinesパッケージ)の経路情報をスクリプトから管理する方法の解説記事です。
これは、SplinePathクラスを用いると比較的楽に実現できます。
例えば、次のような経路情報を扱うことができます。
- スプラインの部分的な経路
- 複数のスプラインに跨る経路
- 分岐するスプライン上の経路
また、経路情報には区間と移動方向のパラメータが保持されています。これにより、例えば道路を走る車を実装できます。
Splinesパッケージの公式サンプルにもSplinePathクラスを使ったデモシーンが用意されています。
本記事では、SplinePathクラスを用いてスプライン上の経路をスクリプトから管理する方法を解説していきます。
なお、SplinePathクラスはSplines 2.0.0以降でないと使用できないためご注意ください。
- Unity 2022.2.13f1
- Splines 2.1.0
目次 非表示
前提条件
Unity 2022以降でUnityプロジェクトが開かれており、Splines 2.0.0以降がインストールされているものとします。
ここまでの手順が分からない方は、以下記事をご覧ください。
また、本記事の例では、Splinesパッケージ公式が提供しているサンプルシーンSplinePath Sampleを使うものとします。
SplinePathクラス
複数のスプラインにまたがる経路情報を扱うクラスです。SplinePathクラスのほか、ジェネリック型のSplinePath<T>クラスがあります。
これらのクラスは、SplineSlice型のコレクションとして実装されています。
参考:Class SplinePath| Splines | 2.1.0
参考:Class SplinePath<T>| Splines | 2.1.0
SplineSlice構造体
単一のスプライン上の一部または全部の区間を表す構造体です。
次のようにジェネリック型として定義されます。
内部的には次の情報を持っています。
- スプラインオブジェクトへの参照(T型フィールド)
- スプラインの範囲と向き(SplineRange型フィールド)
- 変換行列(float4x4型フィールド)
参考:Struct SplineSlice<T>| Splines | 2.1.0
単一のスプラインのある点からある点までの一方向の経路で良い場合は、SplineSlice構造体でも事足ります。
SplineRange構造体
スプライン上の範囲と向きの情報を持つ構造体です。
範囲情報は、制御点単位で管理されます。
次のようなデータ表現になっています。
- 開始制御点のインデックス(int型フィールド)
- インデックスを進める個数(int型フィールド)
- 向き(SliceDirection型フィールド)
参考:Struct SplineRange| Splines | 2.1.0
経路に沿って移動するサンプル
SplinePathクラスを用いて経路に沿ってオブジェクトを移動させるサンプルスクリプトです。
上記をPathMovementExample.csという名前で保存し、スプラインに沿って移動させたいオブジェクトにアタッチし、インスペクターから経路情報の設定を行うと機能します。
Spline Container項目に移動対象のスプライン、Path項目に経路情報を入力してください。
例では、次のような経路情報としました。
実行結果
インスペクターより割合Tを変更すると、移動対象がその位置に移動します。向きもスプラインに沿って回転しています。
スクリプトの説明
シーン上などで定義されるスプラインの情報は、SplineContainerオブジェクトが管理しています。
これを参照する必要があるため、以下でインスペクターから指定するようにしています。
Splines 2.1.0現在、SplinePathクラスはインスペクターから編集できないため 、以下で独自のパス構造体を定義して疑似的に編集可能にしています。
上記の経路情報からSplinePathインスタンスを作成する処理は以下部分です。
LinqのSelectメソッドを使ってSplineSlice型のコレクションに変換しています。
SplinePathクラスはコンストラクタとしてSplineSlice型コレクションを受け取ることで初期化できます。
参考:Struct SplineSlice<T>| Splines | 2.1.0
そして、予め作成されたSplinePathインスタンスから、割合tにおけるスプライン上の位置や向きなどを取得します。
取得から移動までの処理は以下で行っています。
Evaluateメソッドから、経路における位置、向き、上向きベクトルを一気に取得できます。
なお、EvaluateメソッドはSplinePathクラスではなく、SplineUtilityクラスの拡張メソッドとして提供されているものです。
TはISplineインタフェースを実装している型であれば良いため、SplinePath型以外にもSplineSlice型やSpline型などに対しても使えます。
参考:Class SplineUtility| Splines | 2.1.0
なお、位置や向き、上向きベクトルを個別に取得したい場合は、以下メソッドが使えます。
位置の取得
向きの取得
上向きベクトルの取得
参考:Class SplineUtility| Splines | 2.1.0
実行時は、開始時にSplinePathインスタンスを作成し、フレーム毎に割合tにおける位置や向きなどを反映する移動処理を実施しています。
インスペクターから値を編集するとオブジェクトが移動する仕組みは以下で実現しています。
参考:MonoBehaviour-OnValidate() – Unity スクリプトリファレンス
経路を編集するGUIツールについて
Splines 2.1.0現在では、インスペクターやシーンビュー上から経路を編集できるようなツールは存在しません。
そのため、現状ではスクリプトから動的にSplinePathクラスから経路情報を作成する必要があります。
今後のバージョンアップにより、将来的にはGUI経由で編集可能になるかもしれません。
さいごに
スプラインの経路情報はSplinePathクラスを使うと楽に管理できます。
補間の計算も経路の長さに基づいて行ってくれるため、移動処理などの実装が簡単になります。
これ以外にも、SplinePathオブジェクトの経路情報に基づいて線を描画したり、オブジェクトを配置したりなど、様々な応用が期待できるでしょう。