Skip to content

Instantly share code, notes, and snippets.

@tsubaki
Last active October 9, 2023 13:39
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsubaki/6438870 to your computer and use it in GitHub Desktop.
Save tsubaki/6438870 to your computer and use it in GitHub Desktop.
複雑な形状のmeshcollider向けのraycast。posListに概ね全部の接触の接触が入ってる。
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