TOP PAGE

ビーム光線を表示するためのクラス

シンプルなビーム光線を表示するためのクラス(ShotEffect.cs)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// ビーム光線を表示するためのクラス
// 使い方:コンストラクタで、ビーム光線の始点となるオブジェクトを指定します。
// ビームの発射方向は、コンストラクタで指定したオブジェクトが向く方法です。
// beamMaxDistanceの距離に進む時、衝突対象があれば、そこがビーム到達点になる。
// ビームが当たった処理のdelegate設定が可能
/* LineRendererを使って実装しようとしていが、Unityならではの手続きで、必ずGameObjectが必要となる。
 * 発光時はこのオブジェクトのSetPositionメソッドを始点と終点で使うことで発光できる。
 * しかし、一度発光させると自動では消えないで存在し続ける。
 * 頂点の数のpositionCountを1にすることで見えなくする技法を使う。
*/
public class ShotEffect
{
    LineRenderer lr;    // 線の発光に使うレンダー
    GameObject cannonObject;// 上記レンダーコンポーネントを設定するGameObject
    float beamMaxDistance = 500;// ビームが届く最大の距離

    public bool setBeam; // ビーム発光させる時にtrueを設定(UpdaateShotメソッドでリyプ)


    // 判定対象外にしたいレイヤーの名前
    string[] targetLayers = { "Ignore Raycast" };
    int layerMask;

    public delegate void DelegateHit(RaycastHit hit);//delegate型を定義
    public DelegateHit delegateHit;//ビームが当たった時処理する上位delegate型の変数

    public ShotEffect(GameObject gameobject)
    {
        this.cannonObject = gameobject;
        lr = gameobject.AddComponent<LineRenderer>();
        lr.positionCount = 1; // 始点だけの1個
        lr.startWidth = 0.505f;
        lr.endWidth = 0.505f;
        lr.material = new Material(Shader.Find("Unlit/Color"));
        // 上記シェーダーは、 [Edit] → [Project Settings] → [Graphics] を開き、
        //  [Always Included Shaders] セクションに追加しておく必要がある。
        lr.material.color = Color.cyan; // 線の色

        // LayerMask.GetMask を使用して、指定したレイヤーだけを含むマスクを作成
        this.layerMask = ~LayerMask.GetMask(targetLayers);

        this.delegateHit = defaultHit;// ビームが当たった時のデリゲート関数登録
        // Debug.Log($"{lr}");
    }

    // ビームが当たった時に実行するデフォルトdelegateメソッド
    public void defaultHit(RaycastHit hit)//GameObject hitObject, Vector3 hitPoint)
    {
        Debug.Log($"デフォルトの処理--当たりオブジェクト{hit.collider.gameObject.name}");
        UnityEngine.Object.Destroy(hit.collider.gameObject);
    }

    // 砲弾を発射する銃口は、英語で主にMuzzle(マズル)で、そのワールド座標を返す
    public Vector3 getMuzzle()
    {
        Vector3 retnVal = cannonObject.transform.position;
        //retnVal += new Vector3(0, 0, 10.5f); // 銃口の親からのオフセット
        return retnVal;
    }

    // ビーム発光イベント
    private void Shot(bool displayFlag = true)
    {
        Vector3 pos = getMuzzle();// ビーム発射の視点取得(銃口)
        if (displayFlag)
        {
            lr.positionCount = 2; // 始点と終点の2点
            lr.SetPosition(0, pos);// 始点はオブジェクトの位置

            //オブジェクトを起点としてが向いている方向のRay
            Ray ray = new Ray(this.cannonObject.transform.position, this.cannonObject.transform.forward);
            RaycastHit hit;
            float maxDistance = 100f; // Rayの最大距離

            // Raycastを実行
            if (Physics.Raycast(ray, out hit, maxDistance, this.layerMask))
            {
                // ビームが当たった処理
                lr.SetPosition(1, hit.point);// 光の衝突位置までビーム発光させる
                this.delegateHit(hit); // ビームにに当てた時の処理
            }
            else
            {
                Vector3 calculatedReachPoint = ray.GetPoint(maxDistance);
                lr.SetPosition(1, calculatedReachPoint);// 光の届く位置までビーム発光させる
            }
        }
        else
        {
            lr.positionCount = 1; // 始点の1つにすると消える
        }
    }

    // Updateで呼ぶ前提で、setBeamの状態でビームを表示する。
    public void UpdaateShot()
    {
        if (this.setBeam)
        {
            this.Shot(true);// ビーム発光
        }
        else
        {
            this.Shot(false);// ビーム無し
        }
    }
}

上記のShotEffectクラスの利用例

マウス左ボタンを押している間だけビーム光線を出す。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    [SerializeField] public GameObject cannonObject;// 銃のオブジェクト
    public static ShotEffect shotEffect; // ビーム発光用オブジェクト管理用

    void Start()
    {
        GameManager.shotEffect = new ShotEffect(this.cannonObject);// ビーム用
        //GameManager.shotEffect.delegateHit = this.Hitdelegate;// ビームが当たった時の処理を登録
        // (上記の登録を行わない場合の当たったデフォルト処理は、当たったオブジェクトを破棄)
    }

    void Update()
    {
        GameManager.shotEffect.setBeam = false;// ビーム無し状態の設定
        if (Input.GetMouseButton(0)) // 実験コード (マウス左ボタン)
        {
              GameManager.shotEffect.setBeam = true;// ビーム発光状態の設定
        }
        GameManager.shotEffect.UpdaateShot(); // ビーム光線の表示処理(オブジェクトを起点としてが向いている方向に)
    }
}