rabidus-test/Assets/SCSM/SciFiShipController/Editor/DestructModuleEditor.cs

257 lines
15 KiB
C#
Raw Permalink Normal View History

2023-07-24 16:38:13 +03:00
using UnityEngine;
using UnityEditor;
// Sci-Fi Ship Controller. Copyright (c) 2018-2021 SCSM Pty Ltd. All rights reserved.
namespace SciFiShipController
{
[CustomEditor(typeof(DestructModule))]
public class DestructModuleEditor : Editor
{
#region Custom Editor private variables
// Formatting and style variables
private DestructModule destructModule = null;
private string labelText;
private GUIStyle labelFieldRichText;
private GUIStyle helpBoxRichText;
private GUIStyle buttonCompact;
private float defaultEditorLabelWidth = 0f;
private float defaultEditorFieldWidth = 0f;
private bool isDebuggingEnabled = false;
#endregion
#region GUIContent
private readonly static GUIContent headerContent = new GUIContent("<b>Destruct Module</b>\n\nThis module enables you to manage a prefab as it breaks into fragments.");
private readonly static GUIContent isExplodeOnStartContent = new GUIContent("Explode on Start", "Should the explosion occur immediately the scene is started or the module is instantiated? This should be disabled if used with a pooling system.");
private readonly static GUIContent usePoolingContent = new GUIContent("Use Pooling", "Use the Pooling system to manage create, re-use, and destroy destruct objects.");
private readonly static GUIContent minPoolSizeContent = new GUIContent("Min Pool Size", "When using the Pooling system, this is the number of destruct objects kept in reserve for spawning and despawning.");
private readonly static GUIContent maxPoolSizeContent = new GUIContent("Max Pool Size", "When using the Pooling system, this is the maximum number of destruct objects permitted in the scene at any one time.");
private readonly static GUIContent isStartStaticContent = new GUIContent("Start Static", "Start in Static mode rather than Dynamic");
private readonly static GUIContent isAddRigidBodiesEnabledContent = new GUIContent("Add Rigidbodies", "Add rigidbodies to the fragments in the prefab");
private readonly static GUIContent isAddMeshCollidersEnabledContent = new GUIContent("Add Mesh Colliders", "Add mesh colliders to the fragments in the prefab");
private readonly static GUIContent explosionRadiusContent = new GUIContent("Explosion Radius", "The default effective range, in metres, of the blast");
private readonly static GUIContent explosionPowerContent = new GUIContent("Explosion Power", "The default power of the blast");
private readonly static GUIContent unmovingVelocityContent = new GUIContent("Unmoving Velocity", "When the speed (in metres per second) in any direction of the fragment falls below this value, the fragment is considered to have stopped moving");
private readonly static GUIContent maxTimeUnmovingContent = new GUIContent("Max Time Unmoving", "If a fragment has been unmoving for more than the maximum time, set the object as static");
private readonly static GUIContent massContent = new GUIContent("Total Mass", "The total mass of all fragments in the prefab");
private readonly static GUIContent isCalcMassByBoundsContent = new GUIContent("Calc Mass by Bounds", "This may be more accurate when there the is a lot of variation between the size of each fragment.");
private readonly static GUIContent dragContent = new GUIContent("Drag", "The amount of drag the fragments have. A solid block of metal would be 0.001, while a feather would be 10.");
private readonly static GUIContent angularDragContent = new GUIContent("Angular Drag", "The amount of angular drag the fragments have");
private readonly static GUIContent useGravityContent = new GUIContent("Use Gravity", "Fragments are affected by gravity");
private readonly static GUIContent interpolationContent = new GUIContent("Interpolation", "The rigidbody interpolation");
private readonly static GUIContent collisionDetectionContent = new GUIContent("Collision Detection", "The rigidbody collision detection mode");
private readonly static GUIContent despawnRulesContent = new GUIContent("Despawn Rules");
private readonly static GUIContent despawnTimeContent = new GUIContent(" Despawn Time", "After this time (in seconds), the destruct object is automatically despawned or removed from the scene.");
private readonly static GUIContent disableRigidbodyModeContent = new GUIContent("Disable Rigidbody Mode", "How the rigidbodies are disabled when considered static. See manual for details.");
private readonly static GUIContent despawnConditionContent = new GUIContent(" Despawn Condition", "The conditions under which this object despawns");
private readonly static GUIContent waitUntilNotRenderedContent = new GUIContent(" Wait until not Rendered", "Wait until the fragment is not being rendered by the camera before being despawned");
private readonly static GUIContent waitUntilStaticContent = new GUIContent(" Wait until Static", "Wait until the fragment is set to static before being despawned");
#endregion
#region GUIConnent Debugging
private readonly static GUIContent debugModeContent = new GUIContent("Debug Mode", "Use this to display destruct data from the component at runtime in the editor.");
private readonly static GUIContent debugNotSetContent = new GUIContent("--", "not set");
private readonly static GUIContent debugIsInitialisedContent = new GUIContent("Is Initialised?");
private readonly static GUIContent debugIsActivatedContent = new GUIContent("Is Activated?", "Is the destruct module currently in use?");
private readonly static GUIContent debugIsDestructEnabledContent = new GUIContent("Is Destruct Enabled?", "Is the destruct module currently ready for use, or has it been paused?");
private readonly static GUIContent debugEstimatedDespawnTimeContent = new GUIContent("Est. Despawn Time", "The estimated number of seconds before the object is despawned");
#endregion
#region Serialized Properties
private SerializedProperty usePoolingProp;
private SerializedProperty minPoolSizeProp;
private SerializedProperty maxPoolSizeProp;
private SerializedProperty despawnConditionProp;
private SerializedProperty disableRigidbodyModeProp;
private SerializedProperty isStartStaticProp;
private SerializedProperty useGravityProp;
private SerializedProperty waitUntilNotRenderedToDespawnProp;
#endregion
#region Events
public void OnEnable()
{
destructModule = (DestructModule)target;
defaultEditorLabelWidth = 175f;
defaultEditorFieldWidth = EditorGUIUtility.fieldWidth;
#region Find Properties
usePoolingProp = serializedObject.FindProperty("usePooling");
isStartStaticProp = serializedObject.FindProperty("isStartStatic");
useGravityProp = serializedObject.FindProperty("useGravity");
despawnConditionProp = serializedObject.FindProperty("despawnCondition");
disableRigidbodyModeProp = serializedObject.FindProperty("disableRigidbodyMode");
waitUntilNotRenderedToDespawnProp = serializedObject.FindProperty("waitUntilNotRenderedToDespawn");
#endregion
}
/// <summary>
/// Gets called automatically 10 times per second
/// Comment out if not required
/// </summary>
void OnInspectorUpdate()
{
// OnInspectorGUI() only registers events when the mouse is positioned over the custom editor window
// This code forces OnInspectorGUI() to run every frame, so it registers events even when the mouse
// is positioned over the scene view
if (destructModule.allowRepaint) { Repaint(); }
}
#endregion
#region OnInspectorGUI
// This function overides what is normally seen in the inspector window
// This allows stuff like buttons to be drawn there
public override void OnInspectorGUI()
{
#region Initialise
destructModule.allowRepaint = false;
EditorGUIUtility.labelWidth = defaultEditorLabelWidth;
EditorGUIUtility.fieldWidth = defaultEditorFieldWidth;
#endregion
#region Configure Buttons and Styles
// Set up rich text GUIStyles
helpBoxRichText = new GUIStyle("HelpBox");
helpBoxRichText.richText = true;
labelFieldRichText = new GUIStyle("Label");
labelFieldRichText.richText = true;
buttonCompact = new GUIStyle("Button");
buttonCompact.fontSize = 10;
#endregion
// Read in all the properties
serializedObject.Update();
GUILayout.BeginVertical("HelpBox");
EditorGUILayout.LabelField("<b>Sci-Fi Ship Controller</b> Version " + ShipControlModule.SSCVersion + " " + ShipControlModule.SSCBetaVersion, labelFieldRichText);
GUILayout.EndVertical();
EditorGUILayout.LabelField(headerContent, helpBoxRichText);
#region General Properties
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.PropertyField(serializedObject.FindProperty("isExplodeOnStart"), isExplodeOnStartContent);
EditorGUILayout.PropertyField(usePoolingProp, usePoolingContent);
if (usePoolingProp.boolValue)
{
minPoolSizeProp = serializedObject.FindProperty("minPoolSize");
maxPoolSizeProp = serializedObject.FindProperty("maxPoolSize");
EditorGUILayout.PropertyField(minPoolSizeProp, minPoolSizeContent);
EditorGUILayout.PropertyField(maxPoolSizeProp, maxPoolSizeContent);
if (minPoolSizeProp.intValue > maxPoolSizeProp.intValue) { maxPoolSizeProp.intValue = minPoolSizeProp.intValue; }
}
if (disableRigidbodyModeProp.intValue != (int)DestructModule.DisableRigidbodyMode.Destroy)
{
EditorGUILayout.PropertyField(isStartStaticProp, isStartStaticContent);
}
else if (isStartStaticProp.boolValue)
{
// isStartStatic is not compatible with DisableRigidbodyMode.Destroy
isStartStaticProp.boolValue = false;
}
EditorGUILayout.PropertyField(serializedObject.FindProperty("isAddRigidBodiesEnabled"), isAddRigidBodiesEnabledContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("isAddMeshCollidersEnabled"), isAddMeshCollidersEnabledContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("explosionRadius"), explosionRadiusContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("explosionPower"), explosionPowerContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("unmovingVelocity"), unmovingVelocityContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("maxTimeUnmoving"), maxTimeUnmovingContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("mass"), massContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("isCalcMassByBounds"), isCalcMassByBoundsContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("drag"), dragContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("angularDrag"), angularDragContent);
EditorGUILayout.PropertyField(useGravityProp, useGravityContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("interpolation"), interpolationContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("collisionDetection"), collisionDetectionContent);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(disableRigidbodyModeProp, disableRigidbodyModeContent);
if (EditorGUI.EndChangeCheck() && isStartStaticProp.boolValue && disableRigidbodyModeProp.intValue == (int)DestructModule.DisableRigidbodyMode.Destroy)
{
// isStartStatic is not compatible with DisableRigidbodyMode.Destroy
isStartStaticProp.boolValue = false;
}
EditorGUILayout.LabelField(despawnRulesContent);
EditorGUILayout.PropertyField(despawnConditionProp, despawnConditionContent);
if (despawnConditionProp.intValue == (int)DestructModule.DespawnCondition.Time)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("despawnTime"), despawnTimeContent);
}
if (waitUntilNotRenderedToDespawnProp.boolValue)
{
SSCEditorHelper.NotImplemented();
}
EditorGUILayout.PropertyField(waitUntilNotRenderedToDespawnProp, waitUntilNotRenderedContent);
EditorGUILayout.PropertyField(serializedObject.FindProperty("waitUntilStaticToDespawn"), waitUntilStaticContent);
EditorGUILayout.EndVertical();
#endregion
// Apply property changes
serializedObject.ApplyModifiedProperties();
#region Debug Mode
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
isDebuggingEnabled = EditorGUILayout.Toggle(debugModeContent, isDebuggingEnabled);
if (isDebuggingEnabled && destructModule != null)
{
float rightLabelWidth = 150f;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(debugIsInitialisedContent, labelFieldRichText, GUILayout.Width(defaultEditorLabelWidth - 3f));
EditorGUILayout.LabelField(destructModule.IsInitialised ? "Yes" : "No", GUILayout.MaxWidth(rightLabelWidth));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(debugIsActivatedContent, labelFieldRichText, GUILayout.Width(defaultEditorLabelWidth - 3f));
EditorGUILayout.LabelField(destructModule.IsActivated ? "Yes" : "No", GUILayout.MaxWidth(rightLabelWidth));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(debugIsDestructEnabledContent, labelFieldRichText, GUILayout.Width(defaultEditorLabelWidth - 3f));
EditorGUILayout.LabelField(destructModule.IsDestructEnabled ? "Yes" : "No", GUILayout.MaxWidth(rightLabelWidth));
EditorGUILayout.EndHorizontal();
float estDespawnTime = destructModule.EstimatedDespawnTime;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(debugEstimatedDespawnTimeContent, labelFieldRichText, GUILayout.Width(defaultEditorLabelWidth - 3f));
EditorGUILayout.LabelField(float.IsInfinity(estDespawnTime) ? "--" : estDespawnTime.ToString("0.0"), GUILayout.MaxWidth(rightLabelWidth));
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
#endregion
destructModule.allowRepaint = true;
//DrawDefaultInspector();
}
#endregion
}
}