Line Rendererの基本的な使い方とライン上を移動する処理[Unity]

Line Rendererはゲーム内で線を書くことができる便利なツールです。ゲームの機能としても、デバッグの目印としても使うことが出来ます。ここでは基本的な使い方に合わせて、Line Renderer上を移動するプログラムも作って見ましょう。

目次

Line Rendererの使い方・基本編

まずは基本的な利用方法を覚えましょう。

シーン内にLine Rendererを配置する

まずはLine Rendererをゲーム内で利用するために、呼び出す処理。

  • GameObjectMenu からEffects>Lineで作成
  • 空のGameObjectにAdd Component>Line Renderer

初期設定とかが楽なのはEffects経由の方になります。

主要なコンポーネント・プロパティ

いくつか知っておきたいプロパティがあります。インスペクターで設定できることなど、知らないと戸惑うことなどありますので、そのあたりの紹介。

プロパティ効果など
Scene ToolsLine 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とかにする必要があります。ちなみに寿司ゲーの皿の移動なんかも同じものを利用しています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次