11using System ;
22using System . Linq ;
33using System . Reflection ;
4+ using System . Runtime . CompilerServices ;
45using UnityEngine ;
56using UnityEngine . Rendering . HighDefinition ;
67using UnityEngine . Rendering ;
@@ -62,6 +63,8 @@ enum ShutterSpeedUnit
6263 "Custom"
6364 } ;
6465
66+ static readonly int k_CustomPresetIndex = k_ApertureFormatNames . Length - 1 ;
67+
6568 static readonly Vector2 [ ] k_ApertureFormatValues =
6669 {
6770 new Vector2 ( 4.8f , 3.5f ) ,
@@ -76,6 +79,10 @@ enum ShutterSpeedUnit
7679 new Vector2 ( 70.41f , 52.63f )
7780 } ;
7881
82+ // Saves the value of the sensor size when the user switches from "custom" size to a preset per camera.
83+ // We use a ConditionalWeakTable instead of a Dictionary to avoid keeping alive (with strong references) deleted cameras
84+ static ConditionalWeakTable < Camera , object > s_PerCameraSensorSizeHistory = new ConditionalWeakTable < Camera , object > ( ) ;
85+
7986 static bool s_FovChanged ;
8087 static float s_FovLastValue ;
8188
@@ -298,14 +305,51 @@ static void Drawer_PhysicalCamera(SerializedHDCamera p, Editor owner)
298305 using ( new EditorGUI . IndentLevelScope ( ) )
299306 {
300307 EditorGUI . BeginChangeCheck ( ) ;
301- int filmGateIndex = Array . IndexOf ( k_ApertureFormatValues , new Vector2 ( ( float ) Math . Round ( cam . sensorSize . vector2Value . x , 3 ) , ( float ) Math . Round ( cam . sensorSize . vector2Value . y , 3 ) ) ) ;
302- if ( filmGateIndex == - 1 )
303- filmGateIndex = EditorGUILayout . Popup ( cameraTypeContent , k_ApertureFormatNames . Length - 1 , k_ApertureFormatNames ) ;
304- else
305- filmGateIndex = EditorGUILayout . Popup ( cameraTypeContent , filmGateIndex , k_ApertureFormatNames ) ;
306308
307- if ( EditorGUI . EndChangeCheck ( ) && filmGateIndex < k_ApertureFormatValues . Length )
308- cam . sensorSize . vector2Value = k_ApertureFormatValues [ filmGateIndex ] ;
309+ int oldFilmGateIndex = Array . IndexOf ( k_ApertureFormatValues , new Vector2 ( ( float ) Math . Round ( cam . sensorSize . vector2Value . x , 3 ) , ( float ) Math . Round ( cam . sensorSize . vector2Value . y , 3 ) ) ) ;
310+
311+ // If it is not one of the preset sizes, set it to custom
312+ oldFilmGateIndex = ( oldFilmGateIndex == - 1 ) ? k_CustomPresetIndex : oldFilmGateIndex ;
313+
314+ // Get the new user selection
315+ int newFilmGateIndex = EditorGUILayout . Popup ( cameraTypeContent , oldFilmGateIndex , k_ApertureFormatNames ) ;
316+
317+ if ( EditorGUI . EndChangeCheck ( ) )
318+ {
319+ // Retrieve the previous custom size value, if one exists for this camera
320+ object previousCustomValue ;
321+ s_PerCameraSensorSizeHistory . TryGetValue ( ( Camera ) p . serializedObject . targetObject , out previousCustomValue ) ;
322+
323+ // When switching from custom to a preset, update the last custom value (to display again, in case the user switches back to custom)
324+ if ( oldFilmGateIndex == k_CustomPresetIndex )
325+ {
326+ if ( previousCustomValue == null )
327+ {
328+ s_PerCameraSensorSizeHistory . Add ( ( Camera ) p . serializedObject . targetObject , cam . sensorSize . vector2Value ) ;
329+ }
330+ else
331+ {
332+ previousCustomValue = cam . sensorSize . vector2Value ;
333+ }
334+ }
335+
336+ if ( newFilmGateIndex < k_CustomPresetIndex )
337+ {
338+ cam . sensorSize . vector2Value = k_ApertureFormatValues [ newFilmGateIndex ] ;
339+ }
340+ else
341+ {
342+ // The user switched back to custom, so display by deafulr the previous custom value
343+ if ( previousCustomValue != null )
344+ {
345+ cam . sensorSize . vector2Value = ( Vector2 ) previousCustomValue ;
346+ }
347+ else
348+ {
349+ cam . sensorSize . vector2Value = new Vector2 ( 36.0f , 24.0f ) ; // this is the value new cameras are created with
350+ }
351+ }
352+ }
309353
310354 EditorGUILayout . PropertyField ( cam . sensorSize , sensorSizeContent ) ;
311355 EditorGUILayout . PropertyField ( p . iso , isoContent ) ;
0 commit comments