Kasper Karlgren c84494a697 new files
2025-01-21 13:54:40 +01:00

200 lines
6.1 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace DistantLands.Cozy
{
[ExecuteAlways]
public class CustomCollisionShape : MonoBehaviour
{
public MeshCollider trigger;
public Color displayColor = new Color(1, 1, 1, 1);
public List<Vector3> bounds = new List<Vector3>() { new Vector3(-5, 0, 5), new Vector3(5, 0, 5), new Vector3(5, 0, -5), new Vector3(-5, 0, -5) };
public float height = 10;
void OnEnable()
{
if (!trigger)
CheckTrigger();
}
void OnDisable()
{
if (trigger.gameObject.activeInHierarchy)
DestroyImmediate(trigger);
}
public void CheckTrigger()
{
trigger = gameObject.AddComponent<MeshCollider>();
trigger.sharedMesh = BuildZoneCollider();
trigger.convex = true;
trigger.isTrigger = true;
}
public Mesh BuildZoneCollider()
{
Mesh mesh = new Mesh();
mesh.name = $"{name} Custom Trigger Mesh";
List<Vector3> verts = new List<Vector3>();
List<int> tris = new List<int>();
foreach (Vector3 i in bounds)
{
verts.Add(i);
verts.Add(new Vector3(i.x, height, i.z));
}
for (int i = 0; i < bounds.Count; i++)
{
if (i == 0)
{
tris.Add(0);
tris.Add(verts.Count - 1);
tris.Add(verts.Count - 2);
tris.Add(0);
tris.Add(1);
tris.Add(verts.Count - 1);
}
else
{
int start = i * 2;
tris.Add(start);
tris.Add(start - 1);
tris.Add(start - 2);
tris.Add(start);
tris.Add(start + 1);
tris.Add(start - 1);
}
}
for (int i = 0; i < verts.Count - 4; i += 2)
{
tris.Add(0);
tris.Add(i + 2);
tris.Add(i + 4);
tris.Add(1);
tris.Add(i + 3);
tris.Add(i + 5);
}
mesh.SetVertices(verts);
mesh.SetTriangles(tris, 0, true);
mesh.RecalculateNormals();
return mesh;
}
private void OnDrawGizmos()
{
if (!trigger)
return;
if (bounds.Count >= 3)
{
for (int i = 0; i < bounds.Count; i++)
{
Gizmos.color = new Color(displayColor.r, displayColor.g, displayColor.b, 0.3f);
Gizmos.DrawSphere(TransformToLocalSpace(bounds[i]), 0.2f);
Vector3 point = Vector3.zero;
if (i == 0)
point = bounds.Last();
else
point = bounds[i - 1];
Gizmos.color = new Color(displayColor.r, displayColor.g, displayColor.b, 1);
Gizmos.DrawLine(TransformToLocalSpace(bounds[i]), TransformToLocalSpace(point));
}
for (int i = 0; i < bounds.Count; i++)
{
Gizmos.color = new Color(displayColor.r, displayColor.g, displayColor.b, 0.5f);
Gizmos.DrawSphere(TransformToLocalSpace(bounds[i]) + Vector3.up * height, 0.2f);
Vector3 point = Vector3.zero;
if (i == 0)
point = bounds.Last();
else
point = bounds[i - 1];
Gizmos.color = new Color(displayColor.r, displayColor.g, displayColor.b, 1);
Gizmos.DrawLine(TransformToLocalSpace(bounds[i]) + Vector3.up * height, TransformToLocalSpace(point) + Vector3.up * height);
Gizmos.DrawLine(TransformToLocalSpace(bounds[i]), TransformToLocalSpace(bounds[i]) + Vector3.up * height);
Gizmos.color = new Color(displayColor.r, displayColor.g, displayColor.b, 0.3f);
Gizmos.DrawLine((TransformToLocalSpace(bounds[i]) + TransformToLocalSpace(point)) / 2,
(TransformToLocalSpace(bounds[i]) + TransformToLocalSpace(point)) / 2 + Vector3.up * height);
}
Gizmos.DrawMesh(trigger.sharedMesh, -1, transform.position, Quaternion.identity, Vector3.one);
}
}
private Vector3 TransformToLocalSpace(Vector3 pos)
{
Vector3 i = pos.x * transform.right + pos.y * transform.up + pos.z * transform.forward;
i += transform.position;
return i;
}
}
#if UNITY_EDITOR
[CanEditMultipleObjects]
[CustomEditor(typeof(CustomCollisionShape))]
public class E_CustomCollisionShape : Editor
{
public CustomCollisionShape shape;
public void OnEnable()
{
shape = (CustomCollisionShape)target;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(serializedObject.FindProperty("bounds"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("height"));
if (EditorGUI.EndChangeCheck())
if (shape.trigger)
shape.trigger.sharedMesh = shape.BuildZoneCollider();
else
shape.CheckTrigger();
EditorGUILayout.Space();
EditorGUILayout.PropertyField(serializedObject.FindProperty("displayColor"));
EditorGUI.indentLevel--;
serializedObject.ApplyModifiedProperties();
}
}
#endif
}