Skip to content

Instantly share code, notes, and snippets.

@Flattan
Last active June 13, 2023 05:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Flattan/fb3ed34426f8975e2f0aa21141749b4d to your computer and use it in GitHub Desktop.
Save Flattan/fb3ed34426f8975e2f0aa21141749b4d to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LightBehaviour : MonoBehaviour
{
//プレイヤー
public Transform playerTransform;
//rayの角度間隔
private float rayInterval = 0.25f;
//rayの範囲の角度。10だったら,プレイヤーの向きを中心に+-10度の範囲ができる
private float rayRange = 30;
//rayの長さ
private float rayLong = 20;
//hit 用の list
private List<RaycastHit2D> hits = new List<RaycastHit2D>();
//一つ前のhit入れ
private RaycastHit2D lastHit;
//求めてる途中のVertices,Tringlesを入れる
private List<Vector3> pendingVertices = new List<Vector3>();
private List<int> pendingTriangles = new List<int>();
//決定済みのVertices,Tringlesを入れる
private Vector3[] myVertices;
private int[] triangles;
//決定済みの要素で作られるMesh入れ
private Mesh mesh;
//何個目のhitかを表す
private int currentNum = 0;
//自身にアタッチされているMeshFilter
public MeshFilter meshFilter;
//現在のフレームのrayの総数
private int currentRayAmount = 0;
//ray用
private float rayRad;
private Vector3 rayVec;
private void Update()
{
//---マウス方向にrayを飛ばす---
//rayを飛ばすべき角度の算出
Vector3 mousePosition = Input.mousePosition;
Vector3 dir = Camera.main.ScreenToWorldPoint(mousePosition) - this.playerTransform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
//フレームごとのrayの総数の初期化
this.currentRayAmount = 0;
//rayを実際に複数、扇状に飛ばす
for (float minAngle = angle - this.rayRange; minAngle < angle + this.rayRange; minAngle += this.rayInterval)
{
float rad = minAngle * Mathf.Deg2Rad;
Vector3 vec = new Vector3(Mathf.Cos(rad), Mathf.Sin(rad), 0);
this.hits.Add(Physics2D.Raycast(this.playerTransform.position, vec, this.rayLong));
this.currentRayAmount++;
}
//---hitsを参照してメッシュを更新する処理---
//求めている途中のVerticesの、要素番号0にプレイヤーの位置を代入しておく
this.pendingVertices.Add(this.playerTransform.position);
//hitsを参照してhitの情報から適切な処理を行う
foreach (RaycastHit2D hit in this.hits)
{
//今何本目のhitか
this.currentNum += 1;
//最初の要素でなく、最後の要素でもない
if (this.currentNum > 1 && this.currentNum < this.currentRayAmount)
{
if (hit.collider)
{
//現在参照しているhitは衝突していて、一つ前のhit(lastHit)も衝突していた場合
if (lastHit.collider)
{
// vertices に、hitの pos を入れ、trianglesに、その pos の要素番号を入れる
this.AddVerticesAndTriangles(hit.point);
// vertices に、lastHit の pos を入れ、trianglesに、その pos の要素番号を入れる
this.AddVerticesAndTriangles(lastHit.point);
//要素番号0は、プレイヤーの位置が入っている
this.pendingTriangles.Add(0);
}
//現在参照しているhitは衝突していて、一つ前のhit(lastHit)は衝突していなかった場合
else
{
//[一つ前のrayの先端位置],[現在のrayの先端位置],[プレイヤーの位置]を三角形作成用の情報として登録する
this.AddVerticesAndTriangles(this.pendingVertices[this.pendingVertices.Count - 1]);
this.rayRad = (angle - this.rayRange + this.rayInterval * (this.currentNum - 1)) * Mathf.Deg2Rad;
this.rayVec = new Vector3(Mathf.Cos(rayRad), Mathf.Sin(rayRad), 0);
this.AddVerticesAndTriangles(this.rayVec * this.rayLong + this.playerTransform.position);
//要素番号0は、プレイヤーの位置が入っている
this.pendingTriangles.Add(0);
}
}
else
{
//hitしなくて、一つ前もhitしていない
if (!lastHit.collider)
{
//[一つ前のrayの先端位置],[現在のrayの先端位置],[プレイヤーの位置]を三角形作成用の情報として登録する
this.AddVerticesAndTriangles(this.pendingVertices[this.pendingVertices.Count - 1]);
this.rayRad = (angle - this.rayRange + this.rayInterval * (this.currentNum - 1)) * Mathf.Deg2Rad;
this.rayVec = new Vector3(Mathf.Cos(rayRad), Mathf.Sin(rayRad), 0);
this.AddVerticesAndTriangles(this.rayVec * this.rayLong + this.playerTransform.position);
//要素番号0は、プレイヤーの位置が入っている
this.pendingTriangles.Add(0);
}
//hitしなくて、一つ前はhitした
else
{
//[一つ前のrayがhitしなかったとみなした際の、ray先端位置],[現在のrayの先端位置],[プレイヤーの位置]を三角形作成用の情報として登録する
this.rayRad = (angle - this.rayRange + this.rayInterval * (this.currentNum-2)) * Mathf.Deg2Rad;
this.rayVec = new Vector3(Mathf.Cos(rayRad), Mathf.Sin(rayRad), 0);
this.AddVerticesAndTriangles(this.rayVec * this.rayLong + this.playerTransform.position);
this.rayRad = (angle - this.rayRange + this.rayInterval * (this.currentNum-1)) * Mathf.Deg2Rad;
this.rayVec = new Vector3(Mathf.Cos(rayRad), Mathf.Sin(rayRad), 0);
this.AddVerticesAndTriangles(this.rayVec * this.rayLong + this.playerTransform.position);
//要素番号0は、プレイヤーの位置が入っている
this.pendingTriangles.Add(0);
}
}
}
//最後の要素であれば
else
{
if (hit.collider)
{
//現在参照しているhitは衝突していて、一つ前のhit(lastHit)も衝突していた場合
if (lastHit.collider)
{
// vertices に、次のhit の pos を入れ、trianglesに、その pos の要素番号を入れる
this.AddVerticesAndTriangles(this.hits[this.currentNum - 2].point);
// vertices に、hitの pos を入れ、trianglesに、その pos の要素番号を入れる
this.AddVerticesAndTriangles(hit.point);
//要素番号0は、プレイヤーの位置が入っている
this.pendingTriangles.Add(0);
}
}
//現在参照しているhitは衝突していて、一つ前のhit(lastHit)は衝突していなかった場合
else
{
//[一つ前のrayがhitしなかったとみなした際の、ray先端位置],[現在のrayの先端位置],[プレイヤーの位置]を三角形作成用の情報として登録する
this.rayRad = (angle - this.rayRange + this.rayInterval * (this.currentNum - 2)) * Mathf.Deg2Rad;
this.rayVec = new Vector3(Mathf.Cos(rayRad), Mathf.Sin(rayRad), 0);
this.AddVerticesAndTriangles(this.rayVec * this.rayLong + this.playerTransform.position);
this.rayRad = (angle - this.rayRange + this.rayInterval * (this.currentNum - 1)) * Mathf.Deg2Rad;
this.rayVec = new Vector3(Mathf.Cos(rayRad), Mathf.Sin(rayRad), 0);
this.AddVerticesAndTriangles(this.rayVec * this.rayLong + this.playerTransform.position);
//要素番号0は、プレイヤーの位置が入っている
this.pendingTriangles.Add(0);
}
//仕上げの表示処理
this.myVertices = this.pendingVertices.ToArray();
this.triangles = this.pendingTriangles.ToArray();
mesh = new Mesh();
this.mesh.SetVertices(this.myVertices);
this.mesh.SetTriangles(this.triangles, 0);
// MeshFilter に Mesh のオブジェクトを設定する
this.meshFilter.mesh = this.mesh;
}
  
//lastHit(一つ前のhit)の更新
this.lastHit = hit;
}
//各種更新処理
this.pendingTriangles.Clear();
this.pendingVertices.Clear();
this.hits.Clear();
this.currentNum = 0;
}
//位置の情報を渡したら三角形作成用の情報に変換して登録してくれる
private void AddVerticesAndTriangles(Vector3 pos)
{
this.pendingVertices.Add(pos);
this.pendingTriangles.Add(this.pendingVertices.Count - 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment