2024-08-03 22:24:42 +02:00
using ABI.CCK.Components ;
using ABI.CCK.Scripts.Editor ;
using ABI.CCK.Scripts.Editor.Tools ;
2023-01-22 16:38:23 +01:00
using UnityEditor ;
using UnityEditorInternal ;
using UnityEngine ;
namespace ABI.CCK.Scripts.Editor
{
2024-08-03 22:24:42 +02:00
//[CustomEditor(typeof(CVRSpawnable), true)]
2023-01-22 16:38:23 +01:00
public class CCK_CVRSpawnableEditor : UnityEditor . Editor
{
private CVRSpawnable _spawnable ;
2024-08-03 22:24:42 +02:00
private ReorderableList _syncedValueList ;
private CVRSpawnableValue _syncedValueEntry ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
private ReorderableList _subSyncList ;
private CVRSpawnableSubSync _subSyncEntry ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
private float _subSyncCosts ;
private bool _outOfBoundsError ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
#region Unity Events
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
public void OnEnable ( )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
// Occurs on recompile
if ( target = = null )
return ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
_spawnable = ( CVRSpawnable ) target ;
_spawnable . Reset ( ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
if ( _syncedValueList = = null )
InitializeList ( ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
if ( _subSyncList = = null )
InitializeSubSyncList ( ) ;
}
public override void OnInspectorGUI ( )
{
if ( _spawnable = = null )
return ;
EditorGUI . BeginChangeCheck ( ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
_spawnable . spawnHeight = EditorGUILayout . FloatField ( "Spawn Height" , _spawnable . spawnHeight ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
_spawnable . propPrivacy = ( CVRSpawnable . PropPrivacy ) EditorGUILayout . EnumPopup ( "Prop Usage" , _spawnable . propPrivacy ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
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 )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
UpdateSubSyncCosts ( ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
GUILayout . BeginHorizontal ( ) ;
GUILayout . BeginVertical ( "GroupBox" ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
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 ( ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
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 )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
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 ;
2023-01-22 16:38:23 +01:00
}
2024-08-03 22:24:42 +02:00
if ( EditorGUI . EndChangeCheck ( ) )
EditorUtility . SetDirty ( _spawnable ) ;
2023-01-22 16:38:23 +01:00
}
2024-08-03 22:24:42 +02:00
#endregion
#region ReorderableList SyncedValue
private void InitializeList ( )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
_syncedValueList = new ReorderableList ( _spawnable . syncValues , typeof ( CVRAdvancedSettingsEntry ) , true , true , true , true )
{
drawHeaderCallback = OnDrawHeaderSyncedValue ,
drawElementCallback = OnDrawElementSyncedValue ,
elementHeightCallback = OnHeightElementSyncedValue ,
onAddCallback = OnAddSyncedValue ,
onChangedCallback = OnChangedSyncedValue
} ;
2023-01-22 16:38:23 +01:00
}
2024-08-03 22:24:42 +02:00
private void OnChangedSyncedValue ( ReorderableList list )
2023-01-22 16:38:23 +01:00
{
//EditorUtility.SetDirty(target);
}
2024-08-03 22:24:42 +02:00
private void OnAddSyncedValue ( ReorderableList list )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
if ( _spawnable . syncValues . Count > = 40 ) return ;
_spawnable . syncValues . Add ( new CVRSpawnableValue ( ) ) ;
Repaint ( ) ;
2023-01-22 16:38:23 +01:00
}
2024-08-03 22:24:42 +02:00
private float OnHeightElementSyncedValue ( int index )
2023-01-22 16:38:23 +01:00
{
return EditorGUIUtility . singleLineHeight * 7.5f ;
}
2024-08-03 22:24:42 +02:00
private void OnDrawElementSyncedValue ( Rect rect , int index , bool isactive , bool isfocused )
2023-01-22 16:38:23 +01:00
{
if ( index > _spawnable . syncValues . Count ) return ;
2024-08-03 22:24:42 +02:00
_syncedValueEntry = _spawnable . syncValues [ index ] ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
rect = new Rect ( rect . x , rect . y + 2 , rect . width , EditorGUIUtility . singleLineHeight ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
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 ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
_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 ) ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
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 )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
_subSyncEntry . syncBoundary = EditorGUI . FloatField ( rect , "Sync Boundary" , _subSyncEntry . syncBoundary ) ;
rect . y + = spacing ;
if ( _subSyncEntry . transform ! = null )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
Vector3 localPosition = _subSyncEntry . transform . localPosition ;
_outOfBoundsError = Mathf . Abs ( localPosition . x ) > _subSyncEntry . syncBoundary | |
Mathf . Abs ( localPosition . y ) > _subSyncEntry . syncBoundary | |
Mathf . Abs ( localPosition . z ) > _subSyncEntry . syncBoundary ;
2023-01-22 16:38:23 +01:00
}
}
2024-08-03 22:24:42 +02:00
EditorGUIUtility . labelWidth = originalLabelWidth ;
2023-01-22 16:38:23 +01:00
}
2024-08-03 22:24:42 +02:00
private float OnHeightElementSubSync ( int index )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
if ( _spawnable . subSyncs [ index ] . precision = = CVRSpawnableSubSync . SyncPrecision . Full )
return EditorGUIUtility . singleLineHeight * 3.75f ;
return EditorGUIUtility . singleLineHeight * 5f ;
}
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
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);
2023-01-22 16:38:23 +01:00
}
2024-08-03 22:24:42 +02:00
#endregion
#region Private Methods
private void UpdateSubSyncCosts ( )
2023-01-22 16:38:23 +01:00
{
2024-08-03 22:24:42 +02:00
_subSyncCosts = 0f ;
2023-01-22 16:38:23 +01:00
2024-08-03 22:24:42 +02:00
foreach ( CVRSpawnableSubSync subSync in _spawnable . subSyncs )
2023-01-22 16:38:23 +01:00
{
if ( subSync . syncedValues . HasFlag ( CVRSpawnableSubSync . SyncFlags . TransformX ) )
2024-08-03 22:24:42 +02:00
_subSyncCosts + = ( int ) subSync . precision / 4f ;
2023-01-22 16:38:23 +01:00
if ( subSync . syncedValues . HasFlag ( CVRSpawnableSubSync . SyncFlags . TransformY ) )
2024-08-03 22:24:42 +02:00
_subSyncCosts + = ( int ) subSync . precision / 4f ;
2023-01-22 16:38:23 +01:00
if ( subSync . syncedValues . HasFlag ( CVRSpawnableSubSync . SyncFlags . TransformZ ) )
2024-08-03 22:24:42 +02:00
_subSyncCosts + = ( int ) subSync . precision / 4f ;
2023-01-22 16:38:23 +01:00
if ( subSync . syncedValues . HasFlag ( CVRSpawnableSubSync . SyncFlags . RotationX ) )
2024-08-03 22:24:42 +02:00
_subSyncCosts + = ( int ) subSync . precision / 4f ;
2023-01-22 16:38:23 +01:00
if ( subSync . syncedValues . HasFlag ( CVRSpawnableSubSync . SyncFlags . RotationY ) )
2024-08-03 22:24:42 +02:00
_subSyncCosts + = ( int ) subSync . precision / 4f ;
2023-01-22 16:38:23 +01:00
if ( subSync . syncedValues . HasFlag ( CVRSpawnableSubSync . SyncFlags . RotationZ ) )
2024-08-03 22:24:42 +02:00
_subSyncCosts + = ( int ) subSync . precision / 4f ;
2023-01-22 16:38:23 +01:00
}
}
2024-08-03 22:24:42 +02:00
#endregion
2023-01-22 16:38:23 +01:00
}
}