rn.log

備忘録など

【Unity C#】エフェクト用のらせんメッシュを作る

はじめに

お遊びで、エフェクト用のらせんメッシュをUnity C# で作ってみました。
今回の記事では、Unity C# でらせんメッシュを作る方法を解説したいと思います。

f:id:r-ngtm:20210115205521p:plain:w480
Unity C# で動的に作成したメッシュ

ソースコード

らせんメッシュのC#スクリプトは、GitHubリポジトリにて公開しています。SpiralMeshGenerator.csというスクリプトが当該のスクリプトになります。

github.com

Unity 上でメッシュを作るメリット

エフェクト用のメッシュを用意する時、通常はHoudiniやBlenderといった外部のDCCツールを使ってエフェクト用の3Dモデルを作成することになります。
しかし、DCCツールとUnityを行ったり来たりするのはコストがかかります。

Unity上でメッシュを作れる場合、Unity上で結果を見ながら形状を調整できるため、低コストでエフェクト用のメッシュを作ることが可能となります。



作り方解説

STEP1 : らせんのカーブを作る

らせんを作る考え方

らせん上の点の方位角を  \theta と置いたとき、らせん上の点の座標Pは (cos k \theta, \theta, sin k \theta) のような形で表されます。

f:id:r-ngtm:20210115185818p:plain:w480
らせん
/// <summary>
/// カーブに沿ったポイントを作成
/// </summary>
private static void ComputeCurvePoints(SpiralMeshGenerator generator, out Vector3[] points)
{
    float curveTimeMin = generator.radiusCurve[0].time;
    float curveTimeMax = generator.radiusCurve[generator.radiusCurve.length - 1].time;

    points = new Vector3[generator.curveDivsV]; // らせん上のポイントの座標を保存するための配列
    for (int i = 0; i < generator.curveDivsV; i++)
    {
        float t = (float) i / (generator.curveDivsV - 1);
        float radian = t * 2f * Mathf.PI * generator.loops;
        float radius = generator.radiusCurve.Evaluate(Remap(t, 0f, 1f, curveTimeMin, curveTimeMax));  // らせんの半径はAnimationCurveで管理している
        float x = Mathf.Cos(radian) * radius;
        float y = generator.height * t;
        float z = Mathf.Sin(radian) * radius;
        points[i] = new Vector3(x, y, z);
    }
}

半径rのコントロール

高さ \thetaでの らせんの半径 r(\theta) は AnimationCurve でコントロールできるようにしています。

f:id:r-ngtm:20210115192431p:plain:w240
らせんの半径r
float radius = generator.radiusCurve.Evaluate(Remap(t, 0f, 1f, curveTimeMin, curveTimeMax));  // らせんの半径はAnimationCurveで管理している

これにより、AnimationCurveを変えることでらせん形状のバリエーションを出せるようになります。

f:id:r-ngtm:20210115204435p:plain:w320
様々ならせん形状



STEP2 : らせんに沿ってメッシュを作成する

らせんメッシュの作り方

STEP1 でらせんを計算しました。

f:id:r-ngtm:20210115194751p:plain:w280
らせんのライン

らせんの各ポイントから外側へ向かうベクトル  r を計算します。

f:id:r-ngtm:20210115212315p:plain:w280
外側へ向かうベクトル r

ベクトル  r にそってメッシュを広げることで、らせんメッシュを作ることができます。

f:id:r-ngtm:20210115212710p:plain:w280
らせんメッシュ


このベクトル  r外積を利用して計算することができます。

外積を利用する

らせんに沿うような接線ベクトルを  \vec t 、y軸上向きのベクトルを  \vec uと置きます。

らせんの外側を向くベクトル  \vec r外積を利用して計算できます。

 \vec r = \vec t \times \vec u

f:id:r-ngtm:20210115010540p:plain:w320
外側方向のベクトル r

STEP3 : らせんメッシュをねじる

 \vec r, \vec  u を軸とみなす

STEP2で、二つのベクトル  \vec r  \vec  u を計算しました。
ここで、これらのベクトルを座標軸と考えて、以下のような点Pを取ることを考えます。

 \vec P = cos \theta \cdot \vec r + sin  \theta \cdot \vec u
f:id:r-ngtm:20210115011833p:plain:w320

 \vec r, \vec  u を利用して、メッシュ頂点を計算する

この点Pをメッシュの頂点として利用すると、らせんメッシュをらせんに沿ってひねったような軌跡を描きます。

f:id:r-ngtm:20210115201110p:plain:w240
点Pを取る
f:id:r-ngtm:20210115201713p:plain:w240
点Pをメッシュ頂点として利用
f:id:r-ngtm:20210115213052p:plain:w240
結果

この \vec r, \vec  uは、線形代数学では直交基底ベクトルと呼ばれたりもします。