Unity で自由に線を引くには Line Renderer というコンポーネントがお手軽です。
今回はこれを使って☆を描画してみようと思います。
オブジェクトを配置
まず、空の GameObject を作成し、Line Renderer コンポーネントを追加します。
3D/Sphere は描画の先端を表す球体です。
Line Renderer のインスペクタを設定
オレンジの箇所を設定します。
Color
虹色にしたかったので、頑張って調整。
キーは合計8つまでなんですね…お陰で数値が割り切れなかった。
Corner Vertices, End Cap Vertices
角や終端を多角形にすることで、丸みを出すことができます。
Materials
設定必須。Default-Line を選択しましょう。
設定しないと unity ではお馴染みピンク表示になってしまいます。
Width
こちらは任意で。始点から終点の線の太さを設定します。
初期状態のままだと、結構太目のラインです。
☆を描画するスクリプト
以下のスクリプトを Line Renderer と同じオブジェクトに貼り付けます。
using System.Collections; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { [SerializeField] LineRenderer render; [SerializeField] GameObject sphere; IEnumerator Start() { yield return null; Vector3[] point = new Vector3[6]; point[0] = Quaternion.Euler(0, 216.0f, 0) * new Vector3(0, 0, 10); point[1] = Quaternion.Euler(0, 0.0f, 0) * new Vector3(0, 0, 10); point[2] = Quaternion.Euler(0, 144.0f, 0) * new Vector3(0, 0, 10); point[3] = Quaternion.Euler(0, 288.0f, 0) * new Vector3(0, 0, 10); point[4] = Quaternion.Euler(0, 72.0f, 0) * new Vector3(0, 0, 10); point[5] = Quaternion.Euler(0, 216.0f, 0) * new Vector3(0, 0, 10); for (int no = 0; no < 6; no++) { render.positionCount = no+1; render.SetPositions(point); if (no > 0) { float time = 0; while (time < 0.9f) { time += Time.deltaTime * 2; if (time > 0.9f) { time = 0.9f; } Vector3 p = point[no-1] + ((point[no] - point[no-1]) * (time + 0.1f)); render.SetPosition(no, p); sphere.transform.position = p; yield return null; } } yield return null; } } }
忘れずインスペクタに、オブジェクトをアタッチしてください。
(これをやっておかないとエラーで実行されません)
以下、ソースコードについて軽く説明します。
☆の書き方
☆の頂点は5角形の頂点と同じです。
5角形は同じ円の上に存在します。5等分するので、1つにつき 72 度間隔をあけます。
書き順は左下①~⑤の順番になるので、その頂点順に頂点座標を求めています。
point[0] と point[5] が同一なのは、☆を書く時の始点と終点が同じ場所だからです。
point[0] = Quaternion.Euler(0, 216.0f, 0) * new Vector3(0, 0, 10); point[1] = Quaternion.Euler(0, 0.0f, 0) * new Vector3(0, 0, 10); point[2] = Quaternion.Euler(0, 144.0f, 0) * new Vector3(0, 0, 10); point[3] = Quaternion.Euler(0, 288.0f, 0) * new Vector3(0, 0, 10); point[4] = Quaternion.Euler(0, 72.0f, 0) * new Vector3(0, 0, 10); point[5] = Quaternion.Euler(0, 216.0f, 0) * new Vector3(0, 0, 10);
線を伸ばしながら描画する
26-45 行目は線を伸ばしながら描画している部分です。
time += Time.deltaTime * 2;
0.45 秒で線を1つ描画しています。
Time.deltaTime は yield return してからの経過時間です。
Vector3 p = point[no-1] + ((point[no] - point[no-1]) * (time + 0.1f));
始点+ (終点ー始点) × 時間(0~1) の計算式で、経過時間ごとの「始点から終点までのポジション」を計算します。
このあたり直感的にわからない場合は、Debug.Log などで具体的に数字を表示するといいかもしれません。
ワンポイント
time が 0.0~0.9 を範囲として、後から 0.1 足しているのは Line Renderer の特性で表示がおかしくなってしまう部分を誤魔化しています(笑)
time を 0.0~1.0 とするコードはこちらです(差し替え分)。
while (time < 1.0f) { time += Time.deltaTime; if (time > 1.0f) { time = 1.0f; } Vector3 p = point[no-1] + ((point[no] - point[no-1]) * time); render.SetPosition(no, p); sphere.transform.position = p; yield return null; }
time を 0.0~1.0 として素直に動かした場合、頂点付近を描画する際「線が細く」なっているのがわかるでしょうか。
これは一瞬ですが不安定な動作と言えます。
はっきりと理由を解析していません(頂点を綺麗に描画するためのロジック上、2頂点の位置が近すぎると計算誤差がひどくなるため、とか?)が、その特性も加味しつつ、正しく動かすために time を 0.1~1.0 として不安定な部分をクリアしました。
時間が許すのであれば、不安定になってしまう理由をひたすら追求するのもいいですね!
初心者にはオススメしませんが…。