Line Rendererはゲーム内で線を書くことができる便利なツールです。ゲームの機能としても、デバッグの目印としても使うことが出来ます。ここでは基本的な使い方に合わせて、Line Renderer上を移動するプログラムも作って見ましょう。
Line Rendererの使い方・基本編
まずは基本的な利用方法を覚えましょう。
シーン内にLine Rendererを配置する
まずはLine Rendererをゲーム内で利用するために、呼び出す処理。
- GameObjectMenuヒエラルキー右クリックの中のメニュー。 ... More からEffects>Lineで作成
- 空のGameObjectにAdd Component>Line Renderer
初期設定とかが楽なのはEffects経由の方になります。
主要なコンポーネント・プロパティ
いくつか知っておきたいプロパティがあります。インスペクターで設定できることなど、知らないと戸惑うことなどありますので、そのあたりの紹介。
プロパティ | 効果など |
---|---|
Scene Tools | Line Rendererの線を編集するためのツール 点を増やしたりすることが出来ます。 |
Positions | 線を構成する各点の座標が確認できる 2021以上だとドラッグアンドドロップで頂点の番号が入れ替えられる |
Width | 直線の太さ調整 先端から終端までの太さをAnimation Curveで制御 |
Color | 色 |
Corner Vertices | 直線のつなぎ目のカーブをなめらかにできる。 数字が多いほどなめらかだが、その分メッシュの数が増える |
End Cap Vertices | 始点と終点に丸みをもたせられる 数字が多いほどなめらかだが、その分メッシュの数が増える |
Use World Space | チェックが入っていると絶対座標系になります |
Materials | マテリアル |
Order In Layer | レンダリングの前後関係 Sorting Layerとかも |
頂点の追加方法
多分これが一番楽だと思います。
- Scene Toolsの「+」ボタンを選択
- 頂点追加モードになります
- Input:Mouse Position
- シーン内の頂点を追加したいところをクリック
- 頂点の追加を終了する
- 「+」ボタンを再度押すと、頂点追加モードが解除されます
InputのPhysics Raycastはどう使う?
Physics Raycastはデコボコした当たり判定などがあるものに対して頂点を作ってくれます。床から壁に沿って線を作りたいときなどに便利です。
作った点の編集
作った頂点もシーンビューで編集します。繊細な数値調整を行う場合はPositionsから数値を調整してください。
- Scene Toolsのへし折れた串団子みたいなアイコンを選択
- 頂点編集モードへ移行(名前は適当です)
- 移動させたい頂点を選択
- 頂点の黄色い点を左クリック
- MoveToolの矢印が表示されるのを確認
- 変更したい位置に移動
- 頂点編集モード終了
- 再度串団子を選択
- 全然違うGameObject選択しても解除されます
おまけ:LineMover
ここからはLiner Rendererを使ったちょっとした便利機能の紹介。作ったラインをなぞって移動するプログラムをご紹介
LineMoverスクリプト
下記スクリプトでは、LineMoverの張り付いたGameObjectがLineに沿って移動します。ロジックとしては次の点に向ってspeedに設定された速さで移動します。
- ライン上を移動させたいGameObjectに貼り付ける
- インスペクターに移動させたいLine Rendererをセットする
- Unityを再生すると勝手に動きます
- 速さを調整したい場合、speedの値を増減させて調整
using UnityEngine;
using System;
public class LineMover : MonoBehaviour
{
[SerializeField] private LineRenderer lineRenderer;
[SerializeField] private float speed = 1f;
private int currentIndex;
public EventHandler OnEndReached;
private void Start()
{
Initialize(0,speed,lineRenderer);
}
public void Initialize(int index, float speed, LineRenderer lineRenderer)
{
enabled = true;
currentIndex = index;
this.speed = speed;
this.lineRenderer = lineRenderer;
transform.position = this.lineRenderer.GetPosition(currentIndex);
}
public static (Vector3 targetPosition, bool isEnd) GetTargetPosition(ref int index, float moveSpeed, Vector3 currentPosition, LineRenderer lineRenderer)
{
int nextIndex = index + 1;
if (lineRenderer.positionCount <= nextIndex)
{
return (lineRenderer.GetPosition(index)+ lineRenderer.transform.position, true);
}
var nextPosition = lineRenderer.GetPosition(nextIndex) + lineRenderer.transform.position;
float distance = Vector3.Distance(currentPosition, nextPosition);
if (distance < moveSpeed)
{
index += 1;
return GetTargetPosition(ref index, moveSpeed - distance, nextPosition, lineRenderer);
}
else
{
Vector3 direction = (nextPosition - currentPosition).normalized;
return (currentPosition + direction * moveSpeed, false);
}
}
private void Update()
{
var result = GetTargetPosition(
ref currentIndex,
speed * Time.deltaTime,
transform.position,
lineRenderer);
transform.position = result.targetPosition;
if (result.isEnd)
{
OnEndReached?.Invoke(this, EventArgs.Empty);
enabled = false;
}
}
}
移動が完了したのを受け取りたい場合はOnEndReachedのEventHandlerを受け取れるようにすると確認出来ます。
- 2023-08-18:プログラムを一部修正しました
- Initializeメソッドを追加し、外部から設定できるように変更
プログラムは用途に応じて変更が必要な場合あり
上のプログラムはtransform.positionを更新しているだけなので、物理挙動に組み合わせる場合はRigidbody系のMovePositionとかにする必要があります。ちなみに寿司ゲーの皿の移動なんかも同じものを利用しています。
コメント