Init
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 390693d164cfc554d86ed64d284ceb66
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,167 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!43 &4300000
|
||||
Mesh:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Cylinder
|
||||
serializedVersion: 11
|
||||
m_SubMeshes:
|
||||
- serializedVersion: 2
|
||||
firstByte: 0
|
||||
indexCount: 144
|
||||
topology: 0
|
||||
baseVertex: 0
|
||||
firstVertex: 0
|
||||
vertexCount: 50
|
||||
localAABB:
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
m_Extent: {x: 1, y: 0.5, z: 1}
|
||||
m_Shapes:
|
||||
vertices: []
|
||||
shapes: []
|
||||
channels: []
|
||||
fullWeights: []
|
||||
m_BindPose: []
|
||||
m_BoneNameHashes:
|
||||
m_RootBoneNameHash: 0
|
||||
m_BonesAABB: []
|
||||
m_VariableBoneCountWeights:
|
||||
m_Data:
|
||||
m_MeshCompression: 0
|
||||
m_IsReadable: 1
|
||||
m_KeepVertices: 1
|
||||
m_KeepIndices: 1
|
||||
m_IndexFormat: 0
|
||||
m_IndexBuffer: 00000300010000000200030002000500030002000400050004000700050004000600070006000900070006000800090008000b00090008000a000b000a000d000b000a000c000d000c000f000d000c000e000f000e0011000f000e001000110010001300110010001200130012001500130012001400150014001700150014001600170016001900170016001800190018001b00190018001a001b001a001d001b001a001c001d001c001f001d001c001e001f001e0021001f001e002000210020002300210020002200230022002500230022002400250024002700250024002600270026002900270026002800290028002b00290028002a002b002a002d002b002a002c002d002c002f002d002c002e002f002e0031002f002e0030003100
|
||||
m_VertexData:
|
||||
serializedVersion: 3
|
||||
m_VertexCount: 50
|
||||
m_Channels:
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 3
|
||||
- stream: 0
|
||||
offset: 12
|
||||
format: 0
|
||||
dimension: 3
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
- stream: 0
|
||||
offset: 0
|
||||
format: 0
|
||||
dimension: 0
|
||||
m_DataSize: 1200
|
||||
_typelessdata: 0000803f000000bf0000000054cf7dbf00000000aca805be0000803f0000003f0000000054cf7dbf00000000aca805beea46773f000000bfee83843e682274bf00000000f7119abeea46773f0000003fee83843eb2f179bf0000000056695dbed7b35d3f000000bf0000003fa8e057bf00000000c89809bfd7b35d3f0000003f0000003fe21963bf000000006a50ecbef304353f000000bff304353fb7e82cbf0000000011c83cbff304353f0000003ff304353f11c83cbf00000000b6e82cbfffffff3e000000bfd8b35d3f6950ecbe00000000e31963bfffffff3e0000003fd8b35d3fc99809bf00000000a7e057bfef83843e000000bfea46773f4e695dbe00000000b1f179bfef83843e0000003fea46773ff3119abe00000000682274bf2ebd3bb3000000bf0000803fa593333d00000000fcc07fbf2ebd3bb30000003f0000803fa59333bd00000000fcc07fbff28384be000000bfea46773ff7119a3e00000000662274bff28384be0000003fea46773f54695d3e00000000b2f179bf010000bf000000bfd7b35d3fca98093f00000000a7e057bf010000bf0000003fd7b35d3f6d50ec3e00000000e11963bff30435bf000000bff304353f12c83c3f00000000b8e82cbff30435bf0000003ff304353fb8e82c3f0000000012c83cbfd7b35dbf000000bf0100003fe219633f000000006850ecbed7b35dbf0000003f0100003fa7e0573f00000000c89809bfeb4677bf000000bfea83843eb1f1793f000000004e695dbeeb4677bf0000003fea83843e6722743f00000000f5119abe000080bf000000bf2ebdbbb3fcc07f3f00000000bf93333d000080bf0000003f2ebdbbb3fec07f3f00000000829333bdea4677bf000000bfef8384be6522743f00000000fc119a3eea4677bf0000003fef8384beb1f1793f000000005e695d3ed5b35dbf000000bf030000bfa7e0573f00000000c998093fd5b35dbf0000003f030000bfe119633f000000006d50ec3ef10435bf000000bff50435bfb6e82c3f0000000014c83c3ff10435bf0000003ff50435bf11c83c3f00000000b8e82c3ffdffffbe000000bfd8b35dbf6950ec3e00000000e319633ffdffffbe0000003fd8b35dbfc798093f00000000a9e0573fec8384be000000bfeb4677bf4f695d3e00000000b2f1793fec8384be0000003feb4677bff6119a3e000000006822743f2ede4c32000000bf000080bfbf9333bd00000000fcc07f3f2ede4c320000003f000080bf8293333d00000000fcc07f3fed83843e000000bfea4677bff5119abe000000006822743fed83843e0000003fea4677bf54695dbe00000000b3f1793ffdffff3e000000bfd8b35dbfcb9809bf00000000a6e0573ffdffff3e0000003fd8b35dbf6d50ecbe00000000e219633ff704353f000000bfef0435bf14c83cbf00000000b6e82c3ff704353f0000003fef0435bfb7e82cbf0000000011c83c3fdab35d3f000000bff8ffffbee51963bf000000006150ec3edab35d3f0000003ff8ffffbeabe057bf00000000c698093feb46773f000000bfe78384beb3f179bf0000000043695d3eeb46773f0000003fe78384be692274bf00000000ec119a3e0000803f000000bf2ebd3b3455cf7dbf000000009ea8053e0000803f0000003f2ebd3b3455cf7dbf000000009ea8053e
|
||||
m_CompressedMesh:
|
||||
m_Vertices:
|
||||
m_NumItems: 0
|
||||
m_Range: 0
|
||||
m_Start: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_UV:
|
||||
m_NumItems: 0
|
||||
m_Range: 0
|
||||
m_Start: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_Normals:
|
||||
m_NumItems: 0
|
||||
m_Range: 0
|
||||
m_Start: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_Tangents:
|
||||
m_NumItems: 0
|
||||
m_Range: 0
|
||||
m_Start: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_Weights:
|
||||
m_NumItems: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_NormalSigns:
|
||||
m_NumItems: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_TangentSigns:
|
||||
m_NumItems: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_FloatColors:
|
||||
m_NumItems: 0
|
||||
m_Range: 0
|
||||
m_Start: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_BoneIndices:
|
||||
m_NumItems: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_Triangles:
|
||||
m_NumItems: 0
|
||||
m_Data:
|
||||
m_BitSize: 0
|
||||
m_UVInfo: 0
|
||||
m_LocalAABB:
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
m_Extent: {x: 1, y: 0.5, z: 1}
|
||||
m_MeshUsageFlags: 0
|
||||
m_CookingOptions: 30
|
||||
m_BakedConvexCollisionMesh:
|
||||
m_BakedTriangleCollisionMesh:
|
||||
'm_MeshMetrics[0]': 1
|
||||
'm_MeshMetrics[1]': 1
|
||||
m_MeshOptimizationFlags: 1
|
||||
m_StreamData:
|
||||
serializedVersion: 2
|
||||
offset: 0
|
||||
size: 0
|
||||
path:
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3554d6a17caef8148b1220e9e2e79454
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 4300000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 318546
|
||||
packageName: Collider Visualizer
|
||||
packageVersion: 1.0.0
|
||||
assetPath: Assets/ColliderVisualizer/Meshes/Cylinder.mesh
|
||||
uploadId: 752951
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2150e3d3605f3f54087ca225c7af31aa
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 4300000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 318546
|
||||
packageName: Collider Visualizer
|
||||
packageVersion: 1.0.0
|
||||
assetPath: Assets/ColliderVisualizer/Meshes/LowerHalfSphere.mesh
|
||||
uploadId: 752951
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea110afe4078082468955a8ec59d1ee0
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 4300000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 318546
|
||||
packageName: Collider Visualizer
|
||||
packageVersion: 1.0.0
|
||||
assetPath: Assets/ColliderVisualizer/Meshes/UpperHalfSphere.mesh
|
||||
uploadId: 752951
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72dfab8be846ad645b03d0bebd460d8b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,631 @@
|
||||
namespace ColliderVisualizer
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Collider visualizer.
|
||||
/// </summary>
|
||||
[ExecuteAlways]
|
||||
[RequireComponent(typeof(Collider))]
|
||||
public class ColliderVisualizer : MonoBehaviour
|
||||
{
|
||||
private static readonly int ColorPropertyID = Shader.PropertyToID("_Color");
|
||||
|
||||
private static readonly int[,] BoxEdges =
|
||||
{
|
||||
{ 0, 1 }, { 1, 3 }, { 3, 2 }, { 2, 0 },
|
||||
{ 4, 5 }, { 5, 7 }, { 7, 6 }, { 6, 4 },
|
||||
{ 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The need to draw the collider fill has changed.
|
||||
/// </summary>
|
||||
public event Action onNeedDrawSolidChanged = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// The need to draw collider boundaries has changed.
|
||||
/// </summary>
|
||||
public event Action onNeedDrawWireChanged = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// The fill color has changed.
|
||||
/// </summary>
|
||||
public event Action onSolidColorChanged = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// The border color has changed.
|
||||
/// </summary>
|
||||
public event Action onWireColorChanged = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Need to draw a fill.
|
||||
/// </summary>
|
||||
public bool NeedDrawSolid
|
||||
{
|
||||
get => drawSolid;
|
||||
|
||||
set
|
||||
{
|
||||
if (drawSolid != value)
|
||||
{
|
||||
drawSolid = value;
|
||||
onNeedDrawSolidChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// You need to draw boundaries.
|
||||
/// </summary>
|
||||
public bool NeedDrawWire
|
||||
{
|
||||
get => drawWire;
|
||||
|
||||
set
|
||||
{
|
||||
if (drawWire != value)
|
||||
{
|
||||
drawWire = value;
|
||||
onNeedDrawWireChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill color.
|
||||
/// </summary>
|
||||
public Color SolidColor
|
||||
{
|
||||
get => solidColor;
|
||||
|
||||
set
|
||||
{
|
||||
if (solidColor != value)
|
||||
{
|
||||
solidColor = value;
|
||||
onSolidColorChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Border color.
|
||||
/// </summary>
|
||||
public Color WireColor
|
||||
{
|
||||
get => wireColor;
|
||||
|
||||
set
|
||||
{
|
||||
if (wireColor != value)
|
||||
{
|
||||
wireColor = value;
|
||||
onWireColorChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Rendering")] [SerializeField] private bool drawSolid = true;
|
||||
[SerializeField] private bool drawWire = true;
|
||||
|
||||
[SerializeField] private Color solidColor = new Color(0f, 1f, 0f, 0.15f);
|
||||
[SerializeField] private Color wireColor = Color.green;
|
||||
|
||||
[Header("Wire Quality")]
|
||||
[SerializeField, Range(3, 64)] private int wireSegments = 24;
|
||||
|
||||
[SerializeField, HideInInspector, Range(0, 100000)] private int maxMeshTriangles = 0; // 0 = without limit
|
||||
[SerializeField, Range(2, 32)] private int capsuleArcSegments = 8;
|
||||
|
||||
[SerializeField, HideInInspector] private Mesh meshBox;
|
||||
[SerializeField, HideInInspector] private Mesh meshSphere;
|
||||
|
||||
[SerializeField, HideInInspector] private Mesh meshCylinder;
|
||||
[SerializeField, HideInInspector] private Mesh upperHalfSphere;
|
||||
[SerializeField, HideInInspector] private Mesh lowerHalfSphere;
|
||||
|
||||
[SerializeField, HideInInspector] private Shader coloredShader;
|
||||
|
||||
private Material solidMat;
|
||||
private Material wireMat;
|
||||
|
||||
private Collider col;
|
||||
|
||||
private Transform _transform;
|
||||
|
||||
private void Start() => Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the component.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
col = GetComponent<Collider>();
|
||||
if (col == null) return;
|
||||
|
||||
_transform = transform;
|
||||
|
||||
RemoveMaterials();
|
||||
|
||||
solidMat = new Material(coloredShader);
|
||||
wireMat = new Material(coloredShader);
|
||||
}
|
||||
|
||||
private void OnRenderObject()
|
||||
{
|
||||
if (!enabled || col == null) return;
|
||||
|
||||
if (drawSolid)
|
||||
{
|
||||
solidMat.SetColor(ColorPropertyID, solidColor);
|
||||
solidMat.SetPass(0);
|
||||
DrawSolid(col);
|
||||
}
|
||||
|
||||
if (drawWire)
|
||||
{
|
||||
wireMat.SetColor(ColorPropertyID, wireColor);
|
||||
wireMat.SetPass(0);
|
||||
|
||||
if (col is SphereCollider or CapsuleCollider)
|
||||
{
|
||||
GL.Begin(GL.LINES);
|
||||
GL.Color(wireColor);
|
||||
DrawWire(col);
|
||||
GL.End();
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.PushMatrix();
|
||||
GL.MultMatrix(transform.localToWorldMatrix);
|
||||
GL.Begin(GL.LINES);
|
||||
GL.Color(wireColor);
|
||||
DrawWire(col);
|
||||
GL.End();
|
||||
GL.PopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
RemoveMaterials();
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveMaterials()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (solidMat != null)
|
||||
{
|
||||
DestroyImmediate(solidMat);
|
||||
}
|
||||
|
||||
if (wireMat != null)
|
||||
{
|
||||
DestroyImmediate(wireMat);
|
||||
}
|
||||
#else
|
||||
if (solidMat != null)
|
||||
{
|
||||
Destroy(solidMat);
|
||||
}
|
||||
|
||||
if (wireMat != null)
|
||||
{
|
||||
Destroy(wireMat);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void DrawSolid(Collider collider)
|
||||
{
|
||||
switch (collider)
|
||||
{
|
||||
case BoxCollider box:
|
||||
Graphics.DrawMeshNow(meshBox,
|
||||
Matrix4x4.TRS(_transform.position + _transform.rotation * Vector3.Scale(box.center, _transform.lossyScale), _transform.rotation, Vector3.Scale(box.size, _transform.lossyScale)));
|
||||
break;
|
||||
|
||||
case SphereCollider sphere:
|
||||
float scaledRadius = sphere.radius * MaxAbsAxis(_transform.lossyScale);
|
||||
Graphics.DrawMeshNow(meshSphere,
|
||||
Matrix4x4.TRS(_transform.position + _transform.rotation * Vector3.Scale(sphere.center, _transform.lossyScale), _transform.rotation, Vector3.one * scaledRadius * 2f));
|
||||
break;
|
||||
|
||||
case CapsuleCollider capsule:
|
||||
DrawCapsuleSolid(capsule);
|
||||
break;
|
||||
|
||||
case MeshCollider meshCol:
|
||||
if (meshCol.sharedMesh != null)
|
||||
Graphics.DrawMeshNow(meshCol.sharedMesh, _transform.localToWorldMatrix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWire(Collider collider)
|
||||
{
|
||||
switch (collider)
|
||||
{
|
||||
case BoxCollider box:
|
||||
DrawWireCube(box.center, box.size);
|
||||
break;
|
||||
|
||||
case SphereCollider sphere:
|
||||
DrawWireSphere(sphere);
|
||||
break;
|
||||
|
||||
case CapsuleCollider capsule:
|
||||
DrawWireCapsule(capsule);
|
||||
break;
|
||||
|
||||
case MeshCollider meshCol:
|
||||
DrawWireMesh(meshCol);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private float MaxAbsAxis(Vector3 v) =>
|
||||
Mathf.Max(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z));
|
||||
|
||||
#region Box
|
||||
|
||||
private void DrawWireCube(Vector3 center, Vector3 size)
|
||||
{
|
||||
Vector3 half = size * 0.5f;
|
||||
Vector3[] pts = new Vector3[8];
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
pts[i] = new Vector3(
|
||||
((i & 1) == 0 ? -1 : 1) * half.x,
|
||||
((i & 2) == 0 ? -1 : 1) * half.y,
|
||||
((i & 4) == 0 ? -1 : 1) * half.z
|
||||
) + center;
|
||||
}
|
||||
|
||||
for (int i = 0; i < BoxEdges.GetLength(0); i++)
|
||||
{
|
||||
GL.Vertex(pts[BoxEdges[i, 0]]);
|
||||
GL.Vertex(pts[BoxEdges[i, 1]]);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sphere
|
||||
|
||||
private void DrawWireSphere(SphereCollider sphere)
|
||||
{
|
||||
float scaledRadius = sphere.radius * MaxAbsAxis(transform.lossyScale);
|
||||
float angleStep = 360f / wireSegments;
|
||||
|
||||
for (int i = 0; i < wireSegments; i++)
|
||||
{
|
||||
float a0 = Mathf.Deg2Rad * i * angleStep;
|
||||
float a1 = Mathf.Deg2Rad * (i + 1) * angleStep;
|
||||
|
||||
Vector3 c = _transform.TransformPoint(sphere.center);
|
||||
|
||||
// XY
|
||||
Vector3 p0 = c + _transform.rotation * new Vector3(Mathf.Cos(a0), Mathf.Sin(a0), 0) * scaledRadius;
|
||||
Vector3 p1 = c + _transform.rotation * new Vector3(Mathf.Cos(a1), Mathf.Sin(a1), 0) * scaledRadius;
|
||||
GL.Vertex(p0);
|
||||
GL.Vertex(p1);
|
||||
|
||||
// XZ
|
||||
p0 = c + _transform.rotation * new Vector3(Mathf.Cos(a0), 0, Mathf.Sin(a0)) * scaledRadius;
|
||||
p1 = c + _transform.rotation * new Vector3(Mathf.Cos(a1), 0, Mathf.Sin(a1)) * scaledRadius;
|
||||
GL.Vertex(p0);
|
||||
GL.Vertex(p1);
|
||||
|
||||
// YZ
|
||||
p0 = c + _transform.rotation * new Vector3(0, Mathf.Cos(a0), Mathf.Sin(a0)) * scaledRadius;
|
||||
p1 = c + _transform.rotation * new Vector3(0, Mathf.Cos(a1), Mathf.Sin(a1)) * scaledRadius;
|
||||
GL.Vertex(p0);
|
||||
GL.Vertex(p1);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Capsule
|
||||
|
||||
private void DrawCapsuleSolid(CapsuleCollider capsule)
|
||||
{
|
||||
float radius = capsule.radius;
|
||||
float height = capsule.height;
|
||||
Vector3 center = capsule.center;
|
||||
|
||||
float cylinderHeight = Mathf.Max(0f, height - 2f * radius);
|
||||
|
||||
Quaternion rotation = transform.rotation;
|
||||
Vector3 up = Vector3.up;
|
||||
|
||||
Vector3 lossyScale = transform.lossyScale;
|
||||
float heightScale = 1f;
|
||||
float radiusScale = 1f;
|
||||
|
||||
switch (capsule.direction)
|
||||
{
|
||||
case 0: // X-axis
|
||||
up = Vector3.right;
|
||||
rotation *= Quaternion.Euler(0, 0, -90);
|
||||
|
||||
heightScale = lossyScale.x;
|
||||
radiusScale = Mathf.Max(lossyScale.y, lossyScale.z);
|
||||
break;
|
||||
|
||||
case 1: // Y-axis
|
||||
up = Vector3.up;
|
||||
|
||||
heightScale = lossyScale.y;
|
||||
radiusScale = Mathf.Max(lossyScale.x, lossyScale.z);
|
||||
break;
|
||||
|
||||
case 2: // Z-axis
|
||||
up = Vector3.forward;
|
||||
rotation *= Quaternion.Euler(90, 0, 0);
|
||||
|
||||
heightScale = lossyScale.z;
|
||||
radiusScale = Mathf.Max(lossyScale.x, lossyScale.y);
|
||||
break;
|
||||
}
|
||||
|
||||
Vector3 worldCenter = transform.TransformPoint(center);
|
||||
Vector3 worldUp = transform.TransformDirection(up);
|
||||
|
||||
float scaledRadius = radius * radiusScale;
|
||||
float scaledHeight = (height * heightScale) - 2f * scaledRadius;
|
||||
scaledHeight = Mathf.Max(0f, scaledHeight);
|
||||
|
||||
Vector3 top = worldCenter + worldUp * (scaledHeight * 0.5f);
|
||||
Vector3 bottom = worldCenter - worldUp * (scaledHeight * 0.5f);
|
||||
|
||||
Vector3 cylinderScale = new Vector3(scaledRadius, scaledHeight, scaledRadius);
|
||||
Vector3 sphereScale = Vector3.one * scaledRadius;
|
||||
|
||||
Graphics.DrawMeshNow(meshCylinder, Matrix4x4.TRS(worldCenter, rotation, cylinderScale));
|
||||
Graphics.DrawMeshNow(upperHalfSphere, Matrix4x4.TRS(top, rotation, sphereScale));
|
||||
Graphics.DrawMeshNow(lowerHalfSphere, Matrix4x4.TRS(bottom, rotation, sphereScale));
|
||||
}
|
||||
|
||||
|
||||
private void DrawWireCapsule(CapsuleCollider capsule)
|
||||
{
|
||||
Vector3 center = capsule.center;
|
||||
float radius = capsule.radius;
|
||||
float height = capsule.height;
|
||||
|
||||
Vector3 up = Vector3.up;
|
||||
Vector3 right = Vector3.right;
|
||||
Vector3 forward = Vector3.forward;
|
||||
Quaternion rotation = transform.rotation;
|
||||
Vector3 scale = transform.lossyScale;
|
||||
Vector3 position = transform.position;
|
||||
|
||||
switch (capsule.direction)
|
||||
{
|
||||
case 0:
|
||||
up = Vector3.right;
|
||||
right = Vector3.up;
|
||||
forward = Vector3.forward;
|
||||
break;
|
||||
case 1:
|
||||
up = Vector3.up;
|
||||
right = Vector3.right;
|
||||
forward = Vector3.forward;
|
||||
break;
|
||||
case 2:
|
||||
up = Vector3.forward;
|
||||
right = Vector3.right;
|
||||
forward = Vector3.up;
|
||||
break;
|
||||
}
|
||||
|
||||
float heightScale = Mathf.Abs(Vector3.Dot(scale, up));
|
||||
float radiusScale = Mathf.Max(
|
||||
Mathf.Abs(Vector3.Dot(scale, right)),
|
||||
Mathf.Abs(Vector3.Dot(scale, forward))
|
||||
);
|
||||
|
||||
float scaledRadius = radius * radiusScale;
|
||||
float scaledHeight = height * heightScale;
|
||||
float cylinderHeight = Mathf.Max(0f, scaledHeight - 2f * scaledRadius);
|
||||
|
||||
Vector3 worldCenter = position + rotation * Vector3.Scale(center, scale);
|
||||
Vector3 worldUp = rotation * up;
|
||||
Vector3 worldRight = rotation * right;
|
||||
Vector3 worldForward = rotation * forward;
|
||||
|
||||
Vector3 top = worldCenter + worldUp * (cylinderHeight * 0.5f);
|
||||
Vector3 bottom = worldCenter - worldUp * (cylinderHeight * 0.5f);
|
||||
|
||||
DrawWireCapsuleBody(top, bottom, worldUp, worldRight, worldForward, scaledRadius);
|
||||
DrawWireCapsuleCap(top, worldUp, worldRight, worldForward, scaledRadius, true);
|
||||
DrawWireCapsuleCap(bottom, worldUp, worldRight, worldForward, scaledRadius, false);
|
||||
}
|
||||
private void DrawWireCapsuleBody(Vector3 top, Vector3 bottom, Vector3 up, Vector3 right, Vector3 forward, float radius)
|
||||
{
|
||||
float angleStep = 360f / wireSegments;
|
||||
|
||||
for (int i = 0; i < wireSegments; i++)
|
||||
{
|
||||
float angle0 = Mathf.Deg2Rad * i * angleStep;
|
||||
float angle1 = Mathf.Deg2Rad * (i + 1) * angleStep;
|
||||
|
||||
Vector3 dir0 = (right * Mathf.Cos(angle0) + forward * Mathf.Sin(angle0)) * radius;
|
||||
Vector3 dir1 = (right * Mathf.Cos(angle1) + forward * Mathf.Sin(angle1)) * radius;
|
||||
|
||||
GL.Vertex(top + dir0);
|
||||
GL.Vertex(bottom + dir0);
|
||||
|
||||
GL.Vertex(top + dir0);
|
||||
GL.Vertex(top + dir1);
|
||||
|
||||
GL.Vertex(bottom + dir0);
|
||||
GL.Vertex(bottom + dir1);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWireCapsuleCap(Vector3 center, Vector3 up, Vector3 right, Vector3 forward, float radius, bool isTop)
|
||||
{
|
||||
int arcSegments = capsuleArcSegments;
|
||||
float arcStep = 90f / arcSegments;
|
||||
|
||||
for (int i = 0; i < 360; i += 360 / wireSegments)
|
||||
{
|
||||
float rad = Mathf.Deg2Rad * i;
|
||||
Vector3 baseDir = (right * Mathf.Cos(rad) + forward * Mathf.Sin(rad)).normalized;
|
||||
|
||||
Vector3 from = baseDir * radius;
|
||||
|
||||
Vector3 axis = Vector3.Cross(baseDir, up).normalized;
|
||||
if (!isTop)
|
||||
axis = -axis;
|
||||
|
||||
Quaternion rot = Quaternion.AngleAxis(arcStep, axis);
|
||||
|
||||
for (int j = 0; j < arcSegments; j++)
|
||||
{
|
||||
Vector3 to = rot * from;
|
||||
GL.Vertex(center + from);
|
||||
GL.Vertex(center + to);
|
||||
from = to;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Mesh GenerateHalfSphereMesh(bool upper = true, int longitude = 24, int latitude = 12)
|
||||
{
|
||||
Mesh mesh = new Mesh();
|
||||
mesh.name = upper ? "UpperHalfSphere" : "LowerHalfSphere";
|
||||
|
||||
List<Vector3> vertices = new();
|
||||
List<int> triangles = new();
|
||||
|
||||
int latStart = upper ? 0 : latitude / 2;
|
||||
int latEnd = upper ? latitude / 2 : latitude;
|
||||
|
||||
for (int lat = latStart; lat <= latEnd; lat++)
|
||||
{
|
||||
float a1 = Mathf.PI * lat / latitude;
|
||||
float sin1 = Mathf.Sin(a1);
|
||||
float cos1 = Mathf.Cos(a1);
|
||||
|
||||
for (int lon = 0; lon <= longitude; lon++)
|
||||
{
|
||||
float a2 = 2f * Mathf.PI * lon / longitude;
|
||||
float sin2 = Mathf.Sin(a2);
|
||||
float cos2 = Mathf.Cos(a2);
|
||||
|
||||
Vector3 vertex = new Vector3(sin1 * cos2, cos1, sin1 * sin2);
|
||||
vertices.Add(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
int vertsPerRow = longitude + 1;
|
||||
for (int lat = 0; lat < (latEnd - latStart); lat++)
|
||||
{
|
||||
for (int lon = 0; lon < longitude; lon++)
|
||||
{
|
||||
int current = lat * vertsPerRow + lon;
|
||||
int next = current + vertsPerRow;
|
||||
|
||||
triangles.Add(current);
|
||||
triangles.Add(next);
|
||||
triangles.Add(current + 1);
|
||||
|
||||
triangles.Add(current + 1);
|
||||
triangles.Add(next);
|
||||
triangles.Add(next + 1);
|
||||
}
|
||||
}
|
||||
|
||||
mesh.SetVertices(vertices);
|
||||
mesh.SetTriangles(triangles, 0);
|
||||
mesh.RecalculateNormals();
|
||||
mesh.RecalculateBounds();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private Mesh GenerateOpenCylinder(int segments = 24)
|
||||
{
|
||||
Mesh mesh = new Mesh();
|
||||
mesh.name = "OpenCylinder";
|
||||
|
||||
List<Vector3> vertices = new();
|
||||
List<int> triangles = new();
|
||||
|
||||
for (int i = 0; i <= segments; i++)
|
||||
{
|
||||
float angle = 2f * Mathf.PI * i / segments;
|
||||
float x = Mathf.Cos(angle);
|
||||
float z = Mathf.Sin(angle);
|
||||
|
||||
vertices.Add(new Vector3(x, -0.5f, z));
|
||||
vertices.Add(new Vector3(x, 0.5f, z));
|
||||
}
|
||||
|
||||
for (int i = 0; i < segments; i++)
|
||||
{
|
||||
int baseIndex = i * 2;
|
||||
|
||||
triangles.Add(baseIndex);
|
||||
triangles.Add(baseIndex + 3);
|
||||
triangles.Add(baseIndex + 1);
|
||||
|
||||
triangles.Add(baseIndex);
|
||||
triangles.Add(baseIndex + 2);
|
||||
triangles.Add(baseIndex + 3);
|
||||
}
|
||||
|
||||
mesh.SetVertices(vertices);
|
||||
mesh.SetTriangles(triangles, 0);
|
||||
mesh.RecalculateNormals();
|
||||
mesh.RecalculateBounds();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mesh
|
||||
|
||||
private void DrawWireMesh(MeshCollider meshCollider)
|
||||
{
|
||||
var mesh = meshCollider.sharedMesh;
|
||||
if (mesh == null) return;
|
||||
|
||||
var vertices = mesh.vertices;
|
||||
var triangles = mesh.triangles;
|
||||
int triangleCount = triangles.Length / 3;
|
||||
|
||||
if (maxMeshTriangles > 0 && triangleCount > maxMeshTriangles)
|
||||
triangleCount = maxMeshTriangles;
|
||||
|
||||
for (int i = 0; i < triangleCount * 3; i += 3)
|
||||
{
|
||||
int i0 = triangles[i];
|
||||
int i1 = triangles[i + 1];
|
||||
int i2 = triangles[i + 2];
|
||||
|
||||
GL.Vertex(vertices[i0]);
|
||||
GL.Vertex(vertices[i1]);
|
||||
|
||||
GL.Vertex(vertices[i1]);
|
||||
GL.Vertex(vertices[i2]);
|
||||
|
||||
GL.Vertex(vertices[i2]);
|
||||
GL.Vertex(vertices[i0]);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0de9c2653c954307856264ec248eab4d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- meshBox: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
- meshSphere: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
|
||||
- meshCylinder: {fileID: 4300000, guid: 3554d6a17caef8148b1220e9e2e79454, type: 2}
|
||||
- upperHalfSphere: {fileID: 4300000, guid: ea110afe4078082468955a8ec59d1ee0, type: 2}
|
||||
- lowerHalfSphere: {fileID: 4300000, guid: 2150e3d3605f3f54087ca225c7af31aa, type: 2}
|
||||
- coloredShader: {fileID: 4800000, guid: 38859b428448107418ad51fa96d642e7, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 318546
|
||||
packageName: Collider Visualizer
|
||||
packageVersion: 1.0.0
|
||||
assetPath: Assets/ColliderVisualizer/Scripts/ColliderVisualizer.cs
|
||||
uploadId: 752951
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a585ee9d00f3614a9797391c5eb902d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace ColliderVisualizer.Editor
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Rendering the <see cref="ColliderVisualizer"/> component in the Inspector.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(ColliderVisualizer))]
|
||||
public class ColliderVisualizerEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (GUILayout.Button("Reinitialize"))
|
||||
{
|
||||
((ColliderVisualizer)target).Initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b96329cd891b4003b1ad8561043f743e
|
||||
timeCreated: 1745442290
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 318546
|
||||
packageName: Collider Visualizer
|
||||
packageVersion: 1.0.0
|
||||
assetPath: Assets/ColliderVisualizer/Scripts/Editor/ColliderVisualizerEditor.cs
|
||||
uploadId: 752951
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6042617990f969344bd70fc3314adfa7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
Shader "ColliderVisualizer/SolidAndWire"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_Color ("Color", Color) = (0, 1, 0, 0.15)
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
|
||||
LOD 100
|
||||
|
||||
Pass
|
||||
{
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ZWrite Off
|
||||
Cull Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
fixed4 _Color;
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
};
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
return _Color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38859b428448107418ad51fa96d642e7
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 318546
|
||||
packageName: Collider Visualizer
|
||||
packageVersion: 1.0.0
|
||||
assetPath: Assets/ColliderVisualizer/Shaders/SolidAndWireShader.shader
|
||||
uploadId: 752951
|
||||
Reference in New Issue
Block a user