LoginSignup
6
4

More than 1 year has passed since last update.

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

Posted at

概要

gif.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;
        }
    }
}

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4