マウスで引いた線に重力や衝突を加えて物体を動かす【Unity】

UnityのLineRendererを利用して、画面上に描いた線に色々と機能を加えてみます。

はじめに

Unityのバージョンは2021.3.14f1です。以前、LineRendererを利用してマウスドラッグで画面に線を描きました。

今回は、その続きと言う感じで下記のように線に重力や衝突を加えてみます。

実装開始

衝突機能(Collider)を加えた後に重力機能(rigidbody)を加えます。

コライダー(Collider)

LineDrawオブジェクトに「EdgeColider2D」をアタッチ。EdgeRadiusは線の太さにあわせて変更します。Pointsのサイズは0に。

スクリプトは下記に変更。コライダーのポイントを追加しています。

using System.Collections.Generic;
using UnityEngine;

public class LineDraw : MonoBehaviour
{
    [SerializeField] private LineRenderer _rend;
    [SerializeField] private Camera _cam;
    [SerializeField] private EdgeCollider2D _collider;

    private int posCount = 0;
    private float interval = 0.1f;
    private List<Vector2> _points = new List<Vector2>();

    private void Update()
    {
        Vector2 mousePos = _cam.ScreenToWorldPoint(Input.mousePosition);

        if (Input.GetMouseButton(0))
            SetPosition(mousePos);
        else if (Input.GetMouseButtonUp(0))
            posCount = 0;
    }

    private void SetPosition(Vector2 pos)
    {
        if (!PosCheck(pos)) return;

        posCount++;
        _rend.positionCount = posCount;
        _rend.SetPosition(posCount - 1, pos);

        _points.Add(pos);
        _collider.points = _points.ToArray();

    }

    private bool PosCheck(Vector2 pos)
    {
        if (posCount == 0) return true;

        float distance = Vector2.Distance(_rend.GetPosition(posCount - 1), pos);
        if (distance > interval)
            return true;
        else
            return false;
    }
}

インスペクタ画面でパラメータをセット。

下記のように、描いた線に衝突機能が追加されます。

リジッドボディ(rigidbody)

次に線に重力機能を追加します。まずはLineRendererの「UseWorldSpace」のチェックが外れているのを確認。

Rigidbody2Dをアタッチします。一応Simulatedのチェックを外しておきますが、ここはスクリプトで制御するのでどちらでもOK。

スクリプトを下記に変更して、パラメータをセットした後に、実行して思った通りに動作すれば完成。

using System.Collections.Generic;
using UnityEngine;

public class LineDraw : MonoBehaviour
{
    [SerializeField] private LineRenderer _rend;
    [SerializeField] private Camera _cam;
    [SerializeField] private EdgeCollider2D _collider;
    [SerializeField] private Rigidbody2D _rigidbody;

    private int posCount = 0;
    private float interval = 0.1f;

    private List<Vector2> _points = new List<Vector2>();
    private void Awake()
    {
        _rigidbody.simulated = false;
    }
    private void Update()
    {
        Vector2 mousePos = _cam.ScreenToWorldPoint(Input.mousePosition);

        if (Input.GetMouseButton(0))
            SetPosition(mousePos);
        else if (Input.GetMouseButtonUp(0))
        {
            _rigidbody.simulated = true;
            posCount = 0;
        }
    }

    private void SetPosition(Vector2 pos)
    {
        if (!PosCheck(pos)) return;

        posCount++;
        _rend.positionCount = posCount;
        _rend.SetPosition(posCount - 1, pos);

        _points.Add(pos);
        _collider.points = _points.ToArray();

    }

    private bool PosCheck(Vector2 pos)
    {
        if (posCount == 0) return true;

        float distance = Vector2.Distance(_rend.GetPosition(posCount - 1), pos);
        if (distance > interval)
            return true;
        else
            return false;
    }
}

下記がこの仕組みを利用して作成してあります。結構バグっぽいのもありますが・・・。

タイトルとURLをコピーしました