cvr-props/Assets/ABI.CCK/Scripts/Editor/CCK_CVRSpawnableEditor.cs

274 lines
No EOL
11 KiB
C#
Executable file

using ABI.CCK.Components;
using ABI.CCK.Scripts.Editor;
using ABI.CCK.Scripts.Editor.Tools;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace ABI.CCK.Scripts.Editor
{
//[CustomEditor(typeof(CVRSpawnable), true)]
public class CCK_CVRSpawnableEditor : UnityEditor.Editor
{
private CVRSpawnable _spawnable;
private ReorderableList _syncedValueList;
private CVRSpawnableValue _syncedValueEntry;
private ReorderableList _subSyncList;
private CVRSpawnableSubSync _subSyncEntry;
private float _subSyncCosts;
private bool _outOfBoundsError;
#region Unity Events
public void OnEnable()
{
// Occurs on recompile
if (target == null)
return;
_spawnable = (CVRSpawnable)target;
_spawnable.Reset();
if (_syncedValueList == null)
InitializeList();
if (_subSyncList == null)
InitializeSubSyncList();
}
public override void OnInspectorGUI()
{
if (_spawnable == null)
return;
EditorGUI.BeginChangeCheck();
_spawnable.spawnHeight = EditorGUILayout.FloatField("Spawn Height", _spawnable.spawnHeight);
_spawnable.propPrivacy = (CVRSpawnable.PropPrivacy) EditorGUILayout.EnumPopup("Prop Usage", _spawnable.propPrivacy);
GUILayout.BeginVertical("HelpBox");
GUILayout.BeginHorizontal ();
_spawnable.useAdditionalValues = EditorGUILayout.Toggle (_spawnable.useAdditionalValues, GUILayout.Width(16));
EditorGUILayout.LabelField ("Enable Sync Values", GUILayout.Width(250));
GUILayout.EndHorizontal ();
if (_spawnable.useAdditionalValues)
{
UpdateSubSyncCosts();
GUILayout.BeginHorizontal();
GUILayout.BeginVertical("GroupBox");
var SyncCost = _spawnable.syncValues.Count + _subSyncCosts;
Rect _rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight);
EditorGUI.ProgressBar(_rect, SyncCost / 40f, Mathf.CeilToInt(SyncCost) + " of 40 Synced Values used");
EditorGUILayout.Space();
if (_subSyncCosts > 0f)
{
EditorGUILayout.HelpBox(_subSyncCosts.ToString("F2")+" Values are used for Sub Sync Transforms", MessageType.Info);
EditorGUILayout.Space();
}
_syncedValueList.displayAdd = SyncCost <= 39f;
_syncedValueList.DoLayoutList();
EditorGUILayout.Space();
_subSyncList.displayAdd = SyncCost <= 39f;
_subSyncList.DoLayoutList();
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
if (_outOfBoundsError)
{
EditorGUILayout.HelpBox("A Sub Sync Transform is out of bounds by default. This object will snap to its bounds, when it is being synced.", MessageType.Error);
_outOfBoundsError = false;
}
if (EditorGUI.EndChangeCheck())
EditorUtility.SetDirty(_spawnable);
}
#endregion
#region ReorderableList SyncedValue
private void InitializeList()
{
_syncedValueList = new ReorderableList(_spawnable.syncValues, typeof(CVRAdvancedSettingsEntry), true, true, true, true)
{
drawHeaderCallback = OnDrawHeaderSyncedValue,
drawElementCallback = OnDrawElementSyncedValue,
elementHeightCallback = OnHeightElementSyncedValue,
onAddCallback = OnAddSyncedValue,
onChangedCallback = OnChangedSyncedValue
};
}
private void OnChangedSyncedValue(ReorderableList list)
{
//EditorUtility.SetDirty(target);
}
private void OnAddSyncedValue(ReorderableList list)
{
if (_spawnable.syncValues.Count >= 40) return;
_spawnable.syncValues.Add(new CVRSpawnableValue());
Repaint();
}
private float OnHeightElementSyncedValue(int index)
{
return EditorGUIUtility.singleLineHeight * 7.5f;
}
private void OnDrawElementSyncedValue(Rect rect, int index, bool isactive, bool isfocused)
{
if (index > _spawnable.syncValues.Count) return;
_syncedValueEntry = _spawnable.syncValues[index];
rect = new Rect(rect.x, rect.y + 2, rect.width, EditorGUIUtility.singleLineHeight);
float spacing = EditorGUIUtility.singleLineHeight * 1.25f;
float originalLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 120;
_syncedValueEntry.name = EditorGUI.TextField(rect, "Name", _syncedValueEntry.name);
rect.y += spacing;
_syncedValueEntry.startValue = EditorGUI.FloatField(rect, "Start Value", _syncedValueEntry.startValue);
rect.y += spacing;
_syncedValueEntry.updatedBy = (CVRSpawnableValue.UpdatedBy) EditorGUI.EnumPopup(rect, "Update Type", _syncedValueEntry.updatedBy);
rect.y += spacing;
_syncedValueEntry.updateMethod = (CVRSpawnableValue.UpdateMethod) EditorGUI.EnumPopup(rect, "Update Method", _syncedValueEntry.updateMethod);
rect.y += spacing;
_syncedValueEntry.animator = (Animator)EditorGUI.ObjectField(rect, "Connected Animator", _syncedValueEntry.animator, typeof(Animator), true);
rect.y += spacing;
_syncedValueEntry.animatorParameterName = EditorGUIExtensions.AdvancedDropdownInput(rect, _syncedValueEntry.animatorParameterName,
CVRCommon.GetParametersFromAnimatorAsString(_syncedValueEntry.animator), "Animator Parameter","No Parameters");
EditorGUIUtility.labelWidth = originalLabelWidth;
}
private void OnDrawHeaderSyncedValue(Rect rect)
{
Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
GUI.Label(_rect, "Values");
EditorGUIExtensions.UtilityMenu(_rect, _syncedValueList);
}
#endregion
#region ReorderableList SubSync
private void InitializeSubSyncList()
{
_subSyncList = new ReorderableList(_spawnable.subSyncs, typeof(CVRSpawnableSubSync), false, true, true, true)
{
drawHeaderCallback = OnDrawHeaderSubSync,
drawElementCallback = OnDrawElementSubSync,
elementHeightCallback = OnHeightElementSubSync,
onAddCallback = OnAddSubSync,
onChangedCallback = OnChangedSubSync
};
}
private void OnDrawHeaderSubSync(Rect rect)
{
Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
GUI.Label(_rect, "Sub Sync Transforms");
EditorGUIExtensions.UtilityMenu(_rect, _subSyncList);
}
private void OnDrawElementSubSync(Rect rect, int index, bool isactive, bool isfocused)
{
if (index > _spawnable.subSyncs.Count) return;
_subSyncEntry = _spawnable.subSyncs[index];
rect = new Rect(rect.x, rect.y + 2, rect.width, EditorGUIUtility.singleLineHeight);
float spacing = EditorGUIUtility.singleLineHeight * 1.25f;
float originalLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 120;
_subSyncEntry.transform = (Transform)EditorGUI.ObjectField(rect, "Transform", _subSyncEntry.transform, typeof(Transform), true);
rect.y += spacing;
_subSyncEntry.syncedValues = (CVRSpawnableSubSync.SyncFlags) EditorGUI.EnumFlagsField(rect, "Synced Properties", _subSyncEntry.syncedValues);
rect.y += spacing;
_subSyncEntry.precision = (CVRSpawnableSubSync.SyncPrecision) EditorGUI.EnumPopup(rect, "Sync Precision", _subSyncEntry.precision);
rect.y += spacing;
if (_subSyncEntry.precision != CVRSpawnableSubSync.SyncPrecision.Full)
{
_subSyncEntry.syncBoundary = EditorGUI.FloatField(rect, "Sync Boundary", _subSyncEntry.syncBoundary);
rect.y += spacing;
if (_subSyncEntry.transform != null)
{
Vector3 localPosition = _subSyncEntry.transform.localPosition;
_outOfBoundsError = Mathf.Abs(localPosition.x) > _subSyncEntry.syncBoundary ||
Mathf.Abs(localPosition.y) > _subSyncEntry.syncBoundary ||
Mathf.Abs(localPosition.z) > _subSyncEntry.syncBoundary;
}
}
EditorGUIUtility.labelWidth = originalLabelWidth;
}
private float OnHeightElementSubSync(int index)
{
if (_spawnable.subSyncs[index].precision == CVRSpawnableSubSync.SyncPrecision.Full)
return EditorGUIUtility.singleLineHeight * 3.75f;
return EditorGUIUtility.singleLineHeight * 5f;
}
private void OnAddSubSync(ReorderableList list)
{
if (_spawnable.subSyncs.Count >= 40) return;
_spawnable.subSyncs.Add(new CVRSpawnableSubSync());
Repaint();
}
private void OnChangedSubSync(ReorderableList list)
{
//EditorUtility.SetDirty(target);
}
#endregion
#region Private Methods
private void UpdateSubSyncCosts()
{
_subSyncCosts = 0f;
foreach (CVRSpawnableSubSync subSync in _spawnable.subSyncs)
{
if (subSync.syncedValues.HasFlag(CVRSpawnableSubSync.SyncFlags.TransformX))
_subSyncCosts += (int) subSync.precision / 4f;
if (subSync.syncedValues.HasFlag(CVRSpawnableSubSync.SyncFlags.TransformY))
_subSyncCosts += (int) subSync.precision / 4f;
if (subSync.syncedValues.HasFlag(CVRSpawnableSubSync.SyncFlags.TransformZ))
_subSyncCosts += (int) subSync.precision / 4f;
if (subSync.syncedValues.HasFlag(CVRSpawnableSubSync.SyncFlags.RotationX))
_subSyncCosts += (int) subSync.precision / 4f;
if (subSync.syncedValues.HasFlag(CVRSpawnableSubSync.SyncFlags.RotationY))
_subSyncCosts += (int) subSync.precision / 4f;
if (subSync.syncedValues.HasFlag(CVRSpawnableSubSync.SyncFlags.RotationZ))
_subSyncCosts += (int) subSync.precision / 4f;
}
}
#endregion
}
}