【Unity】反射するレーザーを作れる関数

# 概要
![gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/a1a79507-4486-52ef-439c-dde6e4b989ae.gif)
反射するレーザーを作れる関数を作りました。
実装は、Ray を打って RayCastHit から次の Ray の座標と方向を決める処理を繰り返す方法を取っています。
太いレーザーを作れるように SphereCast 版の関数も用意しています。
2D版の関数も用意しています。

# 使い方

LineRenderer で使用する際は useWorldSpace を有効にしてください。

``` LineRenderer で使う場合のサンプルコード（抜粋）.cs
void Update()
{
    var poses = PhysicsUtil.RefrectionLinePoses(transform.position, transform.forward, 50f, 1).ToArray();
    lineRenderer.positionCount = poses.Length;
    lineRenderer.SetPositions(poses);
    }
```

# コード

下記コードの関数をお手持ちの Utility クラスに追加してご利用ください。

``` PhysicsUtil.cs
using System.Collections.Generic;
using UnityEngine;

namespace Utility
{
    public class PhysicsUtil
    {
        public static List<Vector3> RefrectionLinePoses(Vector3 position, Vector3 direction, float length, LayerMask layerMask)
        {
            var points = new List<Vector3>() { position };
            while (Physics.Raycast(position, direction, out var hit, length, layerMask))
            {
                position = hit.point;
                points.Add(position);
                length -= hit.distance;
                direction = Vector3.Reflect(direction, hit.normal);
            }
            points.Add(position + direction * length);
            return points;
        }
        public static List<Vector3> RefrectionLinePoses(Vector3 position, float radius, Vector3 direction, float length, LayerMask layerMask)
        {
            var points = new List<Vector3>() { position };
            while (Physics.SphereCast(position, radius, direction, out var hit, length, layerMask))
            {
                position = hit.point + hit.normal * radius;
                points.Add(position);
                length -= hit.distance;
                direction = Vector3.Reflect(direction, hit.normal);
            }
            points.Add(position + direction * length);
            return points;
        }
    }
}

```

``` Physics2DUtil.cs
using System.Collections.Generic;
using UnityEngine;

namespace Utility
{
    public class Physics2DUtil
    {
        public static List<Vector2> RefrectionLinePoses(Vector2 position, Vector2 direction, float length, LayerMask layerMask)
        {
            var points = new List<Vector2>() { position };
            var hit = Physics2D.Raycast(position, direction, length, layerMask);
            while (hit)
            {
                position = hit.point;
                points.Add(position);
                length -= hit.distance;
                direction = Vector2.Reflect(direction, hit.normal);
                hit = Physics2D.Raycast(position, direction, length, layerMask);
            }
            points.Add(position + direction * length);
            return points;
        }
        public static List<Vector2> RefrectionLinePoses(Vector2 position, float radius, Vector2 direction, float length, LayerMask layerMask)
        {
            var points = new List<Vector2>() { position };
            var hit = Physics2D.CircleCast(position, radius, direction, length, layerMask);
            while (hit)
            {
                position = hit.point + hit.normal * radius;
                points.Add(position);
                length -= hit.distance;
                direction = Vector2.Reflect(direction, hit.normal);
                hit = Physics2D.CircleCast(position, radius, direction, length, layerMask);
            }
            points.Add(position + direction * length);
            return points;
        }
    }
}

```