@@ -21,6 +21,10 @@ namespace Oculus.Movement.AnimationRigging
2121    [ CustomPropertyDrawer ( typeof ( RetargetingProcessor ) ,  true ) ] 
2222    public  class  RetargetingProcessorScriptableObjectDrawer  :  PropertyDrawer 
2323    { 
24+         private  const  int  buttonWidth  =  66 ; 
25+         private  static readonly  List < string >  ignoreClassFullNames  =  new  List < string >  {  "TMPro.TMP_FontAsset"  } ; 
26+ 
27+         /// <inheritdoc /> 
2428        public  override  float  GetPropertyHeight ( SerializedProperty  property ,  GUIContent  label ) 
2529        { 
2630            float  totalHeight  =  EditorGUIUtility . singleLineHeight ; 
@@ -39,7 +43,10 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent
3943                { 
4044                    do 
4145                    { 
42-                         if  ( prop . name  ==  "m_Script" )  continue ; 
46+                         if  ( prop . name  ==  "m_Script" ) 
47+                         { 
48+                             continue ; 
49+                         } 
4350                        var  subProp  =  serializedObject . FindProperty ( prop . name ) ; 
4451                        float  height  =  EditorGUI . GetPropertyHeight ( subProp ,  null ,  true )  + 
4552                                       EditorGUIUtility . standardVerticalSpacing ; 
@@ -55,10 +62,7 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent
5562            return  totalHeight ; 
5663        } 
5764
58-         const  int  buttonWidth  =  66 ; 
59- 
60-         static readonly  List < string >  ignoreClassFullNames  =  new  List < string >  {  "TMPro.TMP_FontAsset"  } ; 
61- 
65+         /// <inheritdoc /> 
6266        public  override  void  OnGUI ( Rect  position ,  SerializedProperty  property ,  GUIContent  label ) 
6367        { 
6468            EditorGUI . BeginProperty ( position ,  label ,  property ) ; 
@@ -98,24 +102,63 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
98102
99103            var  indentedPosition  =  EditorGUI . IndentedRect ( position ) ; 
100104            var  indentOffset  =  indentedPosition . x  -  position . x ; 
105+             var  saveToAssets  =  false ; 
106+             var  propertyWidth  =  buttonWidth ; 
101107            propertyRect  =  new  Rect ( position . x  +  ( EditorGUIUtility . labelWidth  -  indentOffset ) ,  position . y , 
102108                position . width  -  ( EditorGUIUtility . labelWidth  -  indentOffset ) ,  EditorGUIUtility . singleLineHeight ) ; 
103109
104-             if  ( propertySO  !=  null  ||  property . objectReferenceValue  ==  null ) 
110+             if  ( property . propertyType  ==  SerializedPropertyType . ObjectReference  && 
111+                 property . objectReferenceValue  !=  null ) 
112+             { 
113+                 var  data  =  ( ScriptableObject ) property . objectReferenceValue ; 
114+                 if  ( ! AssetDatabase . Contains ( data ) ) 
115+                 { 
116+                     saveToAssets  =  true ; 
117+                     propertyWidth  =  Mathf . RoundToInt ( buttonWidth  *  1.5f ) ; 
118+                 } 
119+             } 
120+ 
121+             if  ( propertySO  !=  null  ||  property . objectReferenceValue  ==  null  ||  saveToAssets ) 
105122            { 
106-                 propertyRect . width  -=  buttonWidth ; 
123+                 propertyRect . width  -=  propertyWidth ; 
107124            } 
108125
109126            EditorGUI . ObjectField ( propertyRect ,  property ,  type ,  GUIContent . none ) ; 
110-             if  ( GUI . changed )  property . serializedObject . ApplyModifiedProperties ( ) ; 
127+             if  ( GUI . changed ) 
128+             { 
129+                 property . serializedObject . ApplyModifiedProperties ( ) ; 
130+             } 
111131
112-             var  buttonRect  =  new  Rect ( position . x  +  position . width  -  buttonWidth ,  position . y ,  buttonWidth , 
132+             var  buttonRect  =  new  Rect ( position . x  +  position . width  -  propertyWidth ,  position . y ,  propertyWidth , 
113133                EditorGUIUtility . singleLineHeight ) ; 
114134
115135            if  ( property . propertyType  ==  SerializedPropertyType . ObjectReference  &&  property . objectReferenceValue  !=  null ) 
116136            { 
117137                var  data  =  ( ScriptableObject ) property . objectReferenceValue ; 
118138
139+                 if  ( saveToAssets ) 
140+                 { 
141+                     if  ( GUI . Button ( buttonRect ,  "Save to Assets" ) ) 
142+                     { 
143+                         string  selectedAssetPath  =  "Assets" ; 
144+                         if  ( property . serializedObject . targetObject  is  MonoBehaviour ) 
145+                         { 
146+                             MonoScript  ms  =  MonoScript . FromMonoBehaviour ( ( MonoBehaviour ) property . serializedObject . targetObject ) ; 
147+                             selectedAssetPath  =  System . IO . Path . GetDirectoryName ( AssetDatabase . GetAssetPath ( ms ) ) ; 
148+                         } 
149+ 
150+                         var  replacementObject  =  ReplaceAssetWithSavePrompt ( data . GetType ( ) ,  selectedAssetPath ,  data  as  RetargetingProcessor ) ; 
151+                         if  ( replacementObject  !=  null ) 
152+                         { 
153+                             Undo . DestroyObjectImmediate ( data ) ; 
154+                             property . objectReferenceValue  =  replacementObject ; 
155+                         } 
156+                         property . serializedObject . ApplyModifiedProperties ( ) ; 
157+                         GUIUtility . ExitGUI ( ) ; 
158+                         return ; 
159+                     } 
160+                 } 
161+ 
119162                if  ( property . isExpanded ) 
120163                { 
121164                    // Draw a background that shows us clearly which fields are part of the ScriptableObject 
@@ -137,7 +180,10 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
137180                        do 
138181                        { 
139182                            // Don't bother drawing the class file 
140-                             if  ( prop . name  ==  "m_Script" )  continue ; 
183+                             if  ( prop . name  ==  "m_Script" ) 
184+                             { 
185+                                 continue ; 
186+                             } 
141187                            float  height  =  EditorGUI . GetPropertyHeight ( prop ,  new  GUIContent ( prop . displayName ) ,  true ) ; 
142188                            EditorGUI . PropertyField ( new  Rect ( position . x ,  y ,  position . width  -  buttonWidth ,  height ) ,  prop , 
143189                                true ) ; 
@@ -146,7 +192,9 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
146192                    } 
147193
148194                    if  ( GUI . changed ) 
195+                     { 
149196                        serializedObject . ApplyModifiedProperties ( ) ; 
197+                     } 
150198                    serializedObject . Dispose ( ) ; 
151199                    EditorGUI . indentLevel -- ; 
152200                } 
@@ -163,19 +211,22 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
163211                    } 
164212
165213                    property . objectReferenceValue  =  CreateAssetWithSavePrompt ( type ,  selectedAssetPath ) ; 
214+                     property . serializedObject . ApplyModifiedProperties ( ) ; 
215+                     GUIUtility . ExitGUI ( ) ; 
216+                     return ; 
166217                } 
167218            } 
168219
169220            property . serializedObject . ApplyModifiedProperties ( ) ; 
170221            EditorGUI . EndProperty ( ) ; 
171222        } 
172223
173-         public  static T  _GUILayout < T > ( string  label ,  T  objectReferenceValue ,  ref  bool  isExpanded )  where  T  :  ScriptableObject 
224+         private  static T  _GUILayout < T > ( string  label ,  T  objectReferenceValue ,  ref  bool  isExpanded )  where  T  :  ScriptableObject 
174225        { 
175226            return  _GUILayout < T > ( new  GUIContent ( label ) ,  objectReferenceValue ,  ref  isExpanded ) ; 
176227        } 
177228
178-         public  static T  _GUILayout < T > ( GUIContent  label ,  T  objectReferenceValue ,  ref  bool  isExpanded ) 
229+         private  static T  _GUILayout < T > ( GUIContent  label ,  T  objectReferenceValue ,  ref  bool  isExpanded ) 
179230            where  T  :  ScriptableObject 
180231        { 
181232            Rect  position  =  EditorGUILayout . BeginVertical ( ) ; 
@@ -239,7 +290,7 @@ public static T _GUILayout<T>(GUIContent label, T objectReferenceValue, ref bool
239290            return  objectReferenceValue ; 
240291        } 
241292
242-         static void  DrawScriptableObjectChildFields < T > ( T  objectReferenceValue )  where  T  :  ScriptableObject 
293+         private   static void  DrawScriptableObjectChildFields < T > ( T  objectReferenceValue )  where  T  :  ScriptableObject 
243294        { 
244295            // Draw a background that shows us clearly which fields are part of the ScriptableObject 
245296            EditorGUI . indentLevel ++ ; 
@@ -259,13 +310,15 @@ static void DrawScriptableObjectChildFields<T>(T objectReferenceValue) where T :
259310            } 
260311
261312            if  ( GUI . changed ) 
313+             { 
262314                serializedObject . ApplyModifiedProperties ( ) ; 
315+             } 
263316            serializedObject . Dispose ( ) ; 
264317            EditorGUILayout . EndVertical ( ) ; 
265318            EditorGUI . indentLevel -- ; 
266319        } 
267320
268-         public  static T  DrawScriptableObjectField < T > ( GUIContent  label ,  T  objectReferenceValue ,  ref  bool  isExpanded ) 
321+         private  static T  DrawScriptableObjectField < T > ( GUIContent  label ,  T  objectReferenceValue ,  ref  bool  isExpanded ) 
269322            where  T  :  ScriptableObject 
270323        { 
271324            Rect  position  =  EditorGUILayout . BeginVertical ( ) ; 
@@ -329,11 +382,14 @@ public static T DrawScriptableObjectField<T>(GUIContent label, T objectReference
329382        } 
330383
331384        // Creates a new ScriptableObject via the default Save File panel 
332-         static ScriptableObject  CreateAssetWithSavePrompt ( Type  type ,  string  path ) 
385+         private   static ScriptableObject  CreateAssetWithSavePrompt ( Type  type ,  string  path ) 
333386        { 
334387            path  =  EditorUtility . SaveFilePanelInProject ( "Save ScriptableObject" ,  type . Name  +  ".asset" ,  "asset" , 
335388                "Enter a file name for the ScriptableObject." ,  path ) ; 
336-             if  ( path  ==  "" )  return  null ; 
389+             if  ( path  ==  "" ) 
390+             { 
391+                 return  null ; 
392+             } 
337393            ScriptableObject  asset  =  ScriptableObject . CreateInstance ( type ) ; 
338394            AssetDatabase . CreateAsset ( asset ,  path ) ; 
339395            AssetDatabase . SaveAssets ( ) ; 
@@ -343,16 +399,43 @@ static ScriptableObject CreateAssetWithSavePrompt(Type type, string path)
343399            return  asset ; 
344400        } 
345401
346-         Type  GetFieldType ( ) 
402+         private  static ScriptableObject  ReplaceAssetWithSavePrompt ( Type  type ,  string  path ,  RetargetingProcessor  processor ) 
403+         { 
404+             path  =  EditorUtility . SaveFilePanelInProject ( "Save ScriptableObject" ,  processor . name  +  ".asset" ,  "asset" , 
405+                 "Enter a file name for the ScriptableObject." ,  path ) ; 
406+             if  ( path  ==  "" ) 
407+             { 
408+                 return  null ; 
409+             } 
410+             ScriptableObject  asset  =  ScriptableObject . CreateInstance ( type ) ; 
411+             var  newProcessor  =  asset  as  RetargetingProcessor ; 
412+             if  ( newProcessor  !=  null ) 
413+             { 
414+                 newProcessor . CopyData ( processor ) ; 
415+             } 
416+             AssetDatabase . CreateAsset ( asset ,  path ) ; 
417+             AssetDatabase . SaveAssets ( ) ; 
418+             AssetDatabase . Refresh ( ) ; 
419+             AssetDatabase . ImportAsset ( path ,  ImportAssetOptions . ForceUpdate ) ; 
420+             EditorGUIUtility . PingObject ( asset ) ; 
421+             return  asset ; 
422+         } 
423+ 
424+         private  Type  GetFieldType ( ) 
347425        { 
348426            Type  type  =  fieldInfo . FieldType ; 
349-             if  ( type . IsArray )  type  =  type . GetElementType ( ) ; 
427+             if  ( type . IsArray ) 
428+             { 
429+                 type  =  type . GetElementType ( ) ; 
430+             } 
350431            else  if  ( type . IsGenericType  &&  type . GetGenericTypeDefinition ( )  ==  typeof ( List < > ) ) 
432+             { 
351433                type  =  type . GetGenericArguments ( ) [ 0 ] ; 
434+             } 
352435            return  type ; 
353436        } 
354437
355-         static bool  AreAnySubPropertiesVisible ( SerializedProperty  property ) 
438+         private   static bool  AreAnySubPropertiesVisible ( SerializedProperty  property ) 
356439        { 
357440            var  data  =  ( ScriptableObject ) property . objectReferenceValue ; 
358441            SerializedObject  serializedObject  =  new  SerializedObject ( data ) ; 
0 commit comments