LineRendererでレーザーのようにアニメーションさせる

A01

UnityでNodeGarden その2 」では、LineRendererで線を引くことができましたが、ノードを動かしたときにアニメーションがうまくいきませんでした。ソースコードにいろいろ修正を加えていてシンプルに考えるのが難しくなってきたので、改めて、小さなプロジェクトを作成して、SetVertexCount関数などの挙動を確認しました。

参考資料は2014年に書かれた以下の資料で、現在でも問題なく実装できました。

ソースコード

線を引くスクリプト

画像左側のアニメーションをしないキューブ間の線を引いたスクリプトです。大きな変更はなく、キューブを3つにしたぐらいです。

 

キューブの円運動スクリプト

線を描画したときにキューブが動いたらどうなるか確認するために、キューブをMath.sinで円運動させました。Math.sin、Math.cosでTime.timeで時間が進むごとに、-1から1の範囲の値が取得できます。それをキューブの初期のX座標に足すことで円運動になります。

このソースコードを試したところ、gif画像の左側のように、キューブ間の線が追随して描画されることが確認できました。なのでこのソースコードをベースにすれば、「UnityでNodeGarden その2 」での失敗が修正できそうです。

Lineアニメーション・スクリプト

ちょっと難しそうですが、やっていることは簡単で、1をLineDrawSpeedで割って、それをcountに加算していくことで、線の長さが増えていきます。それでスフィア座標(srcTrans)-スフィア座標(destTrans)がスフィア間の距離なので、そこまで線を引くようになっています。

もし、スフィア間より、線のcountが大きくなったら、SetVertexCount(0)でLineRendererを初期化して、count=0で、線の長さも初期化しています。

ここで重要なのが、Update関数で、SetVertexCount(0)を呼び出すときは、SetVertexCount(2)を呼び出さないことです。Unityでは(DirectX、OpenGLでも同様)、Update関数から抜けた後に描画処理が実行されます。そのため、1回のUpdate関数呼び出しの時に以下のようにSetVertexCountを書いても、SetVertexCount(0)で描画がリセットされて、SetVertexCount(2)で、再設定されるというわけではありません。この場合は、SetVertexCount(2)で2が頂点数として保持されて、Update関数から抜けると、描画処理では頂点数2と判断して描画が開始されます。

 

まとめ

DirectXやOpenGLも同様で、当たり前なのですが、ノードの移動やパーティクルの調整などいろいろなコード修正をしていたら、SetVertexCountの更新と、描画処理の関係も忘れていました。今回シンプルな実装を試したことで、NodeGardenを完成させることができそうです。

UnityでNodeGarden その2

001

前回「UnityでNodeGarden その1」ではとりあえず箱を表示することしかできませんでしたが、LineRendererとカメラのImageEffectsによるBloom、ParticleSystem、オブジェクトの発光で上記の画像のように表示することができました。

まだ問題があって、LineRendererの描画が残ってしまい、ノードが移動すると、どんどん線が増えて行ってしまう状態です。これを解決するにはLineRendererを使っているサンプルなど、他人のプログラムを試す必要がありそうです。

ちなみに最初のコードは以下のような感じでした。我ながらだいぶ成長できたと感じます。

unity01

 

 

ソースコード

元々はLineを生成するためのコードだったのですが、現在はノードを50個生成するソースコードです。これは特に難しいことはしていません。

 

LineRendererで線を描画するスクリプトです。一度引いた線を消すことができていないので実装を修正する必要があります。

 

プロジェクトの配布

このプロジェクトはかなりソースコードが途中ですが配布します。

http://hajimete-program.com/games/LineRendererSandbox.zip

 

 

UnityでNodeGarden その1

unity01

UnityでProcessingで作ったのNode Gardenのようなものを作って見ようとしているのですが、いくつか分からないことがあります。

エッジはどうやって作ればよいのでしょう。

ノードをつなげるエッジは、Spring Jointを使って実現できそうですが、プリミティブオブジェクトをコードで伸縮させるのは面倒そうです。それともパーティクルのようなものでエッジを実現すればよいのかわかりません。

レイキャストができるので、それで照射して一定区間なら、その光線に対してパーティクルを設定するなどができそうな気もします。

上記からできる出来ないは別にして、課題ができました。とりあえずパーティクルが面白そうなのでパーティクルを調べてみます。

  • パーティクルを調査
  • レイキャストを調査
  • ジョイントを調査

ひとまず線を引くということでよければ以下が参考になりそうです。

意外と簡単!Node Gardenを作ってみましょう!

 

node_garden

 

Node Gerdenは、白丸を線で繋いだアニメーションです。白丸をTwitterのアイコンにしたり、Youtubeのお気に入り画像を表示すれば、関係性を視覚化できたりします。複雑なようで実は簡単なのでProcessingで作ってみましょう。

以下ソースコードがたくさん書かれているように感じますが、修正前と修正後のソースコードをすべて貼り付けているためです。実際はコメントを含めて100行ぐらいで、簡単なので挑戦してみてください。

 

大まかな作り方を把握

  1. ノード(白丸)をランダムに表示します。
  2. 白丸が移動できるようにします。
  3. すべての白丸を線でつなぎます。
  4. ある一定の距離だけ線でつなぐように修正します。
  5. (応用)線をばね(スプリング)と考え、白丸の速度に変化を加えます。

ノードをランダムに表示します。

 

白丸が移動移動できるようにします。

ノードクラスに速度を表すxv(X座標のVelocity)とyvを用意して、描画毎にxy座標に足すことで移動します。また画面外に移動した場合は、反対側から出てくるようにします。例えば白丸が右側に進んで画面外になったら、左側からでてくるようにします。

 

すべての白丸を線でつなぎます。

node_garden02

ある一定の距離だけ線でつなぐように修正します。

node_garden03

ここまででほぼ完成しました。冷静に考えると2点の丸を好きな場所に表示して、それを移動するようにして、線でつなげるだけです。

(応用)線をばね(スプリング)と考え、白丸の速度に変化を加えます。

node_garden04

線を表示した場合は、少しだけ速度を変化させるようにしました。例えばx座標の距離dxが100ピクセルなら、係数0.0001を掛けて、0.001速度を加えます。値はかなり小さいのですが、1/60秒毎にこのメソッドが呼ばれているためかなりの効果があります。いろいろ係数を調整してみてください。

また、ノード間の距離が長くなると線が薄く表示されるようにアルファチャンネルを修正しました。

 

このコードでは、ばね効果でどんどんノードの速度が速くなってしまいます。vx,vyがある一定速度になったら、0.5に戻すなどの処置をすると綺麗になります。

応用

基礎のため白色の丸でしたが、別に画像ファイルでも問題ありません。そのため、TwitterアイコンやYoutubeのサムネイルでノードを作成して、関連が強いものは引き合うアルゴリズムなどを作ってみるとおもしろそうです。またノードの追加、削除、ノードをクリックしたときのエフェクトや、任意のノード間の最短経路など様々応用が可能です。

まとめ

インターネット上では日本語でもNode Gardenのサンプルはあるのですが解説が少ないので、ProcessingでNode Gardenを作ってその解説をしてみました。作る前はすごく大変そうと思っていたのですが、100行足らずで作成できたので拍子抜けでした。