2011/03/13

ベジエ曲線を使ってレーザービーム

いやはや。。ようやくベジエ曲線を使ってレーザービームらしきものを飛ばすことができるようになりました。
とはいっても、まだまだ手直ししないといけない部分が満載なのですが。。


赤色の線は、制御点を結んだもので黄緑色の線が3次ベジエ曲線。。のはず。(笑
でもなんか違っているような気もします。


それはさておき、とりあえずソースコードを貼付けてみました。
JavaScriptではなくBooで記述したのであまり参考にはならないかも(笑
(SyntaxHighlighterはBooのシンタックスカラーリングをしてくれないみたいなので、Pythonとして表示してみました。)

下記のBezierBeam1は、Weaponというクラスから派生したもので、BezierBeam1のメソッド_UpdatePositionは、その親クラスのメソッドUpdateから呼び出されます。つまり更新のタイミングでかならず呼び出されます。

やっていることはかなり単純で、メソッド_Blendで求めたベジエ曲線上の点の座標をtransform.positionのx, y, zそれぞれに設定しているだけです。

メソッド_Blendでは、ベジエ曲線の公式で単純に計算しているだけなので、高速化とかそのあたりについては全く考慮されていません。


import UnityEngine

class BezierBeam1 (Weapon):
    # PUBLICS
    public offsetQ1 as Vector3 = Vector3(0.0, 1.0, 1.0)
    public offsetQ2 as Vector3 = Vector3(0.0, 0.5, 1.5)
    # PRIVATES
    _goalPosition as Vector3 = Vector3.zero
    _lastT = 0.0
 
    virtual def _UpdatePosition(initialPos as Vector3):
        posQ0 = initialPos
        posQ1 = posQ0 + offsetQ1
        posQ2 = posQ0 + offsetQ2
        posQ3 = _goalPosition
 
        Debug.DrawLine(posQ0, posQ1, Color.red)
        Debug.DrawLine(posQ1, posQ2, Color.red)
        Debug.DrawLine(posQ2, posQ3, Color.red)

        _lastT += Time.deltaTime
        if _lastT > 1.0:
            _lastT = 0.0

        pos as Vector3
        pos.x = _Blend(_lastT, posQ0.x, posQ1.x, posQ2.x, posQ3.x)
        pos.y = _Blend(_lastT, posQ0.y, posQ1.y, posQ2.y, posQ3.y)
        pos.z = _Blend(_lastT, posQ0.z, posQ1.z, posQ2.z, posQ3.z)
        transform.position = pos
  
    def _Blend(t as single, q0 as single, q1 as single, q2 as single, q3 as single):
        wt as single = 1.0 - t
        val as single = (q0 * wt * wt * wt) + (3 * q1 * wt * wt * t) + (3 * q2 * wt * t * t) + (q3 * t * t * t)
        # Debug.Log("Blend = ${t} ${q0}, ${q1}, ${q2}, ${q3}, ${val}")
        return val

    def SetGoalPosition(goal as Vector3):
        _goalPosition = goal


さて、現状だと1本のビームだけで寂しいので、もう少し本数を増やしてみようかと思っています。

0 件のコメント:

コメントを投稿