// Copyright (C) 2023 Nicholas Maltbie // // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and // associated documentation files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, publish, distribute, // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or // substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. using System; #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; namespace nickmaltbie.OpenKCC.Utils.ColliderCast { /// /// Enum to translate capsule direction to numeric value. /// public enum CapsuleDirection { X = 0, Y = 1, Z = 2, } /// /// List of primitive collider types. /// public enum ColliderType { Box, Sphere, Capsule, Point, } /// /// Generic collider configuration. /// [Serializable] public class ColliderConfiguration : PropertyAttribute { /// /// Type of collider for this configuration. /// public ColliderType type = ColliderType.Box; /// /// Center of box collider. /// public Vector3 boxCenter = Vector3.zero; /// /// Size of the box collider. /// public Vector3 boxSize = Vector3.one; /// /// Center of sphere collider. /// public Vector3 sphereCenter = Vector3.zero; /// /// Radius of the sphere collider. /// public float sphereRadius = 0.5f; /// /// Center of capsule collider /// public Vector3 capsuleCenter = Vector3.zero; /// /// Radius of the capsule collider. /// public float capsuleRadius = 0.5f; /// /// Height of the capsule collider. /// public float capsuleHeight = 2.0f; /// /// Direction fo the capsule collider. /// public CapsuleDirection capsuleDirection = CapsuleDirection.Y; /// /// Center of point collider. /// public Vector3 pointCenter = Vector3.zero; /// /// Gets or sets the radius fo the collider (applies to Sphere or Capsule). /// public float Radius { get { switch (type) { case ColliderType.Sphere: return sphereRadius; case ColliderType.Capsule: return capsuleRadius; default: return 0; } } set { switch (type) { case ColliderType.Sphere: sphereRadius = value; break; case ColliderType.Capsule: capsuleRadius = value; break; } } } /// /// Gets or sets the center of the collider (applies to Box, Sphere, or Capsule). /// public Vector3 Center { get { switch (type) { case ColliderType.Sphere: return sphereCenter; case ColliderType.Capsule: return capsuleCenter; case ColliderType.Box: return boxCenter; default: case ColliderType.Point: return pointCenter; } } set { switch (type) { case ColliderType.Sphere: sphereCenter = value; break; case ColliderType.Capsule: capsuleCenter = value; ; break; case ColliderType.Box: boxCenter = value; break; default: case ColliderType.Point: pointCenter = value; break; } } } /// /// Gets or sets the size of the collider (applies to Box). /// public Vector3 Size { get => boxSize; set => boxSize = value; } /// /// Gets or sets the height of the collider (applies to Capsule). /// public float Height { get => capsuleHeight; set => capsuleHeight = value; } /// /// Gets or Sets Direction of capsule collider. /// public CapsuleDirection CapsuleDirection { get => capsuleDirection; set => capsuleDirection = value; } /// /// Constructs an instance of Collider configuration. /// /// Type of collider to create. /// Center of the collider in 3D space. /// Size of the collider (only applies to Box) /// Radius fo the collider (applies to Sphere or Capsule). /// Height of the collider (applies to Capsule). /// Direction of capsule collider. public ColliderConfiguration( ColliderType type = ColliderType.Box, Vector3? center = null, Vector3? size = null, float radius = 0.5f, float height = 2.0f, CapsuleDirection capsuleDirection = CapsuleDirection.Y) { this.type = type; Center = center ?? Vector3.zero; Size = size ?? Vector3.one; Radius = radius; Height = height; CapsuleDirection = capsuleDirection; } /// /// Attaches a collider component to a given game object /// based on this collider configuration. /// /// Game object to attach collider to. /// Should existing colliders on the object be cleaned up. /// Collider attached to the given game object. public Collider AttachCollider(GameObject go, bool cleanupCollider = true) { if (cleanupCollider) { foreach (Collider col in go.GetComponents()) { #if UNITY_EDITOR if (!EditorApplication.isPlaying) { GameObject.DestroyImmediate(col); } else { GameObject.Destroy(col); } #else GameObject.Destroy(col); #endif } } switch (type) { case ColliderType.Box: BoxCollider box = go.AddComponent(); box.size = Size; box.center = Center; return box; case ColliderType.Sphere: SphereCollider sphere = go.AddComponent(); sphere.center = Center; sphere.radius = Radius; return sphere; case ColliderType.Capsule: CapsuleCollider capsule = go.AddComponent(); capsule.center = Center; capsule.radius = Radius; capsule.height = Height; capsule.direction = (int)CapsuleDirection; return capsule; } return null; } } }