using UnityEditor; using UnityEngine; namespace TowerDefense.Targetting.Editor { /// /// The editor for configuring targetter /// [CustomEditor(typeof(Targetter)), CanEditMultipleObjects] public class TargetterEditor : UnityEditor.Editor { /// /// Configuration for which collider to use /// public enum TargetterCollider { /// /// For sphere collider /// Sphere, /// /// For capsule collider /// Capsule } /// /// The targetter to edit /// Targetter m_Targetter; /// /// The collision configuration to use /// TargetterCollider m_ColliderConfiguration; /// /// The radius of the collider /// float m_ColliderRadius; // Capsule specific info /// /// The height of a capsule collider /// float m_ExtraVerticalRange; /// /// The attached collider /// Collider m_AttachedCollider; /// /// The serialized property representing /// SerializedProperty m_SerializedAttachedCollider; /// /// draws the default inspector /// and then draws configuration for colliders /// public override void OnInspectorGUI() { base.OnInspectorGUI(); // To make the inspector a little bit neater EditorGUILayout.Space(); EditorGUILayout.LabelField("Targetter Collider Configuration", EditorStyles.boldLabel); m_ColliderConfiguration = (TargetterCollider) EditorGUILayout.EnumPopup("Targetter Collider", m_ColliderConfiguration); AttachCollider(); m_ColliderRadius = EditorGUILayout.FloatField("Radius", m_ColliderRadius); if (m_ColliderConfiguration == TargetterCollider.Capsule) { m_ExtraVerticalRange = EditorGUILayout.FloatField("Vertical Range", m_ExtraVerticalRange); } SetValues(); EditorUtility.SetDirty(m_Targetter); EditorUtility.SetDirty(m_AttachedCollider); serializedObject.ApplyModifiedProperties(); } /// /// For attaching and hiding the correct collider /// void AttachCollider() { switch (m_ColliderConfiguration) { case TargetterCollider.Sphere: if (m_AttachedCollider is SphereCollider) { GetValues(); return; } if (m_AttachedCollider != null) { DestroyImmediate(m_AttachedCollider, true); } m_AttachedCollider = m_Targetter.gameObject.AddComponent(); m_SerializedAttachedCollider.objectReferenceValue = m_AttachedCollider; break; case TargetterCollider.Capsule: if (m_AttachedCollider is CapsuleCollider) { GetValues(); return; } if (m_AttachedCollider != null) { DestroyImmediate(m_AttachedCollider, true); } m_AttachedCollider = m_Targetter.gameObject.AddComponent(); m_SerializedAttachedCollider.objectReferenceValue = m_AttachedCollider; break; } SetValues(); m_AttachedCollider.hideFlags = HideFlags.HideInInspector; } /// /// Assigns the values to the collider /// void SetValues() { switch (m_ColliderConfiguration) { case TargetterCollider.Sphere: var sphere = (SphereCollider) m_AttachedCollider; sphere.radius = m_ColliderRadius; break; case TargetterCollider.Capsule: var capsule = (CapsuleCollider) m_AttachedCollider; capsule.radius = m_ColliderRadius; capsule.height = m_ExtraVerticalRange + m_ColliderRadius * 2; break; } } /// /// Obtains the information from the collider /// void GetValues() { switch (m_ColliderConfiguration) { case TargetterCollider.Sphere: var sphere = (SphereCollider) m_AttachedCollider; m_ColliderRadius = sphere.radius; break; case TargetterCollider.Capsule: var capsule = (CapsuleCollider) m_AttachedCollider; m_ColliderRadius = capsule.radius; m_ExtraVerticalRange = capsule.height - m_ColliderRadius * 2; break; } } /// /// Caches the collider and hides it /// and configures all the necessary information from it /// void OnEnable() { m_Targetter = (Targetter) target; m_SerializedAttachedCollider = serializedObject.FindProperty("attachedCollider"); m_AttachedCollider = (Collider) m_SerializedAttachedCollider.objectReferenceValue; if (m_AttachedCollider == null) { m_AttachedCollider = m_Targetter.GetComponent(); if (m_AttachedCollider == null) { switch (m_ColliderConfiguration) { case TargetterCollider.Sphere: m_AttachedCollider = m_Targetter.gameObject.AddComponent(); break; case TargetterCollider.Capsule: m_AttachedCollider = m_Targetter.gameObject.AddComponent(); break; } m_SerializedAttachedCollider.objectReferenceValue = m_AttachedCollider; } } if (m_AttachedCollider is SphereCollider) { m_ColliderConfiguration = TargetterCollider.Sphere; } else if (m_AttachedCollider is CapsuleCollider) { m_ColliderConfiguration = TargetterCollider.Capsule; } // to ensure the collider is referenced by the serialized object if (m_SerializedAttachedCollider.objectReferenceValue == null) { m_SerializedAttachedCollider.objectReferenceValue = m_AttachedCollider; } GetValues(); m_AttachedCollider.isTrigger = true; m_AttachedCollider.hideFlags = HideFlags.HideInInspector; } } }