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(); 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); } } } }