Geen omschrijving
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UniversalRenderPipelineLightUI.Drawers.cs 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. using System;
  2. using System.Linq;
  3. using System.Linq.Expressions;
  4. using System.Reflection;
  5. using UnityEngine;
  6. using UnityEngine.Rendering;
  7. using UnityEngine.Rendering.Universal;
  8. #if XR_MANAGEMENT_4_0_1_OR_NEWER
  9. using UnityEditor.XR.Management;
  10. #endif
  11. namespace UnityEditor.Rendering.Universal
  12. {
  13. using CED = CoreEditorDrawer<UniversalRenderPipelineSerializedLight>;
  14. internal partial class UniversalRenderPipelineLightUI
  15. {
  16. [URPHelpURL("light-component")]
  17. enum Expandable
  18. {
  19. General = 1 << 0,
  20. Shape = 1 << 1,
  21. Emission = 1 << 2,
  22. Rendering = 1 << 3,
  23. Shadows = 1 << 4,
  24. LightCookie = 1 << 5
  25. }
  26. static readonly ExpandedState<Expandable, Light> k_ExpandedState = new(~-1, "URP");
  27. public static readonly CED.IDrawer Inspector = CED.Group(
  28. CED.Conditional(
  29. (_, __) =>
  30. {
  31. if (SceneView.lastActiveSceneView == null)
  32. return false;
  33. #if UNITY_2019_1_OR_NEWER
  34. var sceneLighting = SceneView.lastActiveSceneView.sceneLighting;
  35. #else
  36. var sceneLighting = SceneView.lastActiveSceneView.m_SceneLighting;
  37. #endif
  38. return !sceneLighting;
  39. },
  40. (_, __) => EditorGUILayout.HelpBox(Styles.DisabledLightWarning.text, MessageType.Warning)),
  41. CED.FoldoutGroup(LightUI.Styles.generalHeader,
  42. Expandable.General,
  43. k_ExpandedState,
  44. DrawGeneralContent),
  45. CED.Conditional(
  46. (serializedLight, editor) => !serializedLight.settings.lightType.hasMultipleDifferentValues && serializedLight.settings.light.type == LightType.Spot,
  47. CED.FoldoutGroup(LightUI.Styles.shapeHeader, Expandable.Shape, k_ExpandedState, DrawSpotShapeContent)),
  48. CED.Conditional(
  49. (serializedLight, editor) =>
  50. {
  51. if (serializedLight.settings.lightType.hasMultipleDifferentValues)
  52. return false;
  53. var lightType = serializedLight.settings.light.type;
  54. return lightType == LightType.Rectangle || lightType == LightType.Disc;
  55. },
  56. CED.FoldoutGroup(LightUI.Styles.shapeHeader, Expandable.Shape, k_ExpandedState, DrawAreaShapeContent)),
  57. CED.FoldoutGroup(LightUI.Styles.emissionHeader,
  58. Expandable.Emission,
  59. k_ExpandedState,
  60. CED.Group(
  61. LightUI.DrawColor,
  62. DrawEmissionContent)),
  63. CED.FoldoutGroup(LightUI.Styles.renderingHeader,
  64. Expandable.Rendering,
  65. k_ExpandedState,
  66. DrawRenderingContent),
  67. CED.FoldoutGroup(LightUI.Styles.shadowHeader,
  68. Expandable.Shadows,
  69. k_ExpandedState,
  70. DrawShadowsContent)
  71. );
  72. static Func<int> s_SetGizmosDirty = SetGizmosDirty();
  73. static Func<int> SetGizmosDirty()
  74. {
  75. var type = Type.GetType("UnityEditor.AnnotationUtility,UnityEditor");
  76. var method = type.GetMethod("SetGizmosDirty", BindingFlags.Static | BindingFlags.NonPublic);
  77. var lambda = Expression.Lambda<Func<int>>(Expression.Call(method));
  78. return lambda.Compile();
  79. }
  80. static Action<GUIContent, SerializedProperty, LightEditor.Settings> k_SliderWithTexture = GetSliderWithTexture();
  81. static Action<GUIContent, SerializedProperty, LightEditor.Settings> GetSliderWithTexture()
  82. {
  83. //quicker than standard reflection as it is compiled
  84. var paramLabel = Expression.Parameter(typeof(GUIContent), "label");
  85. var paramProperty = Expression.Parameter(typeof(SerializedProperty), "property");
  86. var paramSettings = Expression.Parameter(typeof(LightEditor.Settings), "settings");
  87. System.Reflection.MethodInfo sliderWithTextureInfo = typeof(EditorGUILayout)
  88. .GetMethod(
  89. "SliderWithTexture",
  90. System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static,
  91. null,
  92. System.Reflection.CallingConventions.Any,
  93. new[] { typeof(GUIContent), typeof(SerializedProperty), typeof(float), typeof(float), typeof(float), typeof(Texture2D), typeof(GUILayoutOption[]) },
  94. null);
  95. var sliderWithTextureCall = Expression.Call(
  96. sliderWithTextureInfo,
  97. paramLabel,
  98. paramProperty,
  99. Expression.Constant((float)typeof(LightEditor.Settings).GetField("kMinKelvin", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetRawConstantValue()),
  100. Expression.Constant((float)typeof(LightEditor.Settings).GetField("kMaxKelvin", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetRawConstantValue()),
  101. Expression.Constant((float)typeof(LightEditor.Settings).GetField("kSliderPower", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetRawConstantValue()),
  102. Expression.Field(paramSettings, typeof(LightEditor.Settings).GetField("m_KelvinGradientTexture", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)),
  103. Expression.Constant(null, typeof(GUILayoutOption[])));
  104. var lambda = Expression.Lambda<System.Action<GUIContent, SerializedProperty, LightEditor.Settings>>(sliderWithTextureCall, paramLabel, paramProperty, paramSettings);
  105. return lambda.Compile();
  106. }
  107. static void DrawGeneralContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
  108. {
  109. DrawGeneralContentInternal(serializedLight, owner, isInPreset: false);
  110. }
  111. static void DrawGeneralContentPreset(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
  112. {
  113. DrawGeneralContentInternal(serializedLight, owner, isInPreset: true);
  114. }
  115. static void DrawGeneralContentInternal(UniversalRenderPipelineSerializedLight serializedLight, Editor owner, bool isInPreset)
  116. {
  117. // To the user, we will only display it as a area light, but under the hood, we have Rectangle and Disc. This is not to confuse people
  118. // who still use our legacy light inspector.
  119. int selectedLightType = serializedLight.settings.lightType.intValue;
  120. // Handle all lights that are not in the default set
  121. if (!Styles.LightTypeValues.Contains(serializedLight.settings.lightType.intValue))
  122. {
  123. if (serializedLight.settings.lightType.intValue == (int)LightType.Disc)
  124. {
  125. selectedLightType = (int)LightType.Rectangle;
  126. }
  127. }
  128. var rect = EditorGUILayout.GetControlRect();
  129. EditorGUI.BeginProperty(rect, Styles.Type, serializedLight.settings.lightType);
  130. EditorGUI.BeginChangeCheck();
  131. int type;
  132. if (Styles.LightTypeValues.Contains(selectedLightType))
  133. {
  134. // ^ The currently selected light type is supported in the
  135. // current pipeline.
  136. type = EditorGUI.IntPopup(rect, Styles.Type, selectedLightType, Styles.LightTypeTitles, Styles.LightTypeValues);
  137. }
  138. else
  139. {
  140. // ^ The currently selected light type is not supported in
  141. // the current pipeline. Add it to the dropdown, since it
  142. // would show up as a blank entry.
  143. string currentTitle = ((LightType)selectedLightType).ToString();
  144. GUIContent[] titles = Styles.LightTypeTitles.Append(EditorGUIUtility.TrTextContent(currentTitle)).ToArray();
  145. int[] values = Styles.LightTypeValues.Append(selectedLightType).ToArray();
  146. type = EditorGUI.IntPopup(rect, Styles.Type, selectedLightType, titles, values);
  147. }
  148. if (EditorGUI.EndChangeCheck())
  149. {
  150. s_SetGizmosDirty();
  151. serializedLight.settings.lightType.intValue = type;
  152. }
  153. EditorGUI.EndProperty();
  154. if (!Styles.LightTypeValues.Contains(type))
  155. {
  156. EditorGUILayout.HelpBox(
  157. "This light type is not supported in the current active render pipeline. Change the light type or the active Render Pipeline to use this light.",
  158. MessageType.Info
  159. );
  160. }
  161. Light light = serializedLight.settings.light;
  162. var lightType = light.type;
  163. if (LightType.Directional != lightType && light == RenderSettings.sun)
  164. {
  165. EditorGUILayout.HelpBox(Styles.SunSourceWarning.text, MessageType.Warning);
  166. }
  167. if (!serializedLight.settings.lightType.hasMultipleDifferentValues)
  168. {
  169. using (new EditorGUI.DisabledScope(serializedLight.settings.isAreaLightType))
  170. serializedLight.settings.DrawLightmapping();
  171. if (serializedLight.settings.isAreaLightType && serializedLight.settings.lightmapping.intValue != (int)LightmapBakeType.Baked)
  172. {
  173. serializedLight.settings.lightmapping.intValue = (int)LightmapBakeType.Baked;
  174. serializedLight.Apply();
  175. }
  176. }
  177. }
  178. internal static void SyncLightAndShadowLayers(UniversalRenderPipelineSerializedLight serializedLight, SerializedProperty serialized)
  179. {
  180. // If we're not in decoupled mode for light layers, we sync light with shadow layers.
  181. // In mixed state, it makes sense to do it only on Light that links the mode.
  182. foreach (var lightTarget in serializedLight.serializedObject.targetObjects)
  183. {
  184. var additionData = (lightTarget as Component).gameObject.GetComponent<UniversalAdditionalLightData>();
  185. if (additionData.customShadowLayers)
  186. continue;
  187. Light target = lightTarget as Light;
  188. if (target.renderingLayerMask != serialized.intValue)
  189. target.renderingLayerMask = serialized.intValue;
  190. }
  191. }
  192. static void DrawSpotShapeContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
  193. {
  194. serializedLight.settings.DrawInnerAndOuterSpotAngle();
  195. }
  196. static void DrawAreaShapeContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
  197. {
  198. int selectedShape = serializedLight.settings.isAreaLightType ? serializedLight.settings.lightType.intValue : 0;
  199. // Handle all lights that are not in the default set
  200. if (!Styles.LightTypeValues.Contains(serializedLight.settings.lightType.intValue))
  201. {
  202. if (serializedLight.settings.lightType.intValue == (int)LightType.Disc)
  203. {
  204. selectedShape = (int)LightType.Disc;
  205. }
  206. }
  207. var rect = EditorGUILayout.GetControlRect();
  208. EditorGUI.BeginProperty(rect, Styles.AreaLightShapeContent, serializedLight.settings.lightType);
  209. EditorGUI.BeginChangeCheck();
  210. int shape = EditorGUI.IntPopup(rect, Styles.AreaLightShapeContent, selectedShape, Styles.AreaLightShapeTitles, Styles.AreaLightShapeValues);
  211. if (EditorGUI.EndChangeCheck())
  212. {
  213. Undo.RecordObject(serializedLight.settings.light, "Adjust Light Shape");
  214. serializedLight.settings.lightType.intValue = shape;
  215. }
  216. EditorGUI.EndProperty();
  217. using (new EditorGUI.IndentLevelScope())
  218. serializedLight.settings.DrawArea();
  219. }
  220. static void DrawEmissionContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
  221. {
  222. serializedLight.settings.DrawIntensity();
  223. serializedLight.settings.DrawBounceIntensity();
  224. if (!serializedLight.settings.lightType.hasMultipleDifferentValues)
  225. {
  226. var lightType = serializedLight.settings.light.type;
  227. if (lightType != LightType.Directional)
  228. {
  229. #if UNITY_2020_1_OR_NEWER
  230. serializedLight.settings.DrawRange();
  231. #else
  232. serializedLight.settings.DrawRange(false);
  233. #endif
  234. }
  235. }
  236. DrawLightCookieContent(serializedLight, owner);
  237. }
  238. static void DrawRenderingContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
  239. {
  240. if (serializedLight.settings.light.type != LightType.Rectangle &&
  241. !serializedLight.settings.isCompletelyBaked)
  242. {
  243. EditorGUI.BeginChangeCheck();
  244. GUI.enabled = UniversalRenderPipeline.asset.useRenderingLayers;
  245. EditorUtils.DrawRenderingLayerMask(
  246. serializedLight.renderingLayers,
  247. UniversalRenderPipeline.asset.useRenderingLayers ? Styles.RenderingLayers : Styles.RenderingLayersDisabled
  248. );
  249. GUI.enabled = true;
  250. if (EditorGUI.EndChangeCheck())
  251. {
  252. if (!serializedLight.customShadowLayers.boolValue)
  253. SyncLightAndShadowLayers(serializedLight, serializedLight.renderingLayers);
  254. }
  255. }
  256. EditorGUILayout.PropertyField(serializedLight.settings.cullingMask, Styles.CullingMask);
  257. if (serializedLight.settings.cullingMask.intValue != -1)
  258. {
  259. EditorGUILayout.HelpBox(Styles.CullingMaskWarning.text, MessageType.Info);
  260. }
  261. }
  262. static void DrawShadowsContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
  263. {
  264. if (serializedLight.settings.lightType.hasMultipleDifferentValues)
  265. {
  266. EditorGUILayout.HelpBox("Cannot multi edit shadows from different light types.", MessageType.Info);
  267. return;
  268. }
  269. serializedLight.settings.DrawShadowsType();
  270. if (serializedLight.settings.shadowsType.hasMultipleDifferentValues)
  271. {
  272. EditorGUILayout.HelpBox("Cannot multi edit different shadow types", MessageType.Info);
  273. return;
  274. }
  275. if (serializedLight.settings.light.shadows == LightShadows.None)
  276. return;
  277. var lightType = serializedLight.settings.light.type;
  278. using (new EditorGUI.IndentLevelScope())
  279. {
  280. if (serializedLight.settings.isBakedOrMixed)
  281. {
  282. switch (lightType)
  283. {
  284. // Baked Shadow radius
  285. case LightType.Point:
  286. case LightType.Spot:
  287. serializedLight.settings.DrawBakedShadowRadius();
  288. break;
  289. case LightType.Directional:
  290. serializedLight.settings.DrawBakedShadowAngle();
  291. break;
  292. }
  293. }
  294. if (lightType != LightType.Rectangle && !serializedLight.settings.isCompletelyBaked)
  295. {
  296. EditorGUILayout.LabelField(Styles.ShadowRealtimeSettings, EditorStyles.boldLabel);
  297. using (new EditorGUI.IndentLevelScope())
  298. {
  299. // Resolution
  300. if (lightType == LightType.Point || lightType == LightType.Spot)
  301. DrawShadowsResolutionGUI(serializedLight);
  302. EditorGUILayout.Slider(serializedLight.settings.shadowsStrength, 0f, 1f, Styles.ShadowStrength);
  303. // Bias
  304. DrawAdditionalShadowData(serializedLight, owner);
  305. // this min bound should match the calculation in SharedLightData::GetNearPlaneMinBound()
  306. float nearPlaneMinBound = Mathf.Min(0.01f * serializedLight.settings.range.floatValue, 0.1f);
  307. EditorGUILayout.Slider(serializedLight.settings.shadowsNearPlane, nearPlaneMinBound, 10.0f, Styles.ShadowNearPlane);
  308. var isHololens = false;
  309. var isQuest = false;
  310. #if XR_MANAGEMENT_4_0_1_OR_NEWER
  311. var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
  312. var buildTargetSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(buildTargetGroup);
  313. if (buildTargetSettings != null && buildTargetSettings.AssignedSettings != null && buildTargetSettings.AssignedSettings.activeLoaders.Count > 0)
  314. {
  315. isHololens = buildTargetGroup == BuildTargetGroup.WSA;
  316. isQuest = buildTargetGroup == BuildTargetGroup.Android;
  317. }
  318. #endif
  319. // Soft Shadow Quality
  320. if (serializedLight.settings.light.shadows == LightShadows.Soft)
  321. EditorGUILayout.PropertyField(serializedLight.softShadowQualityProp, Styles.SoftShadowQuality);
  322. if (isHololens || isQuest)
  323. {
  324. EditorGUILayout.HelpBox(
  325. "Per-light soft shadow quality level is not supported on HoloLens and Oculus platforms. Use the Soft Shadow Quality setting in the URP Asset instead",
  326. MessageType.Warning
  327. );
  328. }
  329. }
  330. if (UniversalRenderPipeline.asset.useRenderingLayers)
  331. {
  332. EditorGUI.BeginChangeCheck();
  333. EditorGUILayout.PropertyField(serializedLight.customShadowLayers, Styles.customShadowLayers);
  334. // Undo the changes in the light component because the SyncLightAndShadowLayers will change the value automatically when link is ticked
  335. if (EditorGUI.EndChangeCheck())
  336. {
  337. if (serializedLight.customShadowLayers.boolValue)
  338. {
  339. serializedLight.settings.light.renderingLayerMask = serializedLight.shadowRenderingLayers.intValue;
  340. }
  341. else
  342. {
  343. serializedLight.serializedAdditionalDataObject.ApplyModifiedProperties(); // we need to push above modification the modification on object as it is used to sync
  344. SyncLightAndShadowLayers(serializedLight, serializedLight.renderingLayers);
  345. }
  346. }
  347. if (serializedLight.customShadowLayers.boolValue)
  348. {
  349. using (new EditorGUI.IndentLevelScope())
  350. {
  351. EditorGUI.BeginChangeCheck();
  352. EditorUtils.DrawRenderingLayerMask(serializedLight.shadowRenderingLayers, Styles.ShadowLayer);
  353. if (EditorGUI.EndChangeCheck())
  354. {
  355. serializedLight.settings.light.renderingLayerMask = serializedLight.shadowRenderingLayers.intValue;
  356. serializedLight.Apply();
  357. }
  358. }
  359. }
  360. }
  361. }
  362. }
  363. if (!UnityEditor.Lightmapping.bakedGI && !serializedLight.settings.lightmapping.hasMultipleDifferentValues && serializedLight.settings.isBakedOrMixed)
  364. EditorGUILayout.HelpBox(Styles.BakingWarning.text, MessageType.Warning);
  365. }
  366. static void DrawAdditionalShadowData(UniversalRenderPipelineSerializedLight serializedLight, Editor editor)
  367. {
  368. // 0: Custom bias - 1: Bias values defined in Pipeline settings
  369. int selectedUseAdditionalData = serializedLight.additionalLightData.usePipelineSettings ? 1 : 0;
  370. Rect r = EditorGUILayout.GetControlRect(true);
  371. EditorGUI.BeginProperty(r, Styles.shadowBias, serializedLight.useAdditionalDataProp);
  372. {
  373. using (var checkScope = new EditorGUI.ChangeCheckScope())
  374. {
  375. selectedUseAdditionalData = EditorGUI.IntPopup(r, Styles.shadowBias, selectedUseAdditionalData, Styles.displayedDefaultOptions, Styles.optionDefaultValues);
  376. if (checkScope.changed)
  377. {
  378. Undo.RecordObjects(serializedLight.lightsAdditionalData, "Modified light additional data");
  379. foreach (var additionData in serializedLight.lightsAdditionalData)
  380. additionData.usePipelineSettings = selectedUseAdditionalData != 0;
  381. serializedLight.Apply();
  382. (editor as UniversalRenderPipelineLightEditor)?.ReconstructReferenceToAdditionalDataSO();
  383. }
  384. }
  385. }
  386. EditorGUI.EndProperty();
  387. if (!serializedLight.useAdditionalDataProp.hasMultipleDifferentValues)
  388. {
  389. if (selectedUseAdditionalData != 1) // Custom Bias
  390. {
  391. using (new EditorGUI.IndentLevelScope())
  392. {
  393. using (var checkScope = new EditorGUI.ChangeCheckScope())
  394. {
  395. EditorGUILayout.Slider(serializedLight.settings.shadowsBias, 0f, 10f, Styles.ShadowDepthBias);
  396. EditorGUILayout.Slider(serializedLight.settings.shadowsNormalBias, 0f, 10f, Styles.ShadowNormalBias);
  397. if (checkScope.changed)
  398. serializedLight.Apply();
  399. }
  400. }
  401. }
  402. }
  403. }
  404. static void DrawShadowsResolutionGUI(UniversalRenderPipelineSerializedLight serializedLight)
  405. {
  406. int shadowResolutionTier = serializedLight.additionalLightData.additionalLightsShadowResolutionTier;
  407. using (new EditorGUILayout.HorizontalScope())
  408. {
  409. using (var checkScope = new EditorGUI.ChangeCheckScope())
  410. {
  411. Rect r = EditorGUILayout.GetControlRect(true);
  412. r.width += 30;
  413. shadowResolutionTier = EditorGUI.IntPopup(r, Styles.ShadowResolution, shadowResolutionTier, Styles.ShadowResolutionDefaultOptions, Styles.ShadowResolutionDefaultValues);
  414. if (shadowResolutionTier == UniversalAdditionalLightData.AdditionalLightsShadowResolutionTierCustom)
  415. {
  416. // show the custom value field GUI.
  417. var newResolution = EditorGUILayout.IntField(serializedLight.settings.shadowsResolution.intValue, GUILayout.ExpandWidth(false));
  418. serializedLight.settings.shadowsResolution.intValue = Mathf.Max(UniversalAdditionalLightData.AdditionalLightsShadowMinimumResolution, Mathf.NextPowerOfTwo(newResolution));
  419. }
  420. else
  421. {
  422. if (GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset urpAsset)
  423. EditorGUILayout.LabelField($"{urpAsset.GetAdditionalLightsShadowResolution(shadowResolutionTier)} ({urpAsset.name})", GUILayout.ExpandWidth(false));
  424. }
  425. if (checkScope.changed)
  426. {
  427. serializedLight.additionalLightsShadowResolutionTierProp.intValue = shadowResolutionTier;
  428. serializedLight.Apply();
  429. }
  430. }
  431. }
  432. EditorGUILayout.HelpBox(Styles.ShadowInfo.text, MessageType.Info);
  433. }
  434. static void DrawLightCookieContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
  435. {
  436. var settings = serializedLight.settings;
  437. if (settings.lightType.hasMultipleDifferentValues)
  438. {
  439. EditorGUILayout.HelpBox("Cannot multi edit light cookies from different light types.", MessageType.Info);
  440. return;
  441. }
  442. settings.DrawCookie();
  443. // Draw 2D cookie size for directional lights
  444. bool isDirectionalLight = settings.light.type == LightType.Directional;
  445. if (isDirectionalLight)
  446. {
  447. if (settings.cookie != null)
  448. {
  449. EditorGUI.BeginChangeCheck();
  450. EditorGUILayout.PropertyField(serializedLight.lightCookieSizeProp, Styles.LightCookieSize);
  451. EditorGUILayout.PropertyField(serializedLight.lightCookieOffsetProp, Styles.LightCookieOffset);
  452. if (EditorGUI.EndChangeCheck())
  453. Experimental.Lightmapping.SetLightDirty((UnityEngine.Light)serializedLight.serializedObject.targetObject);
  454. }
  455. }
  456. }
  457. }
  458. }