cvr-props/Assets/ABI.CCK/Scripts/Editor/CCK_CVRSpawnableEditor.cs
2023-01-22 16:38:23 +01:00

309 lines
No EOL
13 KiB
C#
Executable file

using System.Collections.Generic;
using ABI.CCK.Components;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using AnimatorControllerParameterType = UnityEngine.AnimatorControllerParameterType;
namespace ABI.CCK.Scripts.Editor
{
[CustomEditor(typeof(ABI.CCK.Components.CVRSpawnable), true)]
public class CCK_CVRSpawnableEditor : UnityEditor.Editor
{
private CVRSpawnable _spawnable;
private ReorderableList reorderableList;
private ReorderableList subSyncList;
private CVRSpawnableValue entity;
private CVRSpawnableSubSync subSyncEntity;
private float SubSyncCosts = 0f;
private bool outOfBoundsError = false;
private void InitializeList()
{
if (!_spawnable.useAdditionalValues) return;
reorderableList = new ReorderableList(_spawnable.syncValues, typeof(CVRAdvancedSettingsEntry), true, true, true, true);
reorderableList.drawHeaderCallback = OnDrawHeader;
reorderableList.drawElementCallback = OnDrawElement;
reorderableList.elementHeightCallback = OnHeightElement;
reorderableList.onAddCallback = OnAdd;
reorderableList.onChangedCallback = OnChanged;
}
private void InitializeSubSyncList()
{
if (!_spawnable.useAdditionalValues) return;
subSyncList = new ReorderableList(_spawnable.subSyncs, typeof(CVRSpawnableSubSync), false, true, true, true);
subSyncList.drawHeaderCallback = OnDrawHeaderSubSync;
subSyncList.drawElementCallback = OnDrawElementSubSync;
subSyncList.elementHeightCallback = OnHeightElementSubSync;
subSyncList.onAddCallback = OnAddSubSync;
subSyncList.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");
}
private void OnDrawElementSubSync(Rect rect, int index, bool isactive, bool isfocused)
{
if (index > _spawnable.subSyncs.Count) return;
subSyncEntity = _spawnable.subSyncs[index];
rect.y += 2;
Rect _rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Transform");
_rect.x += 120;
_rect.width = rect.width - 120;
subSyncEntity.transform = (Transform) EditorGUI.ObjectField(_rect, subSyncEntity.transform, typeof(Transform));
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Synced Properties");
_rect.x += 120;
_rect.width = rect.width - 120;
subSyncEntity.syncedValues = (CVRSpawnableSubSync.SyncFlags) EditorGUI.EnumFlagsField(_rect, subSyncEntity.syncedValues);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Sync Precision");
_rect.x += 120;
_rect.width = rect.width - 120;
subSyncEntity.precision = (CVRSpawnableSubSync.SyncPrecision) EditorGUI.EnumPopup(_rect, subSyncEntity.precision);
if (subSyncEntity.precision == CVRSpawnableSubSync.SyncPrecision.Full) return;
if (subSyncEntity.transform != null &&
(Mathf.Abs(subSyncEntity.transform.localPosition.x) > subSyncEntity.syncBoundary ||
Mathf.Abs(subSyncEntity.transform.localPosition.y) > subSyncEntity.syncBoundary ||
Mathf.Abs(subSyncEntity.transform.localPosition.z) > subSyncEntity.syncBoundary))
{
outOfBoundsError = true;
}
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Sync Boundary");
_rect.x += 120;
_rect.width = rect.width - 120;
subSyncEntity.syncBoundary = EditorGUI.FloatField(_rect, subSyncEntity.syncBoundary);
}
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)
{
_spawnable.subSyncs.Add(new CVRSpawnableSubSync());
Repaint();
}
}
private void OnChangedSubSync(ReorderableList list)
{
//EditorUtility.SetDirty(target);
}
private void OnChanged(ReorderableList list)
{
//EditorUtility.SetDirty(target);
}
private void OnAdd(ReorderableList list)
{
if (_spawnable.syncValues.Count < 40)
{
_spawnable.syncValues.Add(new CVRSpawnableValue());
Repaint();
}
}
private float OnHeightElement(int index)
{
return EditorGUIUtility.singleLineHeight * 7.5f;
}
private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused)
{
if (index > _spawnable.syncValues.Count) return;
entity = _spawnable.syncValues[index];
rect.y += 2;
Rect _rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Name");
_rect.x += 120;
_rect.width = rect.width - 120;
entity.name = EditorGUI.TextField(_rect, entity.name);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Start Value");
_rect.x += 120;
_rect.width = rect.width - 120;
entity.startValue = EditorGUI.FloatField(_rect, entity.startValue);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Update Type");
_rect.x += 120;
_rect.width = rect.width - 120;
entity.updatedBy = (CVRSpawnableValue.UpdatedBy) EditorGUI.EnumPopup(_rect, entity.updatedBy);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Update Method");
_rect.x += 120;
_rect.width = rect.width - 120;
entity.updateMethod = (CVRSpawnableValue.UpdateMethod) EditorGUI.EnumPopup(_rect, entity.updateMethod);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Connected Animator");
_rect.x += 120;
_rect.width = rect.width - 120;
entity.animator = (Animator) EditorGUI.ObjectField(_rect, entity.animator, typeof(Animator));
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 120, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Animator Parameter");
_rect.x += 120;
_rect.width = rect.width - 120;
var parameters = new List<string>();
parameters.Add("-none-");
var parameterIndex = 0;
if (entity.animator != null)
{
if (entity.animator.runtimeAnimatorController != null)
{
foreach (var parameter in ((UnityEditor.Animations.AnimatorController) entity.animator.runtimeAnimatorController).parameters)
{
if (parameter.type == AnimatorControllerParameterType.Float)
{
parameters.Add(parameter.name);
}
}
parameterIndex = parameters.FindIndex(match => match == entity.animatorParameterName);
}
}
if (parameterIndex < 0) parameterIndex = 0;
parameterIndex = EditorGUI.Popup(_rect, parameterIndex, parameters.ToArray());
entity.animatorParameterName = parameters[parameterIndex];
}
private void OnDrawHeader(Rect rect)
{
Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
GUI.Label(_rect, "Values");
}
public void UpdateSubSyncCosts()
{
SubSyncCosts = 0f;
foreach (var 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;
}
}
public override void OnInspectorGUI()
{
if (_spawnable == null) _spawnable = (CVRSpawnable) target;
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 Parameter Slots used");
EditorGUILayout.Space();
if (SubSyncCosts > 0f)
{
EditorGUILayout.HelpBox(SubSyncCosts.ToString("F2")+" Values are used for Sub Sync Transforms", MessageType.Info);
EditorGUILayout.Space();
}
if (reorderableList == null) InitializeList();
reorderableList.displayAdd = SyncCost <= 39f;
reorderableList.DoLayoutList();
EditorGUILayout.Space();
outOfBoundsError = false;
if (subSyncList == null) InitializeSubSyncList();
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);
}
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(_spawnable);
}
}
}
}