はじめに
Unity 2022.1から入っている新機能 Splines
を使ってみたかったので、とりあえず 触ってみることにしました。これからゲーム等に活用していければ嬉しいですね
Demo
Runtime及び Editor上で Splinesのknot(各ポジション)を増やせるクラスの作成や調査を行いました。
環境
- Unity 2022.2.0b13
- Splines 2.0.0
- Odin
Splineとは
公式サイトより
パスに沿ってオブジェクトと動作を生成し、軌跡を作成し、形状を描画します。
UnityのSplines デモシーンの確認
どんなものなのかデモを見てみないと分からないので、確認してみます。
サンプルの導入方法
- Unity Package Managerを開く
- Packgesの
Unity Registry
を選択 (画像の1) - 検索欄で Splinesで検索して出てきたものを選択
- タブの中から
Sample
を選択 (画像の2) - サンプルデータをimportする(画像の3)
サンプルシーンの動作確認
Loft Road
道が今までできなかった曲線を描いている静止デモ
2 . Spline Animate
1の道路の上にCubeを載せてアニメーションで動くようにしているデモ
3 . ExtrudeSpline
Meshデータを Splineを使って動かすデモ
4 . SplineInstantiate
Treeや Grassなども曲線に配置している 静止デモ
5 . SplineData and Generation
Spline周りのAPIを使用して生成するデモ
ReadMeより
plineData
、SplineUtility
、SplineEditorUtility
API を使って、シーン上にスプラインベースのオブジェクトをプロシージャルに生成する
6 . Area Generation
5とほぼ同様?のデモ
7 . Nearest Point
任意の場所からスプライン上の最も近い点を見つけて移動するデモ
8 . Curvature
スプライン曲率の可視化しているデモ
9 . Embedded Spline
スプラインをコンポーネントに埋め込んで動かしているデモ
10 . GPU Evaluation
GPU上で Splineの計算を行うデモ
Spline関連クラスについて
クラスイメージは以下のようになっています。
SplineContainer
Inspectorに表示されている Splineは SplineContainer
クラスになっています。
基本これが親クラスです。
Spline
Spline0
と書かれている部分は Spline
になっていて、画面に表示されるポイントの箱(リスト)です
BezierKnot
各ポイントを Knot
と呼ばれる位置や回転情報などの情報です。
SplineのKnotの操作
追加
それでは Editor上やRuntime上で Knotを増やしていけるようにしたいと思います。 上記のクラス関係から 何もない状態からでも追加できるようにします。
まず SplineContainerが追加されているかを判断するために、以下のif文を入れます。
if (splineContainer.Splines.Count != 0) return;
次に 追加したい SplineContainerを指定して、以下の処理で Splineを追加していきます
splineContainer.AddSpline();
最後に Knotを追加します
splineContainer.Spline.Add(knot);
最終的なスクリプトは以下のようになりました。
public class SplineKnotExtra : MonoBehaviour { [SerializeField] private List<SplineContainer> movePointList; #region EditorからSplineを操作する /// <summary> /// Knotを一つランダム値を一つ追加 /// </summary> private static void AddKnotAtRandomValue(SplineContainer splineContainer, int addSplines) { for (var splineCount = 0; splineCount < addSplines; splineCount++) { var knot = new BezierKnot(Random.Range(-50f, 50f), Random.Range(-50f, 50f), Random.Range(-50f, 50f), Random.rotation); splineContainer.Spline.Add(knot); } } private static void AddKnotAt2DLineRandomValue(SplineContainer splineContainer, int addSplines) { for (var splineCount = 0; splineCount < addSplines; splineCount++) { var knot = new BezierKnot(Random.Range(-50f, 50f)); splineContainer.Spline.Add(knot); } } /// <summary> /// SplineのNodeを任意の数を追加 /// </summary> private static void AddSplineKnot(SplineContainer splineContainer, int addSplineCount) { if (splineContainer.Splines.Count != 0) return; for (var addSplineCountIndex = 0; addSplineCountIndex < addSplineCount; addSplineCountIndex++) { splineContainer.AddSpline(); } } #endregion [Button("Spline Knowのランダム追加")] private void AddRandomKnot(int addKnowCount) { foreach (var splineContainer in movePointList) { AddSplineKnot(splineContainer, addKnowCount); AddKnotAtRandomValue(splineContainer, addKnowCount); } } [Button("2D line Knowのランダム追加")] private void AddRandom2DLineKnot(int addKnowCount) { foreach (var splineContainer in movePointList) { AddSplineKnot(splineContainer, addKnowCount); AddKnotAt2DLineRandomValue(splineContainer, addKnowCount); } } [Button("Spline Know Reset")] private void RemoveAllKnot() { foreach (var splineContainer in movePointList) { splineContainer.RemoveSpline(splineContainer.Spline); } } }
取得
以下の画像のように任意のSplineの最後のknot情報を取得したいときは以下のようにして取得します。
_splineContainer.Splines[_splineIndex].Knots.Last();