194 lines
8.3 KiB
C#
194 lines
8.3 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
|
|
namespace EmeraldAI.Utility
|
|
{
|
|
[CustomEditor(typeof(EmeraldHealth))]
|
|
[CanEditMultipleObjects]
|
|
public class EmeraldHealthEditor : Editor
|
|
{
|
|
GUIStyle FoldoutStyle;
|
|
Texture HealthEditorIcon;
|
|
|
|
//Int
|
|
SerializedProperty StartingHealthProp, HealRateProp;
|
|
|
|
//Enum
|
|
SerializedProperty UseHitEffectProp;
|
|
|
|
//Bool
|
|
SerializedProperty HideSettingsFoldout, HealthFoldout, HitEffectFoldout, ImmortalProp;
|
|
|
|
//Float
|
|
SerializedProperty HitEffectTimeoutSecondsProp;
|
|
|
|
//Vector
|
|
SerializedProperty HitEffectPosOffsetProp;
|
|
|
|
ReorderableList HitEffectsList;
|
|
|
|
void OnEnable()
|
|
{
|
|
if (HealthEditorIcon == null) HealthEditorIcon = Resources.Load("Editor Icons/EmeraldHealth") as Texture;
|
|
InitializeProperties();
|
|
InitializeList();
|
|
}
|
|
|
|
void InitializeProperties()
|
|
{
|
|
//Ints
|
|
StartingHealthProp = serializedObject.FindProperty("StartingHealth");
|
|
HealRateProp = serializedObject.FindProperty("HealRate");
|
|
|
|
//Bool
|
|
HideSettingsFoldout = serializedObject.FindProperty("HideSettingsFoldout");
|
|
HealthFoldout = serializedObject.FindProperty("HealthFoldout");
|
|
HitEffectFoldout = serializedObject.FindProperty("HitEffectFoldout");
|
|
ImmortalProp = serializedObject.FindProperty("Immortal");
|
|
|
|
//Float
|
|
HitEffectTimeoutSecondsProp = serializedObject.FindProperty("HitEffectTimeoutSeconds");
|
|
|
|
//Vector
|
|
HitEffectPosOffsetProp = serializedObject.FindProperty("HitEffectPosOffset");
|
|
|
|
//Enum
|
|
UseHitEffectProp = serializedObject.FindProperty("UseHitEffect");
|
|
}
|
|
|
|
void InitializeList ()
|
|
{
|
|
//Hit Effects List
|
|
HitEffectsList = new ReorderableList(serializedObject, serializedObject.FindProperty("HitEffectsList"), true, true, true, true);
|
|
HitEffectsList.drawHeaderCallback = rect =>
|
|
{
|
|
EditorGUI.LabelField(rect, "Hit Effects List", EditorStyles.boldLabel);
|
|
};
|
|
HitEffectsList.drawElementCallback =
|
|
(Rect rect, int index, bool isActive, bool isFocused) =>
|
|
{
|
|
var element = HitEffectsList.serializedProperty.GetArrayElementAtIndex(index);
|
|
EditorGUI.ObjectField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none);
|
|
};
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
FoldoutStyle = CustomEditorProperties.UpdateEditorStyles();
|
|
EmeraldHealth self = (EmeraldHealth)target;
|
|
serializedObject.Update();
|
|
|
|
CustomEditorProperties.BeginScriptHeaderNew("Health", HealthEditorIcon, new GUIContent(), HideSettingsFoldout);
|
|
|
|
if (!HideSettingsFoldout.boolValue)
|
|
{
|
|
EditorGUILayout.Space();
|
|
HealthSettings(self);
|
|
EditorGUILayout.Space();
|
|
HitEffectSettings(self);
|
|
EditorGUILayout.Space();
|
|
}
|
|
|
|
CustomEditorProperties.EndScriptHeader();
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
void HealthSettings(EmeraldHealth self)
|
|
{
|
|
HealthFoldout.boolValue = EditorGUILayout.Foldout(HealthFoldout.boolValue, "Health Settings", true, FoldoutStyle);
|
|
|
|
if (HealthFoldout.boolValue)
|
|
{
|
|
CustomEditorProperties.BeginFoldoutWindowBox();
|
|
CustomEditorProperties.TextTitleWithDescription("Health Settings", "Controls various health related settings.", true);
|
|
|
|
EditorGUILayout.PropertyField(ImmortalProp, new GUIContent("Immortal"));
|
|
CustomEditorProperties.CustomHelpLabelField("Controls whether or not an AI is immune to damage and is unkillable. If this is enabled, it will disable other settings.", true);
|
|
|
|
EditorGUI.BeginDisabledGroup(self.Immortal);
|
|
CustomEditorProperties.CustomIntField(new Rect(), new GUIContent(), StartingHealthProp, "Starting Health");
|
|
CustomEditorProperties.CustomHelpLabelField("Controls how much starting health an AI will have.", true);
|
|
|
|
CustomEditorProperties.CustomPropertyField(HealRateProp, "Heal Rate", "Controls how much an AI will heal per second when not actively in combat, given their health is below its max.", true);
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
DrawHealthBar(self);
|
|
|
|
CustomEditorProperties.EndFoldoutWindowBox();
|
|
}
|
|
}
|
|
|
|
void DrawHealthBar (EmeraldHealth self)
|
|
{
|
|
GUILayout.Space(45);
|
|
GUIStyle LabelStyle = new GUIStyle();
|
|
LabelStyle.alignment = TextAnchor.MiddleCenter;
|
|
LabelStyle.padding.bottom = 4;
|
|
LabelStyle.fontStyle = FontStyle.Bold;
|
|
LabelStyle.normal.textColor = Color.white;
|
|
|
|
Rect r = EditorGUILayout.BeginVertical();
|
|
GUI.backgroundColor = Color.white;
|
|
float CurrentHealth = ((float)self.CurrentHealth / (float)self.StartingHealth);
|
|
|
|
EditorGUI.DrawRect(new Rect(r.x, r.position.y - 39f, ((r.width)), 32), new Color(0.05f, 0.05f, 0.05f, 0.5f)); //Health Bar BG Outline
|
|
EditorGUI.DrawRect(new Rect(r.x + 4, r.position.y - 35f, ((r.width - 8)), 24), new Color(0.16f, 0.16f, 0.16f, 1f)); //Health Bar BG
|
|
Color HealthBarColor = Color.Lerp(new Color(0.6f, 0.1f, 0.1f, 1f), new Color(0.15f, 0.42f, 0.15f, 1f), CurrentHealth);
|
|
EditorGUI.DrawRect(new Rect(r.x + 4, r.position.y - 35f, ((r.width - 8) * CurrentHealth), 24), HealthBarColor); //Health Bar Main
|
|
|
|
if (self.CurrentHealth > 0)
|
|
{
|
|
EditorGUI.LabelField(new Rect(r.x, r.position.y - 35f, (r.width), 26), "Current Health: " + self.CurrentHealth + "/" + self.StartingHealth, LabelStyle);
|
|
}
|
|
else
|
|
{
|
|
EditorGUI.LabelField(new Rect(r.x, r.position.y - 35f, (r.width), 26), "Current Health: " + self.CurrentHealth + "/" + self.StartingHealth + " (Dead)", LabelStyle);
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
|
|
if (!Application.isPlaying)
|
|
{
|
|
self.CurrentHealth = self.StartingHealth;
|
|
}
|
|
}
|
|
|
|
void HitEffectSettings(EmeraldHealth self)
|
|
{
|
|
HitEffectFoldout.boolValue = EditorGUILayout.Foldout(HitEffectFoldout.boolValue, "Hit Effect Settings", true, FoldoutStyle);
|
|
|
|
if (HitEffectFoldout.boolValue)
|
|
{
|
|
CustomEditorProperties.BeginFoldoutWindowBox();
|
|
CustomEditorProperties.TextTitleWithDescription("Hit Effect Settings", "Allows an AI to display a random hit affect after receiving damage.", true);
|
|
|
|
EditorGUILayout.PropertyField(UseHitEffectProp, new GUIContent("Use Hit Effect"));
|
|
CustomEditorProperties.CustomHelpLabelField("Controls whether or not this AI will use a hit effect when it receives melee damage.", true);
|
|
|
|
if (self.UseHitEffect == YesOrNo.Yes)
|
|
{
|
|
CustomEditorProperties.BeginIndent();
|
|
|
|
CustomEditorProperties.CustomHelpLabelField("The hit effect that will appear when this AI receives damage.", true);
|
|
HitEffectsList.DoLayoutList();
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.Space();
|
|
|
|
EditorGUILayout.PropertyField(HitEffectTimeoutSecondsProp, new GUIContent("Hit Effect Timeout Seconds"));
|
|
CustomEditorProperties.CustomHelpLabelField("Controls how long the hit effect will be visible before being deactivated.", true);
|
|
EditorGUILayout.Space();
|
|
|
|
EditorGUILayout.PropertyField(HitEffectPosOffsetProp, new GUIContent("Hit Effect Position Offset"));
|
|
CustomEditorProperties.CustomHelpLabelField("Controls the offset position of the hit effect using the AI's Hit Transform position.", true);
|
|
EditorGUILayout.Space();
|
|
|
|
CustomEditorProperties.EndIndent();
|
|
}
|
|
|
|
CustomEditorProperties.EndFoldoutWindowBox();
|
|
}
|
|
}
|
|
}
|
|
} |