[Unity] 某まるっこい、ぷにっとしたコントローラーを作ってみる

某プロジェクトのぷにっとしたコントローラーを作ってみたいと思います。調べてみると「特許が~」みたいな記述はあるものの、インターフェース関係だし大丈夫だろうと判断しました。

もちろん再現したのは見た目だけなので、触り心地はだいぶ違うものになっています。

 

 

 

環境

Unity 5.0.1f1

 

ぐにぐに

結果から。こんな感じになりました。

punipuni_on_unity

 

作った手順

※最初はVisualStudio上で試しました。

始めに円形を作成します。(あとでUnityに移植する前提でVisualStudio上で作成)

beziercurve_circle

この処理には中心位置(最初に押された場所)と先端位置(現在の位置)の2つの座標値を使用します。

beziercurve_2point_info

中心位置は固定とし、先端位置を変化させることでぷにぷに感を出す必要があります。そこでイラストレーターなどでお馴染みのベジェ曲線を使います。

3次ベジェ曲線なので4点座標値が必要です。中心、先端の2点は決定しているので、残り2点を自動で決めていきます。

ちなみに4点は

  1. 中心点(P1)
  2. 中心制御点(P2)
  3. 先端制御点(P3)
  4. 先端点(P4)

の4つです。

ベジェ曲線のある位置の求め方はこちらを参考にしました。

beziercurve_bezier4point_info

中心制御点(P2)は、中心から先端に向かった一定距離にある点とします。ただし、一定時間で到達するように少しずつ移動するようにします。先端制御点(P3)は基本的に先端点と同じ位置ですが、中心制御点(P2)と同じく一定時間で到達するようにします。

中心制御点(P2)が判りにくいですが、中心から一瞬見えている線がそうです。これで中心から先端までの曲線が引けました。

beziercurve_end_control_point

(※P3の位置はまるっこくする為、記事を書いた後ちょっと修正して移動させました。先端に重ならずちょっと横に飛び出る。)

beziercurve_3curves_info2

円のサイズに合わせて左右に曲線を作成します。左右の中心制御点(P2)の方向は、中央に引いた中心点(P1)から中心制御点(P2)の方向と同じにしました。ぷにっと感を出すには少し太らせた方が良かった為です。

beziercurve_3curves_info

変形すべき点を求めます。判定方法は中心線との外積の符号だけ見ればよさそうだったのでそれで判定しました。

beziercurve_transform_target_points

変形対象の頂点が判ったので、その中で真ん中の頂点1つをドラッグされている位置へ、残りの頂点を半分ずつに分けて各曲線に振り分けていきます。

beziercurve_transform_target_position

曲線に沿って頂点を変形します。ただし円の内側に移動することが無いようにします。

beziercurve_transform_points

頂点数16で円を作っているので、少しガタガタな感じ。頂点数を増やせば綺麗に見えます。

64頂点で作った場合はこうなります。

beziercurve_transform_points2

 

Unity上に移植

円形のメッシュを作成します。中心座標のα値が0、外側のα値は1として生成。起動時に作っておきます。円形の外周点の座標値は使用するので配列化しておきます。

メッシュが使用するマテリアルは「Sprites-Default」を使用。

punipuni_circle

このオブジェクト専用のカメラを用意します。UIとして使う前提に考えると正射影(orthographic)カメラであった方が良さそう。

punipuni_camera

あとはVisualStudio上で行ったことをUnity上のメッシュに適応させます。

最後の最後にポリラインでテストしていた時は良かったのですが、ポリゴンにした時に三角形が見えてしまった。(ヌルヌルしない・・・) この問題はポリゴンの中心位置を移動させて対応。見た目もマウス、指がある部分が透明になったので意外とよさそう!

punipuni_center_info

 

サンプル

 

まとめ

Unityなら頂点変形シェーダー(自分は作れない)とか、ジョイントを繋げて変形(出来るの?)とか、ボーンのウェイトで変形を再現する(しっぽ的な動き?)とか他にもいろいろな方法がありそうです。某プロジェクトは円形以外の形にも変形するので普通にボーンアニメーション+回転だけで作ってそう。(試せる力を持ってないので出来ず・・・)

ベジェ曲線の位置を求める計算が「1フレーム当たり : 最大で円の頂点数の半分」 が必要になるのでCPU側ではなく、GPU側のシェーダーでコーディングできるといいですよね。メッシュの変形も毎フレームやってますし。まぁ1つしか画面に出ないものだからこれでいいのかな。

動きとしてはドラッグされている位置に頂点を持ってくるのではなく、中心からドラッグ位置の少し先に頂点が来るように調整したほうが良いかも。

 

参考サイト

ベジェ曲線

3次ベジェ曲線の数式

点と三角形の当たり判定( 内外判定 )

2つのベクトルのなす角度を求める(2次元 3次元)

[Unity]Meshの頂点を移動

 

ソースコード

ソースコードはこちら -> PunipuniSource

※2015/6/18
ソースコードに間違いあり。
BezierクラスのGetPositionに1以上の値を指定するとP2の値を返してしますが、正しくはP4を返す必要があります。


希木小鳥

Diablo1でハクスラの世界に。今はBorderlands2をプレイ中。ぬるゲーマー。

あわせて読みたい