Last active
October 9, 2023 13:39
-
-
Save tsubaki/6438870 to your computer and use it in GitHub Desktop.
複雑な形状のmeshcollider向けのraycast。posListに概ね全部の接触の接触が入ってる。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
[ExecuteInEditMode] | |
public class MultiHitRay : MonoBehaviour | |
{ | |
[Range(0.1f, 30f)] | |
public float Length = 20; | |
public LayerMask Mask; | |
private List<Vector3> posList = new List<Vector3> (); | |
int rayCount = 0; | |
void Update () | |
{ | |
rayCount = 0; | |
posList.Clear (); | |
// 双方向Rayで大雑把な形状を取得 | |
RaycastHit[] foward = Physics.RaycastAll (transform.position, transform.forward, Length, Mask); | |
RaycastHit[] back = Physics.RaycastAll (transform.position + transform.forward * Length, transform.forward * -1, Length, Mask); | |
rayCount += 2; | |
// 外枠のポイント一覧を登録 | |
foreach (RaycastHit hit in foward) { | |
posList.Add (hit.point); | |
} | |
foreach (RaycastHit hit in back) { | |
posList.Add (hit.point); | |
} | |
// 内部のコライダーを取得 | |
foreach (RaycastHit hit in foward) { | |
foreach (RaycastHit hit2 in back) { | |
if (hit.collider == hit2.collider) { | |
float maxDistance = Vector3.Distance (hit.point, hit2.point); | |
// 正方向の外枠から逆方向の外枠までをチェック | |
{ | |
RaycastHit inMeshHit; | |
float distance = maxDistance; | |
Vector3 currentPoint = hit.point; | |
while (hit.collider.Raycast (new Ray (currentPoint + transform.forward, transform.forward), out inMeshHit, distance)) { | |
posList.Add (inMeshHit.point); | |
currentPoint = inMeshHit.point; | |
distance -= inMeshHit.distance; | |
rayCount ++; | |
} | |
} | |
// 逆方向の外枠から正方向の外枠までをチェック | |
{ | |
RaycastHit inMeshHit; | |
float distance = maxDistance; | |
Vector3 currentPoint = hit2.point; | |
while (hit.collider.Raycast (new Ray (currentPoint - transform.forward, transform.forward * -1), out inMeshHit, distance)) { | |
posList.Add (inMeshHit.point); | |
currentPoint = inMeshHit.point; | |
distance -= inMeshHit.distance; | |
rayCount ++; | |
} | |
} | |
} | |
} | |
} | |
} | |
void OnGUI () | |
{ | |
GUILayout.Label (string.Format ("point count{0} raycount:{1}", posList.Count, rayCount)); | |
} | |
void OnDrawGizmos () | |
{ | |
if (posList == null) { | |
return; | |
} | |
Gizmos.color = Color.white; | |
Gizmos.DrawSphere (transform.position, 0.1f); | |
Gizmos.DrawSphere (transform.position + transform.forward * Length, 0.1f); | |
Gizmos.DrawLine (transform.position, transform.position + transform.forward * Length); | |
Gizmos.color = Color.red; | |
foreach (Vector3 pos in posList) { | |
Gizmos.DrawSphere (pos, 0.1f); | |
} | |
Gizmos.color = Color.white; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment