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);// ビーム無し
}
}
}
マウス左ボタンを押している間だけビーム光線を出す。
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(); // ビーム光線の表示処理(オブジェクトを起点としてが向いている方向に)
}
}