OldBlueWater/BlueWater/Assets/RayFire/Scripts/Editor/RayfireBladeEditor.cs

328 lines
13 KiB
C#
Raw Normal View History

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using UnityEditor.SceneManagement;
using UnityEditorInternal;
namespace RayFire
{
[CanEditMultipleObjects]
[CustomEditor (typeof(RayfireBlade))]
public class RayfireBladeEditor : Editor
{
RayfireBlade blade;
List<string> layerNames;
SerializedProperty targetListProp;
ReorderableList targetList;
/// /////////////////////////////////////////////////////////
/// Static
/// /////////////////////////////////////////////////////////
// Static
static int space = 3;
static GUIContent gui_filtCool = new GUIContent ("Cooldown", "Allows to temporary disable Blade component for defined time to prevent constant slicing.");
static GUIContent gui_propAction = new GUIContent ("Action", "Slice: Object will be Sliced accordingly to Slice Type plane.\n"+
"Demolish: Object will demolished accordingly to it's Mesh or Cluster Demolition properties.");
static GUIContent gui_propTrigger = new GUIContent ("On Trigger", " Enter: Object will be sliced when Blade's trigger collider enter object's collider.\n" +
" Exit: Object will be sliced when Blade's trigger collider exit object's collider.\n" +
" Enter Exit: Object will be sliced when Blade's trigger collider exit object's collider and angle for slicing plane will be average angle between enter and exit. " +
" This type should be used if object with Blade will be rotated while it is inside sliced object so slicing plane at least will have average angle.");
static GUIContent gui_propSlice = new GUIContent ("Slice Plane", "Defines slicing plane which will be used to slice target object.");
static GUIContent gui_propDamage = new GUIContent ("Damage", "Applies damage to sliced object.");
static GUIContent gui_propSkin = new GUIContent ("Skin", "In order to detect collider collision one of the objects has to have RigidBody component and " +
"Skinned Mesh object may not have RigidBody. " +
"when this property enabled Blade object will get its own kinematic RigidBody component" +
"to detect collision with skinned mesh objects.");
static GUIContent gui_forceVal = new GUIContent ("Force", "Add to sliced fragments additional velocity impulse to separate them.");
static GUIContent gui_forceIna = new GUIContent ("Affect Inactive", "Force will be applied to Inactive objects as well.");
static GUIContent gui_targets = new GUIContent ("Target List", "Slicing also can be initiated by Slice Target button or by public SliceTarget() method. " +
"In this case object with Blade doesn't have to enter or exit sliced object collider, but you need to define Target Gameobject for slice.");
/// /////////////////////////////////////////////////////////
/// Enable
/// /////////////////////////////////////////////////////////
private void OnEnable()
{
targetListProp = serializedObject.FindProperty("targets");
targetList = new ReorderableList(serializedObject, targetListProp, true, true, true, true);
targetList.drawElementCallback = DrawInitListItems;
targetList.drawHeaderCallback = DrawInitHeader;
targetList.onAddCallback = AddInit;
targetList.onRemoveCallback = RemoveInit;
}
/// /////////////////////////////////////////////////////////
/// Inspector
/// /////////////////////////////////////////////////////////
public override void OnInspectorGUI()
{
blade = target as RayfireBlade;
if (blade == null)
return;
GUILayout.Space (8);
if (Application.isPlaying == true)
{
// Cooldown
if (blade.coolDownState == true)
GUILayout.Label (" Cooldown...");
}
GUILayout.Space (space);
UI_Props();
GUILayout.Space (space);
UI_Force();
GUILayout.Space (space);
UI_Filters();
GUILayout.Space (space);
UI_Targets();
GUILayout.Space (8);
}
/// /////////////////////////////////////////////////////////
/// Properties
/// /////////////////////////////////////////////////////////
void UI_Props()
{
GUILayout.Label (" Properties", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
blade.actionType = (RayfireBlade.ActionType)EditorGUILayout.EnumPopup (gui_propAction, blade.actionType);
if (EditorGUI.EndChangeCheck() == true)
{
foreach (RayfireBlade scr in targets)
{
scr.actionType = blade.actionType;
SetDirty (scr);
}
}
GUILayout.Space (space);
EditorGUI.BeginChangeCheck();
blade.onTrigger = (RayfireBlade.CutType)EditorGUILayout.EnumPopup (gui_propTrigger, blade.onTrigger);
if (EditorGUI.EndChangeCheck() == true)
{
foreach (RayfireBlade scr in targets)
{
scr.onTrigger = blade.onTrigger;
SetDirty (scr);
}
}
GUILayout.Space (space);
EditorGUI.BeginChangeCheck();
blade.sliceType = (PlaneType)EditorGUILayout.EnumPopup (gui_propSlice, blade.sliceType);
if (EditorGUI.EndChangeCheck() == true)
{
foreach (RayfireBlade scr in targets)
{
scr.sliceType = blade.sliceType;
SetDirty (scr);
}
}
GUILayout.Space (space);
EditorGUI.BeginChangeCheck();
blade.damage = EditorGUILayout.Slider (gui_propDamage, blade.damage, 0.01f, 50f);
if (EditorGUI.EndChangeCheck() == true)
{
foreach (RayfireBlade scr in targets)
{
scr.damage = blade.damage;
SetDirty (scr);
}
}
GUILayout.Space (space);
EditorGUI.BeginChangeCheck();
blade.skin = EditorGUILayout.Toggle (gui_propSkin, blade.skin);
if (EditorGUI.EndChangeCheck())
{
foreach (RayfireBlade scr in targets)
{
scr.skin = blade.skin;
SetDirty (scr);
}
}
}
/// /////////////////////////////////////////////////////////
/// Force
/// /////////////////////////////////////////////////////////
void UI_Force()
{
GUILayout.Label (" Force", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
blade.force = EditorGUILayout.Slider (gui_forceVal, blade.force, 0f, 10f);
if (EditorGUI.EndChangeCheck())
{
foreach (RayfireBlade scr in targets)
{
scr.force = blade.force;
SetDirty (scr);
}
}
GUILayout.Space (space);
EditorGUI.BeginChangeCheck();
blade.affectInactive = EditorGUILayout.Toggle (gui_forceIna, blade.affectInactive);
if (EditorGUI.EndChangeCheck())
{
foreach (RayfireBlade scr in targets)
{
scr.affectInactive = blade.affectInactive;
SetDirty (scr);
}
}
}
/// /////////////////////////////////////////////////////////
/// Filters
/// /////////////////////////////////////////////////////////
void UI_Filters()
{
GUILayout.Label (" Filters", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
blade.cooldown = EditorGUILayout.Slider (gui_filtCool, blade.cooldown, 0f, 10f);
if (EditorGUI.EndChangeCheck())
{
foreach (RayfireBlade scr in targets)
{
scr.cooldown = blade.cooldown;
SetDirty (scr);
}
}
GUILayout.Space (space);
EditorGUI.BeginChangeCheck();
blade.tagFilter = EditorGUILayout.TagField ("Tag", blade.tagFilter);
if (EditorGUI.EndChangeCheck())
foreach (RayfireBlade scr in targets)
{
scr.tagFilter = blade.tagFilter;
SetDirty (scr);
}
GUILayout.Space (space);
if (layerNames == null)
{
layerNames = new List<string>();
for (int i = 0; i <= 31; i++)
layerNames.Add (i + ". " + LayerMask.LayerToName (i));
}
EditorGUI.BeginChangeCheck();
blade.mask = EditorGUILayout.MaskField ("Layer", blade.mask, layerNames.ToArray());
if (EditorGUI.EndChangeCheck())
{
foreach (RayfireBlade scr in targets)
{
scr.mask = blade.mask;
SetDirty (scr);
}
}
}
/// /////////////////////////////////////////////////////////
/// Targets
/// /////////////////////////////////////////////////////////
void UI_Targets()
{
GUILayout.Label (" Targets", EditorStyles.boldLabel);
serializedObject.Update();
targetList.DoLayoutList();
serializedObject.ApplyModifiedProperties();
if (Application.isPlaying == true && blade.HasTargets == true)
{
if (GUILayout.Button (" Slice Target ", GUILayout.Height (25)))
{
foreach (var bl in targets)
if (bl as RayfireBlade != null)
(bl as RayfireBlade).SliceTarget();
}
}
}
/// /////////////////////////////////////////////////////////
/// ReorderableList draw
/// /////////////////////////////////////////////////////////
void DrawInitListItems(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty element = targetList.serializedProperty.GetArrayElementAtIndex(index);
EditorGUI.PropertyField(new Rect(rect.x, rect.y+2, EditorGUIUtility.currentViewWidth - 80f, EditorGUIUtility.singleLineHeight), element, GUIContent.none);
}
void DrawInitHeader(Rect rect)
{
rect.x += 10;
EditorGUI.LabelField(rect, gui_targets);
}
void AddInit(ReorderableList list)
{
if (blade.targets == null)
blade.targets = new List<GameObject>();
blade.targets.Add (null);
list.index = list.count;
}
void RemoveInit(ReorderableList list)
{
if (blade.HasTargets == true)
{
blade.targets.RemoveAt (list.index);
list.index = list.index - 1;
}
}
/// /////////////////////////////////////////////////////////
/// Common
/// /////////////////////////////////////////////////////////
void SetDirty (RayfireBlade scr)
{
if (Application.isPlaying == false)
{
EditorUtility.SetDirty (scr);
EditorSceneManager.MarkSceneDirty (scr.gameObject.scene);
}
}
}
}