BrushProperties.cs 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002
  1. /*
  2. Copyright (c) 2020 Omar Duarte
  3. Unauthorized copying of this file, via any medium is strictly prohibited.
  4. Writen by Omar Duarte, 2020.
  5. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  7. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  8. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  9. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  10. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  11. THE SOFTWARE.
  12. */
  13. using UnityEngine;
  14. namespace PluginMaster
  15. {
  16. public class BrushProperties : UnityEditor.EditorWindow, ISerializationCallbackReceiver
  17. {
  18. #region COMMON
  19. [SerializeField] PWBData _data = null;
  20. private GUISkin _skin = null;
  21. private GUIStyle _itemStyle = null;
  22. private GUIStyle _cursorStyle = null;
  23. private GUIStyle _thumbnailToggleStyle = null;
  24. private Vector2 _mainScrollPosition = Vector2.zero;
  25. private bool _repaint = false;
  26. private bool _updateBrushStroke = false;
  27. private static BrushProperties _instance = null;
  28. public static BrushProperties instance => _instance;
  29. [UnityEditor.MenuItem("Tools/Plugin Master/Prefab World Builder/Brush Properties...", false, 1120)]
  30. public static void ShowWindow() => _instance = GetWindow<BrushProperties>("Brush Properties");
  31. public static void RepaintWindow()
  32. {
  33. if (_instance == null) return;
  34. _instance.Repaint();
  35. _instance._repaint = true;
  36. }
  37. public static void CloseWindow()
  38. {
  39. if (_instance != null) _instance.Close();
  40. }
  41. private void OnEnable()
  42. {
  43. _instance = this;
  44. _data = PWBCore.staticData;
  45. PaletteManager.OnBrushSelectionChanged += OnBrushChanged;
  46. _skin = Resources.Load<GUISkin>("PWBSkin");
  47. if (_skin == null) return;
  48. _itemStyle = _skin.GetStyle("PaletteToggle");
  49. _cursorStyle = _skin.GetStyle("Cursor");
  50. _thumbnailToggleStyle = _skin.GetStyle("ThumbnailToggle");
  51. wantsMouseMove = true;
  52. wantsMouseEnterLeaveWindow = true;
  53. PaletteManager.OnSelectionChanged += UpdateBrushSelectionSettings;
  54. _sameStateIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/Same"),
  55. "All selected brushes define the same value for this element");
  56. _mixedStateIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/Mixed"),
  57. "The Selection contains different values for this element");
  58. _changedStateIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/Edited"),
  59. "This value has changed");
  60. UnityEditor.Undo.undoRedoPerformed += Repaint;
  61. }
  62. private void OnDisable()
  63. {
  64. PaletteManager.OnBrushSelectionChanged -= OnBrushChanged;
  65. PaletteManager.OnSelectionChanged -= UpdateBrushSelectionSettings;
  66. UnityEditor.Undo.undoRedoPerformed -= Repaint;
  67. }
  68. public static void ClearUndo()
  69. {
  70. if (_instance == null) return;
  71. UnityEditor.Undo.ClearUndo(_instance);
  72. }
  73. private void OnGUI()
  74. {
  75. if (_skin == null)
  76. {
  77. Close();
  78. return;
  79. }
  80. if (_itemAdded)
  81. {
  82. PaletteManager.selectedBrush.InsertItemAt(_newItem, _newItemIdx);
  83. _newItem = null;
  84. _selectedItemIdx = _newItemIdx;
  85. _itemAdded = false;
  86. OnMultiBrushChanged();
  87. return;
  88. }
  89. BrushInputData toggleData = null;
  90. using (var scrollView = new UnityEditor.EditorGUILayout.ScrollViewScope(_mainScrollPosition,
  91. false, false, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar, GUIStyle.none))
  92. {
  93. _mainScrollPosition = scrollView.scrollPosition;
  94. if (PaletteManager.selectionCount > 1)
  95. {
  96. BrushSelectionFields(ref _brushPosGroupOpen, ref _brushRotGroupOpen,
  97. ref _brushScaleGroupOpen, ref _brushFlipGroupOpen, BRUSH_SETTINGS_UNDO_MSG, false, true,
  98. PaletteManager.selectedPalette.brushes, PaletteManager.idxSelection,
  99. _brushSelectionSettings, _brushSelectionState);
  100. return;
  101. }
  102. if (PaletteManager.selectedBrushIdx == -1) return;
  103. bool showBrushGroup = PaletteManager.selectedBrush != null;
  104. if (showBrushGroup)
  105. {
  106. if (PaletteManager.selectedBrush.items.Length == 0)
  107. {
  108. showBrushGroup = false;
  109. PaletteManager.selectedPalette.RemoveBrushAt(PaletteManager.selectedBrushIdx);
  110. }
  111. }
  112. if (showBrushGroup)
  113. {
  114. #if UNITY_2019_1_OR_NEWER
  115. _brushGroupOpen = UnityEditor.EditorGUILayout.BeginFoldoutHeaderGroup(_brushGroupOpen, "Brush Settings");
  116. #else
  117. _brushGroupOpen = EditorGUILayout.Foldout(_brushGroupOpen, "Brush Settings");
  118. #endif
  119. if (_brushGroupOpen) BrushGroup();
  120. #if UNITY_2019_1_OR_NEWER
  121. UnityEditor.EditorGUILayout.EndFoldoutHeaderGroup();
  122. #endif
  123. #if UNITY_2019_1_OR_NEWER
  124. _multiBrushGroupOpen = UnityEditor.EditorGUILayout.BeginFoldoutHeaderGroup(_multiBrushGroupOpen,
  125. "Multi Brush Settings");
  126. #else
  127. _multiBrushGroupOpen = EditorGUILayout.Foldout(_multiBrushGroupOpen, "Multi Brush Settings");
  128. #endif
  129. if (_multiBrushGroupOpen) MultiBrushGroup(ref toggleData);
  130. #if UNITY_2019_1_OR_NEWER
  131. UnityEditor.EditorGUILayout.EndFoldoutHeaderGroup();
  132. #endif
  133. }
  134. }
  135. OnObjectSelectorClosed();
  136. ItemMouseEventHandler(toggleData);
  137. var eventType = Event.current.rawType;
  138. if (eventType == EventType.MouseMove || eventType == EventType.MouseUp)
  139. {
  140. _moveItem.to = -1;
  141. draggingItem = false;
  142. _showCursor = false;
  143. }
  144. if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
  145. {
  146. GUI.FocusControl(null);
  147. Repaint();
  148. }
  149. }
  150. private void Update()
  151. {
  152. if (mouseOverWindow != this)
  153. {
  154. _moveItem.to = -1;
  155. _showCursor = false;
  156. }
  157. else if (draggingItem) _showCursor = true;
  158. if (_repaint)
  159. {
  160. _repaint = false;
  161. Repaint();
  162. }
  163. if (_updateBrushStroke)
  164. {
  165. _updateBrushStroke = false;
  166. BrushstrokeManager.UpdateBrushstroke();
  167. }
  168. }
  169. private void OnBrushChanged()
  170. {
  171. _selectedItemIdx = 0;
  172. _repaint = true;
  173. }
  174. public void OnBeforeSerialize() { }
  175. public void OnAfterDeserialize()
  176. {
  177. _repaint = true;
  178. _updateBrushStroke = true;
  179. }
  180. #endregion
  181. #region BRUSH SELECTION
  182. private GUIContent _sameStateIcon = null;
  183. private GUIContent _mixedStateIcon = null;
  184. private GUIContent _changedStateIcon = null;
  185. private enum SelectionFieldState { SAME, MIXED, CHANGED }
  186. private class BrushSelectionState
  187. {
  188. public SelectionFieldState surfaceDistance = SelectionFieldState.SAME;
  189. public SelectionFieldState randomSurfaceDistance = SelectionFieldState.SAME;
  190. public SelectionFieldState randomSurfaceDistanceRange = SelectionFieldState.SAME;
  191. public SelectionFieldState embedInSurface = SelectionFieldState.SAME;
  192. public SelectionFieldState embedAtPivotHeight = SelectionFieldState.SAME;
  193. public SelectionFieldState localPositionOffset = SelectionFieldState.SAME;
  194. public SelectionFieldState rotateToTheSurface = SelectionFieldState.SAME;
  195. public SelectionFieldState eulerOffset = SelectionFieldState.SAME;
  196. public SelectionFieldState addRandomRotation = SelectionFieldState.SAME;
  197. public SelectionFieldState randomEulerOffset = SelectionFieldState.SAME;
  198. public SelectionFieldState alwaysOrientUp = SelectionFieldState.SAME;
  199. public SelectionFieldState separateScaleAxes = SelectionFieldState.SAME;
  200. public SelectionFieldState scaleMultiplier = SelectionFieldState.SAME;
  201. public SelectionFieldState randomScaleMultiplier = SelectionFieldState.SAME;
  202. public SelectionFieldState randomScaleMultiplierRange = SelectionFieldState.SAME;
  203. public SelectionFieldState flipX = SelectionFieldState.SAME;
  204. public SelectionFieldState flipY = SelectionFieldState.SAME;
  205. public virtual bool changed
  206. => surfaceDistance == SelectionFieldState.CHANGED
  207. || randomSurfaceDistance == SelectionFieldState.CHANGED
  208. || randomSurfaceDistanceRange == SelectionFieldState.CHANGED
  209. || embedInSurface == SelectionFieldState.CHANGED
  210. || embedAtPivotHeight == SelectionFieldState.CHANGED
  211. || localPositionOffset == SelectionFieldState.CHANGED
  212. || rotateToTheSurface == SelectionFieldState.CHANGED
  213. || eulerOffset == SelectionFieldState.CHANGED
  214. || addRandomRotation == SelectionFieldState.CHANGED
  215. || randomEulerOffset == SelectionFieldState.CHANGED
  216. || alwaysOrientUp == SelectionFieldState.CHANGED
  217. || separateScaleAxes == SelectionFieldState.CHANGED
  218. || scaleMultiplier == SelectionFieldState.CHANGED
  219. || randomScaleMultiplier == SelectionFieldState.CHANGED
  220. || randomScaleMultiplierRange == SelectionFieldState.CHANGED
  221. || flipX == SelectionFieldState.CHANGED
  222. || flipY == SelectionFieldState.CHANGED;
  223. public virtual void Reset()
  224. {
  225. surfaceDistance = SelectionFieldState.SAME;
  226. randomSurfaceDistance = SelectionFieldState.SAME;
  227. randomSurfaceDistanceRange = SelectionFieldState.SAME;
  228. embedInSurface = SelectionFieldState.SAME;
  229. embedAtPivotHeight = SelectionFieldState.SAME;
  230. localPositionOffset = SelectionFieldState.SAME;
  231. rotateToTheSurface = SelectionFieldState.SAME;
  232. eulerOffset = SelectionFieldState.SAME;
  233. addRandomRotation = SelectionFieldState.SAME;
  234. randomEulerOffset = SelectionFieldState.SAME;
  235. alwaysOrientUp = SelectionFieldState.SAME;
  236. separateScaleAxes = SelectionFieldState.SAME;
  237. scaleMultiplier = SelectionFieldState.SAME;
  238. randomScaleMultiplier = SelectionFieldState.SAME;
  239. randomScaleMultiplierRange = SelectionFieldState.SAME;
  240. flipX = SelectionFieldState.SAME;
  241. flipY = SelectionFieldState.SAME;
  242. }
  243. }
  244. private void UpdateBrushSelectionSettings(int[] selection, BrushSettings[] settingsArray,
  245. BrushSelectionState brushSelectionState, BrushSettings brushSelectionSettings)
  246. {
  247. if (brushSelectionSettings == null) brushSelectionSettings = settingsArray[selection[0]].Clone();
  248. if (selection.Length == 0) return;
  249. if (settingsArray.Length <= selection[0]) return;
  250. brushSelectionState.Reset();
  251. if (selection.Length > 0) brushSelectionSettings.Copy(settingsArray[selection[0]]);
  252. if (focusedWindow == this) GUI.FocusControl(null);
  253. _repaint = true;
  254. }
  255. private GUIContent GetStateGUIContent(SelectionFieldState state)
  256. => state == SelectionFieldState.SAME ? _sameStateIcon : state == SelectionFieldState.MIXED
  257. ? _mixedStateIcon : _changedStateIcon;
  258. private void UpdateSelectionState(BrushSettings[] settingsArray,
  259. int[] selection, BrushSelectionState brushSelectionState)
  260. {
  261. for (int i = 0; i < selection.Length - 1; ++i)
  262. {
  263. var brush = settingsArray[selection[i]];
  264. var nextBrush = settingsArray[selection[i + 1]];
  265. if (brushSelectionState.embedInSurface != SelectionFieldState.CHANGED
  266. && brush.embedInSurface != nextBrush.embedInSurface)
  267. brushSelectionState.embedInSurface = SelectionFieldState.MIXED;
  268. if (brushSelectionState.embedAtPivotHeight != SelectionFieldState.CHANGED
  269. && brush.embedAtPivotHeight != nextBrush.embedAtPivotHeight)
  270. brushSelectionState.embedInSurface = SelectionFieldState.MIXED;
  271. if (brushSelectionState.surfaceDistance != SelectionFieldState.CHANGED
  272. && brush.surfaceDistance != nextBrush.surfaceDistance)
  273. brushSelectionState.surfaceDistance = SelectionFieldState.MIXED;
  274. if (brushSelectionState.randomSurfaceDistance != SelectionFieldState.CHANGED
  275. && brush.randomSurfaceDistance != nextBrush.randomSurfaceDistance)
  276. brushSelectionState.randomSurfaceDistance = SelectionFieldState.MIXED;
  277. if (brushSelectionState.randomSurfaceDistanceRange != SelectionFieldState.CHANGED
  278. && brush.randomSurfaceDistanceRange != nextBrush.randomSurfaceDistanceRange)
  279. brushSelectionState.randomSurfaceDistanceRange = SelectionFieldState.MIXED;
  280. if (brushSelectionState.localPositionOffset != SelectionFieldState.CHANGED
  281. && brush.localPositionOffset != nextBrush.localPositionOffset)
  282. brushSelectionState.localPositionOffset = SelectionFieldState.MIXED;
  283. if (brushSelectionState.rotateToTheSurface != SelectionFieldState.CHANGED
  284. && brush.rotateToTheSurface != nextBrush.rotateToTheSurface)
  285. brushSelectionState.rotateToTheSurface = SelectionFieldState.MIXED;
  286. if (brushSelectionState.addRandomRotation != SelectionFieldState.CHANGED
  287. && brush.addRandomRotation != nextBrush.addRandomRotation)
  288. brushSelectionState.addRandomRotation = SelectionFieldState.MIXED;
  289. if (brushSelectionState.eulerOffset != SelectionFieldState.CHANGED
  290. && brush.eulerOffset != nextBrush.eulerOffset)
  291. brushSelectionState.eulerOffset = SelectionFieldState.MIXED;
  292. if (brushSelectionState.randomEulerOffset != SelectionFieldState.CHANGED
  293. && brush.randomEulerOffset != nextBrush.randomEulerOffset)
  294. brushSelectionState.randomEulerOffset = SelectionFieldState.MIXED;
  295. if (brushSelectionState.randomScaleMultiplier != SelectionFieldState.CHANGED
  296. && brush.randomScaleMultiplier != nextBrush.randomScaleMultiplier)
  297. brushSelectionState.randomScaleMultiplier = SelectionFieldState.MIXED;
  298. if (brushSelectionState.alwaysOrientUp != SelectionFieldState.CHANGED
  299. && brush.alwaysOrientUp != nextBrush.alwaysOrientUp)
  300. brushSelectionState.alwaysOrientUp = SelectionFieldState.MIXED;
  301. if (brushSelectionState.separateScaleAxes != SelectionFieldState.CHANGED
  302. && brush.separateScaleAxes != nextBrush.separateScaleAxes)
  303. brushSelectionState.separateScaleAxes = SelectionFieldState.MIXED;
  304. if (brushSelectionState.scaleMultiplier != SelectionFieldState.CHANGED
  305. && brush.scaleMultiplier != nextBrush.scaleMultiplier)
  306. brushSelectionState.scaleMultiplier = SelectionFieldState.MIXED;
  307. if (brushSelectionState.randomScaleMultiplierRange != SelectionFieldState.CHANGED
  308. && brush.randomScaleMultiplierRange != nextBrush.randomScaleMultiplierRange)
  309. brushSelectionState.randomScaleMultiplierRange = SelectionFieldState.MIXED;
  310. if (brushSelectionState.flipX != SelectionFieldState.CHANGED
  311. && brush.flipX != nextBrush.flipX)
  312. brushSelectionState.flipX = SelectionFieldState.MIXED;
  313. if (brushSelectionState.flipY != SelectionFieldState.CHANGED
  314. && brush.flipY != nextBrush.flipY)
  315. brushSelectionState.flipY = SelectionFieldState.MIXED;
  316. }
  317. }
  318. private bool BrushSelectionFields(ref bool brushPosGroupOpen, ref bool brushRotGroupOpen,
  319. ref bool brushScaleGroupOpen, ref bool brushFlipGroupOpen, string undoMsg, bool isItem, bool showApplyAndDiscard,
  320. BrushSettings[] settingsArray, int[] selection,
  321. BrushSettings brushSelectionSettings, BrushSelectionState brushSelectionState)
  322. {
  323. if (brushSelectionSettings == null)
  324. UpdateBrushSelectionSettings(selection, settingsArray, brushSelectionState, brushSelectionSettings);
  325. UpdateSelectionState(settingsArray, selection, brushSelectionState);
  326. brushPosGroupOpen = UnityEditor.EditorGUILayout.Foldout(brushPosGroupOpen, "Position");
  327. UnityEditor.EditorGUIUtility.labelWidth = 110;
  328. if (brushPosGroupOpen)
  329. {
  330. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  331. {
  332. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  333. {
  334. using (new GUILayout.HorizontalScope())
  335. {
  336. GUILayout.Box(GetStateGUIContent(brushSelectionState.embedInSurface),
  337. UnityEditor.EditorStyles.label);
  338. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  339. {
  340. brushSelectionSettings.embedInSurface
  341. = UnityEditor.EditorGUILayout.ToggleLeft("Embed On the Surface",
  342. brushSelectionSettings.embedInSurface);
  343. if (check.changed) brushSelectionState.embedInSurface = SelectionFieldState.CHANGED;
  344. }
  345. GUILayout.FlexibleSpace();
  346. }
  347. if (brushSelectionSettings.embedInSurface)
  348. {
  349. using (new GUILayout.HorizontalScope())
  350. {
  351. GUILayout.Box(GetStateGUIContent(brushSelectionState.embedAtPivotHeight),
  352. UnityEditor.EditorStyles.label);
  353. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  354. {
  355. brushSelectionSettings.embedAtPivotHeight
  356. = UnityEditor.EditorGUILayout.ToggleLeft("Embed At Pivot Height",
  357. brushSelectionSettings.embedAtPivotHeight);
  358. if (check.changed) brushSelectionState.embedAtPivotHeight = SelectionFieldState.CHANGED;
  359. }
  360. GUILayout.FlexibleSpace();
  361. }
  362. }
  363. }
  364. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  365. {
  366. using (new GUILayout.HorizontalScope())
  367. {
  368. GUILayout.Box(GetStateGUIContent(brushSelectionState.randomSurfaceDistance),
  369. UnityEditor.EditorStyles.label);
  370. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  371. {
  372. brushSelectionSettings.randomSurfaceDistance
  373. = UnityEditor.EditorGUILayout.Popup("Surface Distance:",
  374. brushSelectionSettings.randomSurfaceDistance ? 1 : 0,
  375. new string[] { "Constant", "Random" }) == 1;
  376. if (check.changed)
  377. brushSelectionState.randomSurfaceDistance = SelectionFieldState.CHANGED;
  378. }
  379. GUILayout.FlexibleSpace();
  380. }
  381. if (brushSelectionSettings.randomSurfaceDistance)
  382. {
  383. using (new GUILayout.HorizontalScope())
  384. {
  385. GUILayout.Box(GetStateGUIContent(brushSelectionState.randomSurfaceDistanceRange),
  386. UnityEditor.EditorStyles.label);
  387. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  388. {
  389. brushSelectionSettings.randomSurfaceDistanceRange
  390. = EditorGUIUtils.RangeField(string.Empty,
  391. brushSelectionSettings.randomSurfaceDistanceRange);
  392. if (check.changed)
  393. brushSelectionState.randomSurfaceDistanceRange = SelectionFieldState.CHANGED;
  394. }
  395. GUILayout.FlexibleSpace();
  396. }
  397. }
  398. else
  399. {
  400. using (new GUILayout.HorizontalScope())
  401. {
  402. GUILayout.Box(GetStateGUIContent(brushSelectionState.surfaceDistance),
  403. UnityEditor.EditorStyles.label);
  404. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  405. {
  406. brushSelectionSettings.surfaceDistance
  407. = UnityEditor.EditorGUILayout.FloatField("Value:",
  408. brushSelectionSettings.surfaceDistance);
  409. if (check.changed)
  410. brushSelectionState.surfaceDistance = SelectionFieldState.CHANGED;
  411. }
  412. GUILayout.FlexibleSpace();
  413. }
  414. }
  415. }
  416. using (new GUILayout.HorizontalScope())
  417. {
  418. GUILayout.Box(GetStateGUIContent(brushSelectionState.localPositionOffset),
  419. UnityEditor.EditorStyles.label);
  420. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  421. {
  422. brushSelectionSettings.localPositionOffset
  423. = UnityEditor.EditorGUILayout.Vector3Field("Local Offset:",
  424. brushSelectionSettings.localPositionOffset);
  425. if (check.changed) brushSelectionState.localPositionOffset = SelectionFieldState.CHANGED;
  426. }
  427. GUILayout.FlexibleSpace();
  428. }
  429. }
  430. }
  431. brushRotGroupOpen = UnityEditor.EditorGUILayout.Foldout(brushRotGroupOpen, "Rotation");
  432. if (brushRotGroupOpen)
  433. {
  434. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  435. {
  436. using (new GUILayout.HorizontalScope())
  437. {
  438. GUILayout.Box(GetStateGUIContent(brushSelectionState.rotateToTheSurface),
  439. UnityEditor.EditorStyles.label);
  440. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  441. {
  442. brushSelectionSettings.rotateToTheSurface
  443. = UnityEditor.EditorGUILayout.ToggleLeft("Rotate to the Surface",
  444. brushSelectionSettings.rotateToTheSurface);
  445. if (check.changed) brushSelectionState.rotateToTheSurface = SelectionFieldState.CHANGED;
  446. }
  447. GUILayout.FlexibleSpace();
  448. }
  449. if (brushSelectionSettings.rotateToTheSurface)
  450. {
  451. using (new GUILayout.HorizontalScope())
  452. {
  453. GUILayout.Box(GetStateGUIContent(brushSelectionState.alwaysOrientUp),
  454. UnityEditor.EditorStyles.label);
  455. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  456. {
  457. brushSelectionSettings.alwaysOrientUp
  458. = UnityEditor.EditorGUILayout.ToggleLeft("Always orient up",
  459. brushSelectionSettings.alwaysOrientUp);
  460. if (check.changed) brushSelectionState.alwaysOrientUp = SelectionFieldState.CHANGED;
  461. }
  462. GUILayout.FlexibleSpace();
  463. }
  464. }
  465. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  466. {
  467. using (new GUILayout.HorizontalScope())
  468. {
  469. GUILayout.Box(GetStateGUIContent(brushSelectionState.addRandomRotation),
  470. UnityEditor.EditorStyles.label);
  471. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  472. {
  473. brushSelectionSettings.addRandomRotation
  474. = UnityEditor.EditorGUILayout.Popup("Add Rotation:",
  475. brushSelectionSettings.addRandomRotation ? 1 : 0,
  476. new string[] { "Constant", "Random" }) == 1;
  477. if (check.changed)
  478. brushSelectionState.addRandomRotation = SelectionFieldState.CHANGED;
  479. }
  480. GUILayout.FlexibleSpace();
  481. }
  482. if (brushSelectionSettings.addRandomRotation)
  483. {
  484. using (new GUILayout.HorizontalScope())
  485. {
  486. GUILayout.Box(GetStateGUIContent(brushSelectionState.randomEulerOffset),
  487. UnityEditor.EditorStyles.label);
  488. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  489. {
  490. brushSelectionSettings.randomEulerOffset
  491. = EditorGUIUtils.Range3Field(string.Empty,
  492. brushSelectionSettings.randomEulerOffset);
  493. if (check.changed)
  494. brushSelectionState.randomEulerOffset = SelectionFieldState.CHANGED;
  495. }
  496. GUILayout.FlexibleSpace();
  497. }
  498. }
  499. else
  500. {
  501. using (new GUILayout.HorizontalScope())
  502. {
  503. GUILayout.Box(GetStateGUIContent(brushSelectionState.eulerOffset),
  504. UnityEditor.EditorStyles.label);
  505. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  506. {
  507. brushSelectionSettings.eulerOffset = UnityEditor.EditorGUILayout.Vector3Field(string.Empty,
  508. brushSelectionSettings.eulerOffset);
  509. if (check.changed) brushSelectionState.eulerOffset = SelectionFieldState.CHANGED;
  510. }
  511. GUILayout.FlexibleSpace();
  512. }
  513. }
  514. }
  515. }
  516. }
  517. brushScaleGroupOpen = UnityEditor.EditorGUILayout.Foldout(brushScaleGroupOpen, "Scale");
  518. if (brushScaleGroupOpen)
  519. {
  520. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  521. {
  522. using (new GUILayout.HorizontalScope())
  523. {
  524. GUILayout.Box(GetStateGUIContent(brushSelectionState.randomScaleMultiplier),
  525. UnityEditor.EditorStyles.label);
  526. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  527. {
  528. brushSelectionSettings.randomScaleMultiplier = UnityEditor.EditorGUILayout.Popup("Multiplier:",
  529. brushSelectionSettings.randomScaleMultiplier ? 1
  530. : 0, new string[] { "Constant", "Random" }) == 1;
  531. if (check.changed)
  532. brushSelectionState.randomScaleMultiplier = SelectionFieldState.CHANGED;
  533. }
  534. GUILayout.FlexibleSpace();
  535. }
  536. GUILayout.Space(4);
  537. using (new GUILayout.HorizontalScope())
  538. {
  539. GUILayout.Box(GetStateGUIContent(brushSelectionState.separateScaleAxes),
  540. UnityEditor.EditorStyles.label);
  541. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  542. {
  543. brushSelectionSettings.separateScaleAxes = UnityEditor.EditorGUILayout.ToggleLeft("Separate Axes",
  544. brushSelectionSettings.separateScaleAxes);
  545. if (check.changed) brushSelectionState.separateScaleAxes = SelectionFieldState.CHANGED;
  546. }
  547. GUILayout.FlexibleSpace();
  548. }
  549. if (brushSelectionSettings.separateScaleAxes)
  550. {
  551. if (brushSelectionSettings.randomScaleMultiplier)
  552. {
  553. using (new GUILayout.HorizontalScope())
  554. {
  555. GUILayout.Box(GetStateGUIContent(brushSelectionState.randomScaleMultiplierRange),
  556. UnityEditor.EditorStyles.label);
  557. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  558. {
  559. var range3 = EditorGUIUtils.Range3Field(string.Empty,
  560. brushSelectionSettings.randomScaleMultiplierRange);
  561. if (Mathf.Approximately(range3.x.v1, 0))
  562. range3.x.v1 = brushSelectionSettings.randomScaleMultiplierRange.x.v1;
  563. if (Mathf.Approximately(range3.x.v2, 0))
  564. range3.x.v2 = brushSelectionSettings.randomScaleMultiplierRange.x.v2;
  565. if (Mathf.Approximately(range3.y.v1, 0))
  566. range3.y.v1 = brushSelectionSettings.randomScaleMultiplierRange.y.v1;
  567. if (Mathf.Approximately(range3.y.v2, 0))
  568. range3.y.v2 = brushSelectionSettings.randomScaleMultiplierRange.y.v2;
  569. if (Mathf.Approximately(range3.z.v1, 0))
  570. range3.z.v1 = brushSelectionSettings.randomScaleMultiplierRange.z.v1;
  571. if (Mathf.Approximately(range3.z.v2, 0))
  572. range3.z.v2 = brushSelectionSettings.randomScaleMultiplierRange.z.v2;
  573. brushSelectionSettings.randomScaleMultiplierRange = range3;
  574. if (check.changed && range3 != brushSelectionSettings.randomScaleMultiplierRange)
  575. brushSelectionState.randomScaleMultiplierRange = SelectionFieldState.CHANGED;
  576. }
  577. GUILayout.FlexibleSpace();
  578. }
  579. }
  580. else
  581. {
  582. using (new GUILayout.HorizontalScope())
  583. {
  584. GUILayout.Box(GetStateGUIContent(brushSelectionState.scaleMultiplier),
  585. UnityEditor.EditorStyles.label);
  586. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  587. {
  588. var mult = UnityEditor.EditorGUILayout.Vector3Field(string.Empty,
  589. brushSelectionSettings.scaleMultiplier);
  590. if (Mathf.Approximately(mult.x, 0)) mult.x = brushSelectionSettings.scaleMultiplier.x;
  591. if (Mathf.Approximately(mult.y, 0)) mult.y = brushSelectionSettings.scaleMultiplier.y;
  592. if (Mathf.Approximately(mult.z, 0)) mult.z = brushSelectionSettings.scaleMultiplier.z;
  593. brushSelectionSettings.scaleMultiplier = mult;
  594. if (check.changed)
  595. brushSelectionState.scaleMultiplier = SelectionFieldState.CHANGED;
  596. }
  597. GUILayout.FlexibleSpace();
  598. }
  599. }
  600. }
  601. else
  602. {
  603. if (brushSelectionSettings.randomScaleMultiplier)
  604. {
  605. using (new GUILayout.HorizontalScope())
  606. {
  607. GUILayout.Box(GetStateGUIContent(brushSelectionState.randomScaleMultiplierRange),
  608. UnityEditor.EditorStyles.label);
  609. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  610. {
  611. var range = EditorGUIUtils.RangeField(string.Empty,
  612. brushSelectionSettings.randomScaleMultiplierRange.x);
  613. if (Mathf.Approximately(range.v1, 0))
  614. range.v1 = brushSelectionSettings.randomScaleMultiplierRange.x.v1;
  615. if (Mathf.Approximately(range.v2, 0))
  616. range.v1 = brushSelectionSettings.randomScaleMultiplierRange.x.v2;
  617. brushSelectionSettings.randomScaleMultiplierRange.z
  618. = brushSelectionSettings.randomScaleMultiplierRange.y
  619. = brushSelectionSettings.randomScaleMultiplierRange.x
  620. = range;
  621. if (check.changed && range != brushSelectionSettings.randomScaleMultiplierRange.x)
  622. brushSelectionState.randomScaleMultiplierRange = SelectionFieldState.CHANGED;
  623. }
  624. GUILayout.FlexibleSpace();
  625. }
  626. }
  627. else
  628. {
  629. using (new GUILayout.HorizontalScope())
  630. {
  631. GUILayout.Box(GetStateGUIContent(brushSelectionState.scaleMultiplier),
  632. UnityEditor.EditorStyles.label);
  633. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  634. {
  635. var multiplier = UnityEditor.EditorGUILayout.FloatField("Value:",
  636. brushSelectionSettings.scaleMultiplier.x);
  637. if (!Mathf.Approximately(multiplier, 0))
  638. {
  639. brushSelectionSettings.scaleMultiplier = Vector3.one * multiplier;
  640. if (check.changed)
  641. brushSelectionState.scaleMultiplier = SelectionFieldState.CHANGED;
  642. }
  643. }
  644. GUILayout.FlexibleSpace();
  645. }
  646. }
  647. }
  648. }
  649. }
  650. bool isAsset2D = true;
  651. foreach (var idx in selection)
  652. {
  653. var settings = settingsArray[idx];
  654. if (!settings.isAsset2D)
  655. {
  656. isAsset2D = false;
  657. break;
  658. }
  659. }
  660. if (isAsset2D)
  661. {
  662. brushFlipGroupOpen = UnityEditor.EditorGUILayout.Foldout(brushFlipGroupOpen, "Flip");
  663. if (brushFlipGroupOpen)
  664. {
  665. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  666. {
  667. using (new GUILayout.HorizontalScope())
  668. {
  669. GUILayout.Box(GetStateGUIContent(brushSelectionState.flipX),
  670. UnityEditor.EditorStyles.label);
  671. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  672. {
  673. brushSelectionSettings.flipX
  674. = (BrushSettings.FlipAction)UnityEditor.EditorGUILayout.Popup("Flip X: ",
  675. (int)brushSelectionSettings.flipX, new string[] { "No", "Yes", "Random" });
  676. if (check.changed) brushSelectionState.flipX = SelectionFieldState.CHANGED;
  677. }
  678. GUILayout.FlexibleSpace();
  679. }
  680. using (new GUILayout.HorizontalScope())
  681. {
  682. GUILayout.Box(GetStateGUIContent(brushSelectionState.flipY),
  683. UnityEditor.EditorStyles.label);
  684. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  685. {
  686. brushSelectionSettings.flipY
  687. = (BrushSettings.FlipAction)UnityEditor.EditorGUILayout.Popup("Flip Y: ",
  688. (int)brushSelectionSettings.flipY, new string[] { "No", "Yes", "Random" });
  689. if (check.changed) brushSelectionState.flipY = SelectionFieldState.CHANGED;
  690. }
  691. GUILayout.FlexibleSpace();
  692. }
  693. }
  694. }
  695. }
  696. if (showApplyAndDiscard)
  697. return ApplyDiscardButtons(undoMsg, isItem, settingsArray, selection,
  698. brushSelectionSettings, brushSelectionState);
  699. return false;
  700. }
  701. private bool ApplyDiscardButtons(string undoMsg, bool isItem,
  702. BrushSettings[] settingsArray, int[] selection,
  703. BrushSettings brushSelectionSettings, BrushSelectionState brushSelectionState)
  704. {
  705. using (new GUILayout.HorizontalScope())
  706. {
  707. GUILayout.FlexibleSpace();
  708. using (new UnityEditor.EditorGUI.DisabledGroupScope(!brushSelectionState.changed))
  709. {
  710. if (GUILayout.Button("Discard")) UpdateBrushSelectionSettings(selection, settingsArray,
  711. brushSelectionState, brushSelectionSettings);
  712. }
  713. if (GUILayout.Button("Apply"))
  714. {
  715. foreach (var idx in selection)
  716. {
  717. var brush = isItem ? (BrushSettings)PaletteManager.selectedBrush.GetItemAt(idx)
  718. : PaletteManager.selectedPalette.GetBrush(idx);
  719. brush.surfaceDistance = brushSelectionSettings.surfaceDistance;
  720. brush.randomSurfaceDistance = brushSelectionSettings.randomSurfaceDistance;
  721. brush.randomSurfaceDistanceRange = brushSelectionSettings.randomSurfaceDistanceRange;
  722. brush.embedInSurface = brushSelectionSettings.embedInSurface;
  723. brush.embedAtPivotHeight = brushSelectionSettings.embedAtPivotHeight;
  724. brush.localPositionOffset = brushSelectionSettings.localPositionOffset;
  725. brush.rotateToTheSurface = brushSelectionSettings.rotateToTheSurface;
  726. brush.eulerOffset = brushSelectionSettings.eulerOffset;
  727. brush.addRandomRotation = brushSelectionSettings.addRandomRotation;
  728. brush.randomEulerOffset = brushSelectionSettings.randomEulerOffset;
  729. brush.alwaysOrientUp = brushSelectionSettings.alwaysOrientUp;
  730. brush.separateScaleAxes = brushSelectionSettings.separateScaleAxes;
  731. brush.scaleMultiplier = brushSelectionSettings.scaleMultiplier;
  732. brush.randomScaleMultiplier = brushSelectionSettings.randomScaleMultiplier;
  733. brush.randomScaleMultiplierRange = brushSelectionSettings.randomScaleMultiplierRange;
  734. brush.flipX = brushSelectionSettings.flipX;
  735. brush.flipY = brushSelectionSettings.flipY;
  736. if (ToolManager.tool == ToolManager.PaintTool.PIN
  737. && (brushSelectionState.embedInSurface == SelectionFieldState.CHANGED
  738. || brushSelectionState.embedAtPivotHeight == SelectionFieldState.CHANGED)) PWBIO.ResetPinValues();
  739. }
  740. PaletteManager.selectedPalette.Save();
  741. UpdateBrushSelectionSettings(selection, settingsArray, brushSelectionState, brushSelectionSettings);
  742. return true;
  743. }
  744. }
  745. return false;
  746. }
  747. #endregion
  748. #region BRUSH SETTINGS
  749. private const string BRUSH_SETTINGS_UNDO_MSG = "Brush Settings";
  750. private bool _brushGroupOpen = true;
  751. private bool _brushPosGroupOpen = false;
  752. private bool _brushRotGroupOpen = false;
  753. private bool _brushScaleGroupOpen = false;
  754. private bool _brushFlipGroupOpen = false;
  755. private BrushSelectionState _brushSelectionState = new BrushSelectionState();
  756. private BrushSettings _brushSelectionSettings = new BrushSettings();
  757. private void UpdateBrushSelectionSettings()
  758. {
  759. if (PaletteManager.selectedBrushIdx == -1) return;
  760. UpdateBrushSelectionSettings(PaletteManager.idxSelection, PaletteManager.selectedPalette.brushes,
  761. _brushSelectionState, _brushSelectionSettings);
  762. _selection.Clear();
  763. _selection.Add(0);
  764. _selectedItemIdx = 0;
  765. if (PaletteManager.selectedBrush == null)
  766. {
  767. PaletteManager.ClearSelection();
  768. return;
  769. }
  770. UpdateBrushSelectionSettings(_selection.ToArray(), PaletteManager.selectedBrush.items,
  771. _itemSelectionState, _itemSelectionSettings);
  772. }
  773. public static bool BrushFields(BrushSettings brush, ref bool brushPosGroupOpen, ref bool brushRotGroupOpen,
  774. ref bool brushScaleGroupOpen, ref bool brush2DGroupOpen)
  775. {
  776. bool changed = false;
  777. DrawPositionSettings(brush, ref brushPosGroupOpen, ref changed);
  778. DrawRotationSettings(brush, ref brushRotGroupOpen, ref changed);
  779. DrawScaleSettings(brush, ref brushScaleGroupOpen, ref changed);
  780. if (brush.isAsset2D) Draw2DSettings(brush, ref brush2DGroupOpen, ref changed);
  781. if (changed)
  782. {
  783. brush.UpdateBottomVertices();
  784. PaletteManager.selectedPalette.Save();
  785. BrushstrokeManager.UpdateBrushstroke();
  786. if (ToolManager.tool == ToolManager.PaintTool.TILING) PWBIO.UpdateCellSize();
  787. }
  788. return changed;
  789. }
  790. private static void DrawPositionSettings(BrushSettings brush, ref bool groupOpen, ref bool changed)
  791. {
  792. groupOpen = UnityEditor.EditorGUILayout.Foldout(groupOpen, "Position");
  793. if (!groupOpen) return;
  794. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  795. {
  796. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  797. {
  798. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  799. {
  800. var embedInSurface = UnityEditor.EditorGUILayout.ToggleLeft("Embed On the Surface",
  801. brush.embedInSurface);
  802. if (check.changed)
  803. {
  804. changed = true;
  805. brush.embedInSurface = embedInSurface;
  806. }
  807. }
  808. if (brush.embedInSurface)
  809. {
  810. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  811. {
  812. var embedAtPivotHeight = UnityEditor.EditorGUILayout.ToggleLeft("Embed At Pivot Height",
  813. brush.embedAtPivotHeight);
  814. if (check.changed)
  815. {
  816. changed = true;
  817. brush.embedAtPivotHeight = embedAtPivotHeight;
  818. }
  819. }
  820. }
  821. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  822. {
  823. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  824. {
  825. var randomSurfaceDistance = UnityEditor.EditorGUILayout.Popup("Surface distance:",
  826. brush.randomSurfaceDistance ? 1 : 0, new string[] { "Constant", "Random" }) == 1;
  827. if (check.changed)
  828. {
  829. changed = true;
  830. brush.randomSurfaceDistance = randomSurfaceDistance;
  831. }
  832. }
  833. if (brush.randomSurfaceDistance)
  834. {
  835. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  836. {
  837. var randomSurfaceDistanceRange = EditorGUIUtils.RangeField(string.Empty,
  838. brush.randomSurfaceDistanceRange);
  839. if (check.changed)
  840. {
  841. changed = true;
  842. brush.randomSurfaceDistanceRange = randomSurfaceDistanceRange;
  843. }
  844. }
  845. }
  846. else
  847. {
  848. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  849. {
  850. var surfaceDistance = UnityEditor.EditorGUILayout.FloatField("Value:",
  851. brush.surfaceDistance);
  852. if (check.changed)
  853. {
  854. changed = true;
  855. brush.surfaceDistance = surfaceDistance;
  856. }
  857. }
  858. }
  859. }
  860. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  861. {
  862. var localPositionOffset = UnityEditor.EditorGUILayout.Vector3Field("Local Offset:",
  863. brush.localPositionOffset);
  864. if (check.changed)
  865. {
  866. changed = true;
  867. brush.localPositionOffset = localPositionOffset;
  868. }
  869. }
  870. }
  871. }
  872. }
  873. private static void DrawRotationSettings(BrushSettings brush, ref bool groupOpen, ref bool changed)
  874. {
  875. groupOpen = UnityEditor.EditorGUILayout.Foldout(groupOpen, "Rotation");
  876. if (!groupOpen) return;
  877. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  878. {
  879. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  880. {
  881. var rotateToTheSurface = UnityEditor.EditorGUILayout.ToggleLeft("Rotate to the Surface",
  882. brush.rotateToTheSurface);
  883. if (check.changed)
  884. {
  885. changed = true;
  886. brush.rotateToTheSurface = rotateToTheSurface;
  887. }
  888. }
  889. if (brush.rotateToTheSurface)
  890. {
  891. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  892. {
  893. var alwaysOrientUp = UnityEditor.EditorGUILayout.ToggleLeft("Always orient up",
  894. brush.alwaysOrientUp);
  895. if (check.changed)
  896. {
  897. changed = true;
  898. brush.alwaysOrientUp = alwaysOrientUp;
  899. }
  900. }
  901. }
  902. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  903. {
  904. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  905. {
  906. var addRandomRotation = UnityEditor.EditorGUILayout.Popup("Add Rotation:",
  907. brush.addRandomRotation ? 1 : 0, new string[] { "Constant", "Random" }) == 1;
  908. if (check.changed)
  909. {
  910. changed = true;
  911. brush.addRandomRotation = addRandomRotation;
  912. }
  913. }
  914. if (brush.addRandomRotation)
  915. {
  916. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  917. {
  918. var randomEulerOffset = EditorGUIUtils.Range3Field(string.Empty, brush.randomEulerOffset);
  919. if (check.changed)
  920. {
  921. changed = true;
  922. brush.randomEulerOffset = randomEulerOffset;
  923. }
  924. }
  925. using (new GUILayout.HorizontalScope())
  926. {
  927. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  928. {
  929. UnityEditor.EditorGUIUtility.labelWidth = 80;
  930. var rotateInMultiples = UnityEditor.EditorGUILayout.ToggleLeft
  931. ("Only in multiples of:", brush.rotateInMultiples);
  932. if (check.changed)
  933. {
  934. changed = true;
  935. brush.rotateInMultiples = rotateInMultiples;
  936. }
  937. }
  938. using (new UnityEditor.EditorGUI.DisabledGroupScope(!brush.rotateInMultiples))
  939. {
  940. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  941. {
  942. var rotationFactor = UnityEditor.EditorGUILayout.FloatField(brush.rotationFactor);
  943. if (check.changed)
  944. {
  945. changed = true;
  946. brush.rotationFactor = rotationFactor;
  947. }
  948. }
  949. }
  950. }
  951. }
  952. else // constant
  953. {
  954. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  955. {
  956. var eulerOffset = UnityEditor.EditorGUILayout.Vector3Field(string.Empty, brush.eulerOffset);
  957. if (check.changed)
  958. {
  959. changed = true;
  960. brush.eulerOffset = eulerOffset;
  961. }
  962. }
  963. }
  964. }
  965. }
  966. }
  967. private static void DrawScaleSettings(BrushSettings brush, ref bool groupOpen, ref bool changed)
  968. {
  969. groupOpen = UnityEditor.EditorGUILayout.Foldout(groupOpen, "Scale");
  970. if (!groupOpen) return;
  971. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  972. {
  973. using (new GUILayout.HorizontalScope())
  974. {
  975. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  976. {
  977. var randomScaleMultiplier = UnityEditor.EditorGUILayout.Popup("Multiplier:",
  978. brush.randomScaleMultiplier ? 1 : 0, new string[] { "Constant", "Random" }) == 1;
  979. if (check.changed)
  980. {
  981. changed = true;
  982. brush.randomScaleMultiplier = randomScaleMultiplier;
  983. }
  984. }
  985. GUILayout.Space(4);
  986. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  987. {
  988. var separateScaleAxes = UnityEditor.EditorGUILayout.ToggleLeft("Separate Axes",
  989. brush.separateScaleAxes, GUILayout.Width(102));
  990. if (check.changed)
  991. {
  992. changed = true;
  993. brush.separateScaleAxes = separateScaleAxes;
  994. }
  995. }
  996. }
  997. if (brush.separateScaleAxes)
  998. {
  999. if (brush.randomScaleMultiplier)
  1000. {
  1001. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1002. {
  1003. var range3 = EditorGUIUtils.Range3Field(string.Empty, brush.randomScaleMultiplierRange);
  1004. if (Mathf.Approximately(range3.x.v1, 0))
  1005. range3.x.v1 = brush.randomScaleMultiplierRange.x.v1;
  1006. if (Mathf.Approximately(range3.x.v2, 0))
  1007. range3.x.v2 = brush.randomScaleMultiplierRange.x.v2;
  1008. if (Mathf.Approximately(range3.y.v1, 0))
  1009. range3.y.v1 = brush.randomScaleMultiplierRange.y.v1;
  1010. if (Mathf.Approximately(range3.y.v2, 0))
  1011. range3.y.v2 = brush.randomScaleMultiplierRange.y.v2;
  1012. if (Mathf.Approximately(range3.z.v1, 0))
  1013. range3.z.v1 = brush.randomScaleMultiplierRange.z.v1;
  1014. if (Mathf.Approximately(range3.z.v2, 0))
  1015. range3.z.v2 = brush.randomScaleMultiplierRange.z.v2;
  1016. if (check.changed)
  1017. {
  1018. changed = true;
  1019. brush.randomScaleMultiplierRange = range3;
  1020. }
  1021. }
  1022. }
  1023. else
  1024. {
  1025. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1026. {
  1027. var mult = UnityEditor.EditorGUILayout.Vector3Field(string.Empty, brush.scaleMultiplier);
  1028. if (Mathf.Approximately(mult.x, 0)) mult.x = brush.scaleMultiplier.x;
  1029. if (Mathf.Approximately(mult.y, 0)) mult.y = brush.scaleMultiplier.y;
  1030. if (Mathf.Approximately(mult.z, 0)) mult.z = brush.scaleMultiplier.z;
  1031. if (check.changed)
  1032. {
  1033. changed = true;
  1034. brush.scaleMultiplier = mult;
  1035. }
  1036. }
  1037. }
  1038. }
  1039. else
  1040. {
  1041. if (brush.randomScaleMultiplier)
  1042. {
  1043. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1044. {
  1045. var range = EditorGUIUtils.RangeField(string.Empty, brush.randomScaleMultiplierRange.x);
  1046. if (Mathf.Approximately(range.v1, 0)) range.v1 = brush.randomScaleMultiplierRange.x.v1;
  1047. if (Mathf.Approximately(range.v2, 0)) range.v2 = brush.randomScaleMultiplierRange.x.v2;
  1048. if (check.changed)
  1049. {
  1050. changed = true;
  1051. brush.randomScaleMultiplierRange.z = brush.randomScaleMultiplierRange.y
  1052. = brush.randomScaleMultiplierRange.x = range;
  1053. }
  1054. }
  1055. }
  1056. else
  1057. {
  1058. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1059. {
  1060. var value = UnityEditor.EditorGUILayout.FloatField("Value: ", brush.scaleMultiplier.x);
  1061. var scaleMultiplier = brush.scaleMultiplier;
  1062. if (!Mathf.Approximately(value, 0)) scaleMultiplier = new Vector3(value, value, value);
  1063. if (check.changed)
  1064. {
  1065. changed = true;
  1066. brush.scaleMultiplier = scaleMultiplier;
  1067. }
  1068. }
  1069. }
  1070. }
  1071. }
  1072. }
  1073. private static void Draw2DSettings(BrushSettings brush, ref bool groupOpen, ref bool changed)
  1074. {
  1075. groupOpen = UnityEditor.EditorGUILayout.Foldout(groupOpen, "2D");
  1076. if (!groupOpen) return;
  1077. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  1078. {
  1079. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1080. {
  1081. var flipX = (BrushSettings.FlipAction)UnityEditor.EditorGUILayout.Popup("Flip X: ",
  1082. (int)brush.flipX, new string[] { "No", "Yes", "Random" });
  1083. if (check.changed)
  1084. {
  1085. changed = true;
  1086. brush.flipX = flipX;
  1087. }
  1088. }
  1089. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1090. {
  1091. var flipY = (BrushSettings.FlipAction)UnityEditor.EditorGUILayout.Popup("Flip Y: ",
  1092. (int)brush.flipY, new string[] { "No", "Yes", "Random" });
  1093. if (check.changed)
  1094. {
  1095. changed = true;
  1096. brush.flipY = flipY;
  1097. }
  1098. }
  1099. }
  1100. }
  1101. private void BrushGroup()
  1102. {
  1103. var brush = PaletteManager.selectedBrush;
  1104. if (brush == null) return;
  1105. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  1106. {
  1107. UnityEditor.EditorGUIUtility.labelWidth = 50;
  1108. brush.name = UnityEditor.EditorGUILayout.DelayedTextField("Name:", brush.name);
  1109. if (BrushFields(brush, ref _brushPosGroupOpen, ref _brushRotGroupOpen,
  1110. ref _brushScaleGroupOpen, ref _brushFlipGroupOpen)) PWBIO.UpdateSelectedPersistentObject();
  1111. }
  1112. }
  1113. #endregion
  1114. #region MULTIBRUSH SETTINGS
  1115. private const string MULTIBRUSH_SETTINGS_UNDO_MSG = "Multibrush Settings";
  1116. private bool _multiBrushGroupOpen = false;
  1117. private Vector2 _multiBrushScrollPosition = Vector2.zero;
  1118. private bool _multiBrushClipped = false;
  1119. private bool _itemPosGroupOpen = false;
  1120. private bool _itemRotGroupOpen = false;
  1121. private bool _itemScaleGroupOpen = false;
  1122. private bool _itemFlipGroupOpen = false;
  1123. private bool _frequencyGroupOpen = false;
  1124. private void MultiBrushGroup(ref BrushInputData toggleData)
  1125. {
  1126. if (Event.current.control && Event.current.keyCode == KeyCode.A)
  1127. {
  1128. _selection.Clear();
  1129. for (int i = 0; i < PaletteManager.selectedBrush.itemCount; ++i) _selection.Add(i);
  1130. Repaint();
  1131. }
  1132. if (_moveItem.perform)
  1133. {
  1134. var selection = _selection.ToArray();
  1135. PaletteManager.selectedBrush.Swap(_moveItem.from, _moveItem.to, ref selection);
  1136. _selection = new System.Collections.Generic.List<int>(selection);
  1137. if (selection.Length == 1) _selectedItemIdx = selection[0];
  1138. _moveItem.perform = false;
  1139. }
  1140. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  1141. {
  1142. var brushesRect = new Rect();
  1143. var selectedBrush = PaletteManager.selectedBrush;
  1144. using (var scrollView = new UnityEditor.EditorGUILayout.ScrollViewScope(
  1145. _multiBrushScrollPosition, false, false,
  1146. GUI.skin.horizontalScrollbar, GUIStyle.none, _skin.box,
  1147. GUILayout.Height(_multiBrushClipped ? 102 : 87)))
  1148. {
  1149. _multiBrushScrollPosition = scrollView.scrollPosition;
  1150. using (new GUILayout.HorizontalScope())
  1151. {
  1152. BrushItems(ref toggleData);
  1153. GUILayout.FlexibleSpace();
  1154. }
  1155. brushesRect = GUILayoutUtility.GetLastRect();
  1156. }
  1157. var scrollViewRect = GUILayoutUtility.GetLastRect();
  1158. if (Event.current.type == EventType.Repaint)
  1159. {
  1160. var prev = _multiBrushClipped;
  1161. _multiBrushClipped = (scrollViewRect.width - 8) < brushesRect.width;
  1162. if (prev != _multiBrushClipped) Repaint();
  1163. }
  1164. if (scrollViewRect.Contains(Event.current.mousePosition))
  1165. {
  1166. if (Event.current.type == EventType.ContextClick)
  1167. {
  1168. var menu = new UnityEditor.GenericMenu();
  1169. menu.AddItem(new GUIContent("New Item..."), false, AddItemAt,
  1170. selectedBrush.items.Length);
  1171. menu.AddItem(new GUIContent("New Items From Folder..."), false,
  1172. CreateItemsFromEachPrefabInFolder, selectedBrush.items.Length - 1);
  1173. menu.AddItem(new GUIContent("New Items From Selection"), false,
  1174. CreateItemsFromEachPrefabSelected, selectedBrush.items.Length - 1);
  1175. menu.ShowAsContext();
  1176. Event.current.Use();
  1177. }
  1178. else if (Event.current.type == EventType.DragUpdated)
  1179. {
  1180. UnityEditor.DragAndDrop.visualMode = UnityEditor.DragAndDropVisualMode.Copy;
  1181. Event.current.Use();
  1182. }
  1183. else if (Event.current.type == EventType.DragPerform)
  1184. {
  1185. bool multiBrushChanged = false;
  1186. var droppedItems = PluginMaster.DropUtils.GetDroppedPrefabs();
  1187. foreach (var droppedItem in droppedItems)
  1188. {
  1189. var item = new MultibrushItemSettings(droppedItem.obj, selectedBrush);
  1190. if (_moveItem.to == -1)
  1191. {
  1192. selectedBrush.AddItem(item);
  1193. _selectedItemIdx = selectedBrush.items.Length - 1;
  1194. }
  1195. else
  1196. {
  1197. selectedBrush.InsertItemAt(item, _moveItem.to);
  1198. _selectedItemIdx = _moveItem.to;
  1199. }
  1200. multiBrushChanged = true;
  1201. }
  1202. if (multiBrushChanged) OnMultiBrushChanged();
  1203. Event.current.Use();
  1204. }
  1205. }
  1206. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  1207. {
  1208. if (selectedBrush == null) return;
  1209. var selectedItem = GetSelectedItem(selectedBrush);
  1210. if (selectedItem.prefab == null) return;
  1211. var itemName = selectedItem.prefab.name;
  1212. var itemNameStyle = new GUIStyle(UnityEditor.EditorStyles.boldLabel);
  1213. itemNameStyle.alignment = TextAnchor.MiddleCenter;
  1214. GUILayout.Label((_selectedItemIdx + 1) + ". " + itemName, itemNameStyle);
  1215. var separatorStyle = new GUIStyle(UnityEditor.EditorStyles.toolbarButton);
  1216. separatorStyle.fixedHeight = 1;
  1217. GUILayout.Box(GUIContent.none, separatorStyle);
  1218. _frequencyGroupOpen = UnityEditor.EditorGUILayout.Foldout(_frequencyGroupOpen, "Frequency");
  1219. if (_frequencyGroupOpen) FrequencyGroup();
  1220. UnityEditor.EditorGUIUtility.labelWidth = 150;
  1221. if (_selection.Count <= 1)
  1222. {
  1223. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1224. {
  1225. bool overwriteSettings = UnityEditor.EditorGUILayout.ToggleLeft("Overwrite Brush Settings",
  1226. selectedItem.overwriteSettings);
  1227. if (check.changed)
  1228. {
  1229. selectedItem.overwriteSettings = overwriteSettings;
  1230. if (selectedItem.overwriteSettings) selectedItem.Copy(selectedBrush);
  1231. }
  1232. }
  1233. }
  1234. else
  1235. {
  1236. using (new GUILayout.HorizontalScope())
  1237. {
  1238. GUILayout.Box(GetStateGUIContent(_itemSelectionState.overwriteSettings),
  1239. UnityEditor.EditorStyles.label);
  1240. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1241. {
  1242. _itemSelectionSettings.overwriteSettings
  1243. = UnityEditor.EditorGUILayout.ToggleLeft("Overwrite Brush Settings",
  1244. _itemSelectionSettings.overwriteSettings);
  1245. if (check.changed) _itemSelectionState.overwriteSettings = SelectionFieldState.CHANGED;
  1246. }
  1247. GUILayout.FlexibleSpace();
  1248. }
  1249. }
  1250. if ((_selection.Count > 1 && (_itemSelectionState.overwriteSettings == SelectionFieldState.MIXED
  1251. || (_itemSelectionState.overwriteSettings != SelectionFieldState.MIXED
  1252. && _itemSelectionSettings.overwriteSettings)))
  1253. || (_selection.Count <= 1 && selectedItem.overwriteSettings)) ItemSettingsGroup();
  1254. if (_selection.Count > 1)
  1255. {
  1256. var selection = _selection.ToArray();
  1257. var settingsArray = selectedBrush.items;
  1258. var apply = ApplyDiscardButtons(MULTIBRUSH_SETTINGS_UNDO_MSG, true, settingsArray, selection,
  1259. _itemSelectionSettings, _itemSelectionState);
  1260. if (apply)
  1261. {
  1262. foreach (var idx in selection)
  1263. {
  1264. var brush = selectedBrush.GetItemAt(idx);
  1265. brush.overwriteSettings = _itemSelectionSettings.overwriteSettings;
  1266. brush.frequency = _itemSelectionSettings.frequency;
  1267. }
  1268. if (_itemSelectionState.overwriteSettings == SelectionFieldState.CHANGED)
  1269. _itemSelectionState.overwriteSettings = SelectionFieldState.SAME;
  1270. if (_itemSelectionState.frequency == SelectionFieldState.CHANGED)
  1271. _itemSelectionState.frequency = SelectionFieldState.SAME;
  1272. }
  1273. }
  1274. }
  1275. }
  1276. }
  1277. #region ITEMS
  1278. private int _selectedItemIdx = 0;
  1279. private int _currentPickerId = -1;
  1280. private bool _itemAdded = false;
  1281. private MultibrushItemSettings _newItem = null;
  1282. private int _newItemIdx = -1;
  1283. [SerializeField]
  1284. private System.Collections.Generic.List<int> _selection
  1285. = new System.Collections.Generic.List<int>() { 0 };
  1286. private (int from, int to, bool perform) _moveItem = (0, 0, false);
  1287. private bool _draggingItem = false;
  1288. private Rect _cursorRect = Rect.zero;
  1289. private bool _showCursor = false;
  1290. private bool draggingItem
  1291. {
  1292. get => _draggingItem;
  1293. set
  1294. {
  1295. _draggingItem = value;
  1296. wantsMouseMove = value;
  1297. wantsMouseEnterLeaveWindow = value;
  1298. }
  1299. }
  1300. private class ItemSelectionState : BrushSelectionState
  1301. {
  1302. public SelectionFieldState overwriteSettings = SelectionFieldState.SAME;
  1303. public SelectionFieldState frequency = SelectionFieldState.SAME;
  1304. public override bool changed => base.changed || embedInSurface == SelectionFieldState.CHANGED
  1305. || frequency == SelectionFieldState.CHANGED;
  1306. public override void Reset()
  1307. {
  1308. base.Reset();
  1309. overwriteSettings = SelectionFieldState.SAME;
  1310. frequency = SelectionFieldState.SAME;
  1311. }
  1312. }
  1313. private ItemSelectionState _itemSelectionState = new ItemSelectionState();
  1314. private MultibrushItemSettings _itemSelectionSettings = new MultibrushItemSettings();
  1315. private void ItemSelectionFields(bool checkSelectionIndexes = true)
  1316. {
  1317. var selection = _selection.ToArray();
  1318. var settingsArray = PaletteManager.selectedBrush.items;
  1319. if (checkSelectionIndexes)
  1320. {
  1321. for (int i = 0; i < selection.Length - 1; ++i)
  1322. {
  1323. var brushIdx = selection[i];
  1324. var nextBrushIdx = selection[i + 1];
  1325. if (brushIdx >= settingsArray.Length || nextBrushIdx >= settingsArray.Length)
  1326. {
  1327. _selection.Clear();
  1328. _selection.Add(0);
  1329. _selectedItemIdx = 0;
  1330. UpdateBrushSelectionSettings(_selection.ToArray(), settingsArray,
  1331. _itemSelectionState, _itemSelectionSettings);
  1332. ItemSelectionFields(false);
  1333. Repaint();
  1334. return;
  1335. }
  1336. }
  1337. }
  1338. UpdateSelectionState(settingsArray, selection, _itemSelectionState);
  1339. _itemSelectionState.overwriteSettings = SelectionFieldState.SAME;
  1340. _itemSelectionState.frequency = SelectionFieldState.SAME;
  1341. for (int i = 0; i < selection.Length - 1; ++i)
  1342. {
  1343. var brushIdx = selection[i];
  1344. var nextBrushIdx = selection[i + 1];
  1345. var brush = settingsArray[brushIdx];
  1346. var nextBrush = settingsArray[nextBrushIdx];
  1347. if (_itemSelectionState.overwriteSettings != SelectionFieldState.CHANGED
  1348. && brush.overwriteSettings != nextBrush.overwriteSettings)
  1349. _itemSelectionState.overwriteSettings = SelectionFieldState.MIXED;
  1350. if (_itemSelectionState.frequency != SelectionFieldState.CHANGED
  1351. && brush.frequency != nextBrush.frequency)
  1352. _itemSelectionState.frequency = SelectionFieldState.MIXED;
  1353. }
  1354. BrushSelectionFields(ref _itemPosGroupOpen, ref _itemRotGroupOpen, ref _itemScaleGroupOpen,
  1355. ref _itemFlipGroupOpen, MULTIBRUSH_SETTINGS_UNDO_MSG, true, false, settingsArray, selection,
  1356. _itemSelectionSettings, _itemSelectionState);
  1357. }
  1358. private void BrushItems(ref BrushInputData toggleData)
  1359. {
  1360. var brush = PaletteManager.selectedBrush;
  1361. var items = brush.items;
  1362. for (int i = 0; i < items.Length; ++i)
  1363. {
  1364. var item = items[i];
  1365. BrushItem(item, i, ref toggleData);
  1366. }
  1367. if (_showCursor) GUI.Box(_cursorRect, string.Empty, _cursorStyle);
  1368. }
  1369. private void SelectPrefabs(object idx)
  1370. {
  1371. var prefabs = new System.Collections.Generic.List<GameObject>();
  1372. if (_selection.Contains((int)idx))
  1373. foreach (int selectedIdx in _selection)
  1374. {
  1375. var prefab = PaletteManager.selectedBrush.GetItemAt(selectedIdx).prefab;
  1376. if (prefab != null) prefabs.Add(prefab);
  1377. }
  1378. else
  1379. {
  1380. var prefab = PaletteManager.selectedBrush.GetItemAt((int)idx).prefab;
  1381. if (prefab != null) prefabs.Add(prefab);
  1382. }
  1383. UnityEditor.Selection.objects = prefabs.ToArray();
  1384. }
  1385. private void OpenPrefab(object idx)
  1386. {
  1387. var prefab = PaletteManager.selectedBrush.GetItemAt((int)idx).prefab;
  1388. if (prefab != null) UnityEditor.AssetDatabase.OpenAsset(prefab);
  1389. }
  1390. private void UpdateThumbnail(object idx)
  1391. {
  1392. var item = PaletteManager.selectedBrush.GetItemAt((int)idx);
  1393. item.UpdateThumbnail(updateItemThumbnails: true, savePng: true);
  1394. }
  1395. private void EditThumbnail(object idx)
  1396. {
  1397. var itemIdx = (int)idx;
  1398. var item = PaletteManager.selectedBrush.GetItemAt(itemIdx);
  1399. ThumbnailEditorWindow.ShowWindow(item, itemIdx);
  1400. }
  1401. private void CopyThumbnailSettings(object idx)
  1402. {
  1403. var item = PaletteManager.selectedBrush.GetItemAt((int)idx);
  1404. PaletteManager.clipboardThumbnailSettings = item.thumbnailSettings.Clone();
  1405. PaletteManager.clipboardOverwriteThumbnailSettings = item.overwriteThumbnailSettings
  1406. ? PaletteManager.Trit.TRUE : PaletteManager.Trit.FALSE;
  1407. }
  1408. private void PasteThumbnailSettings(object idx)
  1409. {
  1410. if (PaletteManager.clipboardThumbnailSettings == null) return;
  1411. void Paste(MultibrushItemSettings item)
  1412. {
  1413. if (PaletteManager.clipboardOverwriteThumbnailSettings != PaletteManager.Trit.SAME)
  1414. {
  1415. item.overwriteThumbnailSettings
  1416. = PaletteManager.clipboardOverwriteThumbnailSettings == PaletteManager.Trit.TRUE;
  1417. }
  1418. item.thumbnailSettings.Copy(PaletteManager.clipboardThumbnailSettings);
  1419. ThumbnailUtils.UpdateThumbnail(item, savePng: true, updateParent: true);
  1420. }
  1421. if (_selection.Contains((int)idx))
  1422. {
  1423. foreach (var i in _selection) Paste(PaletteManager.selectedBrush.GetItemAt(i));
  1424. }
  1425. else Paste(PaletteManager.selectedBrush.GetItemAt((int)idx));
  1426. PaletteManager.selectedPalette.Save();
  1427. }
  1428. private void DeleteItem(object obj)
  1429. {
  1430. var idx = (int)obj;
  1431. if (_selection.Contains(idx))
  1432. {
  1433. var descendingSelection = _selection.ToArray();
  1434. System.Array.Sort<int>(descendingSelection, new System.Comparison<int>((i1, i2) => i2.CompareTo(i1)));
  1435. foreach (var i in descendingSelection) PaletteManager.selectedBrush.RemoveItemAt(i);
  1436. }
  1437. else PaletteManager.selectedBrush.RemoveItemAt(idx);
  1438. _selectedItemIdx = Mathf.Clamp(_selectedItemIdx, 0, PaletteManager.selectedBrush.itemCount - 1);
  1439. _selection.Clear();
  1440. _selection.Add(_selectedItemIdx);
  1441. OnMultiBrushChanged();
  1442. }
  1443. private void AddItemAt(object obj)
  1444. {
  1445. _newItemIdx = (int)obj;
  1446. _currentPickerId = UnityEditor.EditorGUIUtility.GetControlID(FocusType.Passive) + 100;
  1447. UnityEditor.EditorGUIUtility.ShowObjectPicker<GameObject>(null, false, "t:Prefab", _currentPickerId);
  1448. }
  1449. private void CreateItemsFromEachPrefabInFolder(object obj)
  1450. {
  1451. _newItemIdx = (int)obj;
  1452. var items = PluginMaster.DropUtils.GetFolderItems();
  1453. if (items == null) return;
  1454. for (int i = 0; i < items.Length; ++i)
  1455. {
  1456. var item = items[i];
  1457. if (item.obj == null) continue;
  1458. _newItem = new MultibrushItemSettings(item.obj, PaletteManager.selectedBrush);
  1459. PaletteManager.selectedBrush.InsertItemAt(_newItem, _newItemIdx + 1 + i);
  1460. }
  1461. OnMultiBrushChanged();
  1462. }
  1463. public void CreateItemsFromEachPrefabSelected(object obj)
  1464. {
  1465. _newItemIdx = (int)obj;
  1466. var selectionPrefabs = SelectionManager.GetSelectionPrefabs();
  1467. if (selectionPrefabs.Length == 0) return;
  1468. for (int i = 0; i < selectionPrefabs.Length; ++i)
  1469. {
  1470. var selectedObj = selectionPrefabs[i];
  1471. if (selectedObj == null) continue;
  1472. _newItem = new MultibrushItemSettings(selectedObj, PaletteManager.selectedBrush);
  1473. PaletteManager.selectedBrush.InsertItemAt(_newItem, _newItemIdx + 1 + i);
  1474. }
  1475. OnMultiBrushChanged();
  1476. }
  1477. private void BrushItem(MultibrushItemSettings item, int index, ref BrushInputData data)
  1478. {
  1479. var style = new GUIStyle(_itemStyle);
  1480. var selection = _selection.ToArray();
  1481. if (PaletteManager.selectedBrush == null) return;
  1482. var settingsArray = PaletteManager.selectedBrush.items;
  1483. for (int i = 0; i < selection.Length; ++i)
  1484. {
  1485. if (selection[i] >= settingsArray.Length)
  1486. {
  1487. _selection.Clear();
  1488. _selection.Add(0);
  1489. _selectedItemIdx = 0;
  1490. UpdateBrushSelectionSettings(_selection.ToArray(), settingsArray,
  1491. _itemSelectionState, _itemSelectionSettings);
  1492. break;
  1493. }
  1494. }
  1495. if (_selection.Contains(index)) style.normal = _itemStyle.onNormal;
  1496. using (new GUILayout.VerticalScope(style))
  1497. {
  1498. var nameStyle = GUIStyle.none;
  1499. nameStyle.margin = new RectOffset(2, 2, 0, 1);
  1500. nameStyle.clipping = TextClipping.Clip;
  1501. nameStyle.fontSize = 8;
  1502. if (item.prefab == null) return;
  1503. GUILayout.Box(new GUIContent((index + 1).ToString() + ". " + item.prefab.name, item.prefab.name),
  1504. nameStyle, GUILayout.Width(56));
  1505. GUILayout.Box(new GUIContent(item.thumbnail, item.prefab.name), GUIStyle.none,
  1506. GUILayout.Width(64), GUILayout.Height(64));
  1507. }
  1508. var rect = GUILayoutUtility.GetLastRect();
  1509. var toggleRect = new Rect(rect.xMax - 16, rect.yMax - 16, 14, 14);
  1510. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1511. {
  1512. var include = GUI.Toggle(toggleRect, item.includeInThumbnail, GUIContent.none, _thumbnailToggleStyle);
  1513. if (check.changed)
  1514. {
  1515. item.includeInThumbnail = include;
  1516. PaletteManager.selectedPalette.Save();
  1517. ThumbnailUtils.UpdateThumbnail(item.parentSettings, updateItemThumbnails: false, savePng: true);
  1518. }
  1519. }
  1520. if (rect.Contains(Event.current.mousePosition))
  1521. data = new BrushInputData(index, rect, Event.current.type, Event.current.control,
  1522. Event.current.shift, Event.current.mousePosition.x);
  1523. }
  1524. private void CopyItemSettings(object idx)
  1525. => PaletteManager.clipboardSetting = PaletteManager.selectedBrush.items[(int)idx].Clone();
  1526. private void PasteItemSettings(object idx)
  1527. {
  1528. PaletteManager.selectedBrush.items[(int)idx].Copy(PaletteManager.clipboardSetting);
  1529. PaletteManager.selectedPalette.Save();
  1530. }
  1531. private void DuplicateItem(object obj)
  1532. {
  1533. var idx = (int)obj;
  1534. if (_selection.Contains(idx))
  1535. {
  1536. var descendingSelection = _selection.ToArray();
  1537. System.Array.Sort<int>(descendingSelection, new System.Comparison<int>((i1, i2) => i2.CompareTo(i1)));
  1538. for (int i = 0; i < descendingSelection.Length; ++i)
  1539. {
  1540. PaletteManager.selectedBrush.Duplicate(descendingSelection[i]);
  1541. descendingSelection[i] += descendingSelection.Length - 1 - i;
  1542. }
  1543. _selection.Clear();
  1544. _selection.AddRange(descendingSelection);
  1545. }
  1546. else PaletteManager.selectedBrush.Duplicate(idx);
  1547. OnMultiBrushChanged();
  1548. BrushstrokeManager.UpdateBrushstroke();
  1549. }
  1550. private void ItemMouseEventHandler(BrushInputData data)
  1551. {
  1552. if (data == null) return;
  1553. if (data.eventType == EventType.MouseUp && Event.current.button == 0)
  1554. {
  1555. void SelectionChanged()
  1556. {
  1557. var selection = _selection.ToArray();
  1558. var settingsArray = PaletteManager.selectedBrush.items;
  1559. UpdateBrushSelectionSettings(_selection.ToArray(), settingsArray,
  1560. _itemSelectionState, _itemSelectionSettings);
  1561. _itemSelectionState.overwriteSettings = SelectionFieldState.SAME;
  1562. for (int i = 0; i < selection.Length - 1; ++i)
  1563. {
  1564. var brushIdx = selection[i];
  1565. var nextBrushIdx = selection[i + 1];
  1566. var brush = settingsArray[brushIdx];
  1567. var nextBrush = settingsArray[nextBrushIdx];
  1568. if (brush.overwriteSettings != nextBrush.overwriteSettings)
  1569. {
  1570. _itemSelectionState.overwriteSettings = SelectionFieldState.MIXED;
  1571. _itemSelectionSettings.overwriteSettings = true;
  1572. }
  1573. }
  1574. if (_itemSelectionState.overwriteSettings == SelectionFieldState.SAME)
  1575. _itemSelectionSettings.overwriteSettings = settingsArray[selection[0]].overwriteSettings;
  1576. _itemSelectionSettings.frequency = settingsArray[selection[0]].frequency;
  1577. }
  1578. void DeselectAllButCurrent()
  1579. {
  1580. _selection.Clear();
  1581. _selection.Add(data.index);
  1582. _selectedItemIdx = data.index;
  1583. SelectionChanged();
  1584. }
  1585. void ToggleCurrent()
  1586. {
  1587. if (_selection.Contains(data.index))
  1588. {
  1589. if (_selection.Count <= 1) return;
  1590. _selectedItemIdx = Mathf.Clamp(_selection.IndexOf(data.index), 0,
  1591. PaletteManager.selectedBrush.itemCount - 2);
  1592. _selection.Remove(data.index);
  1593. }
  1594. else
  1595. {
  1596. _selection.Add(data.index);
  1597. _selectedItemIdx = data.index;
  1598. }
  1599. SelectionChanged();
  1600. }
  1601. if (data.shift)
  1602. {
  1603. var sign = (int)Mathf.Sign(data.index - _selectedItemIdx);
  1604. if (sign != 0)
  1605. {
  1606. _selection.Clear();
  1607. for (int i = _selectedItemIdx; i != data.index; i += sign) _selection.Add(i);
  1608. _selection.Add(data.index);
  1609. SelectionChanged();
  1610. }
  1611. else DeselectAllButCurrent();
  1612. }
  1613. else if (data.control) ToggleCurrent();
  1614. else DeselectAllButCurrent();
  1615. Repaint();
  1616. Event.current.Use();
  1617. }
  1618. else if (data.eventType == EventType.ContextClick)
  1619. {
  1620. var menu = new UnityEditor.GenericMenu();
  1621. menu.AddItem(new GUIContent("Select Prefab" + (_selection.Count > 1 ? "s" : "")),
  1622. false, SelectPrefabs, data.index);
  1623. if (_selection.Count == 1)
  1624. menu.AddItem(new GUIContent("Open Prefab"), false, OpenPrefab, data.index);
  1625. menu.AddSeparator(string.Empty);
  1626. menu.AddItem(new GUIContent("Update Thumbnail"), false, UpdateThumbnail, data.index);
  1627. menu.AddItem(new GUIContent("Edit Thumbnail"), false, EditThumbnail, data.index);
  1628. menu.AddItem(new GUIContent("Copy Thumbnail Settings"), false, CopyThumbnailSettings, data.index);
  1629. if (PaletteManager.clipboardThumbnailSettings != null)
  1630. menu.AddItem(new GUIContent("Paste Thumbnail Settings"), false, PasteThumbnailSettings, data.index);
  1631. menu.AddSeparator(string.Empty);
  1632. if (PaletteManager.selectedBrush.items.Length > 1
  1633. && _selection.Count < PaletteManager.selectedBrush.items.Length)
  1634. menu.AddItem(new GUIContent("Delete"), false, DeleteItem, data.index);
  1635. menu.AddItem(new GUIContent("Duplicate"), false, DuplicateItem, data.index);
  1636. if (_selection.Count == 1)
  1637. menu.AddItem(new GUIContent("Copy Brush Settings"), false, CopyItemSettings, data.index);
  1638. if (PaletteManager.clipboardSetting != null)
  1639. menu.AddItem(new GUIContent("Paste Brush Settings"), false, PasteItemSettings, data.index);
  1640. menu.AddSeparator(string.Empty);
  1641. menu.AddItem(new GUIContent("New Item..."), false, AddItemAt, data.index);
  1642. menu.AddItem(new GUIContent("New Items From Folder..."),
  1643. false, CreateItemsFromEachPrefabInFolder, data.index);
  1644. menu.AddItem(new GUIContent("New Items From Selection"),
  1645. false, CreateItemsFromEachPrefabSelected, data.index);
  1646. menu.ShowAsContext();
  1647. Event.current.Use();
  1648. }
  1649. else if (data.eventType == EventType.MouseDrag)
  1650. {
  1651. UnityEditor.DragAndDrop.PrepareStartDrag();
  1652. UnityEditor.DragAndDrop.StartDrag("Dragging brush");
  1653. UnityEditor.DragAndDrop.visualMode = UnityEditor.DragAndDropVisualMode.Copy;
  1654. draggingItem = true;
  1655. _moveItem.from = data.index;
  1656. _moveItem.perform = false;
  1657. _moveItem.to = -1;
  1658. Event.current.Use();
  1659. }
  1660. else if (data.eventType == EventType.DragUpdated)
  1661. {
  1662. UnityEditor.DragAndDrop.visualMode = UnityEditor.DragAndDropVisualMode.Copy;
  1663. var size = new Vector2(4, data.rect.height);
  1664. var min = data.rect.min;
  1665. var toTheRight = data.mouseX - data.rect.center.x > 0;
  1666. min.x = toTheRight ? data.rect.max.x : min.x - size.x;
  1667. _cursorRect = new Rect(min, size);
  1668. _showCursor = true;
  1669. _moveItem.to = data.index;
  1670. if (toTheRight) ++_moveItem.to;
  1671. Event.current.Use();
  1672. }
  1673. else if (data.eventType == EventType.DragPerform)
  1674. {
  1675. var toTheRight = data.mouseX - data.rect.center.x > 0;
  1676. _moveItem.to = data.index;
  1677. if (toTheRight) ++_moveItem.to;
  1678. if (draggingItem)
  1679. {
  1680. _moveItem.perform = _moveItem.from != _moveItem.to;
  1681. draggingItem = false;
  1682. }
  1683. _showCursor = false;
  1684. Event.current.Use();
  1685. }
  1686. else if (data.eventType == EventType.DragExited)
  1687. {
  1688. _showCursor = false;
  1689. draggingItem = false;
  1690. _moveItem.to = -1;
  1691. }
  1692. }
  1693. private void OnObjectSelectorClosed()
  1694. {
  1695. if (Event.current.commandName == "ObjectSelectorClosed"
  1696. && UnityEditor.EditorGUIUtility.GetObjectPickerControlID() == _currentPickerId)
  1697. {
  1698. var obj = UnityEditor.EditorGUIUtility.GetObjectPickerObject();
  1699. if (obj != null)
  1700. {
  1701. var prefabType = UnityEditor.PrefabUtility.GetPrefabAssetType(obj);
  1702. if (prefabType == UnityEditor.PrefabAssetType.Regular
  1703. || prefabType == UnityEditor.PrefabAssetType.Variant)
  1704. {
  1705. _itemAdded = true;
  1706. _newItem = new MultibrushItemSettings(obj as GameObject, PaletteManager.selectedBrush);
  1707. }
  1708. }
  1709. _currentPickerId = -1;
  1710. }
  1711. }
  1712. private void OnMultiBrushChanged()
  1713. {
  1714. if (PrefabPalette.instance != null) PrefabPalette.instance.OnPaletteChange();
  1715. }
  1716. private void ItemSettingsGroup()
  1717. {
  1718. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  1719. {
  1720. var item = GetSelectedItem(PaletteManager.selectedBrush);
  1721. if (_selection.Count <= 1)
  1722. BrushFields(item, ref _itemPosGroupOpen, ref _itemRotGroupOpen,
  1723. ref _itemScaleGroupOpen, ref _itemFlipGroupOpen);
  1724. else ItemSelectionFields();
  1725. }
  1726. }
  1727. private MultibrushItemSettings GetSelectedItem(MultibrushSettings brush)
  1728. {
  1729. if (brush == null) return null;
  1730. var item = brush.GetItemAt(_selectedItemIdx);
  1731. if (item == null)
  1732. {
  1733. _selectedItemIdx = 0;
  1734. item = brush.GetItemAt(_selectedItemIdx);
  1735. }
  1736. return item;
  1737. }
  1738. #endregion
  1739. #region FREQUENCY
  1740. private readonly string[] FREQUENCY_MODES = new string[] { "Random", "Pattern" };
  1741. private Texture2D _warningTexture = null;
  1742. private string _patternWarningMsg = null;
  1743. private void FrequencyGroup()
  1744. {
  1745. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  1746. {
  1747. var brush = PaletteManager.selectedBrush;
  1748. var changed = false;
  1749. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1750. {
  1751. var frequencyMode = (MultibrushSettings.FrequencyMode)
  1752. UnityEditor.EditorGUILayout.Popup("Frequency Mode:", (int)brush.frequencyMode, FREQUENCY_MODES);
  1753. if (check.changed)
  1754. {
  1755. changed = true;
  1756. brush.frequencyMode = frequencyMode;
  1757. }
  1758. }
  1759. var item = GetSelectedItem(brush);
  1760. if (brush.frequencyMode == MultibrushSettings.FrequencyMode.RANDOM)
  1761. {
  1762. using (new GUILayout.HorizontalScope())
  1763. {
  1764. if (_selection.Count <= 1)
  1765. {
  1766. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1767. {
  1768. var frequency = UnityEditor.EditorGUILayout.FloatField("Frequency:", item.frequency);
  1769. if (check.changed)
  1770. {
  1771. changed = true;
  1772. item.frequency = frequency;
  1773. }
  1774. }
  1775. GUILayout.Label("in " + brush.totalFrequency);
  1776. }
  1777. else
  1778. {
  1779. GUILayout.Box(GetStateGUIContent(_itemSelectionState.frequency),
  1780. UnityEditor.EditorStyles.label);
  1781. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1782. {
  1783. _itemSelectionSettings.frequency = UnityEditor.EditorGUILayout.FloatField("Frequency:",
  1784. _itemSelectionSettings.frequency);
  1785. if (check.changed)
  1786. {
  1787. foreach (var selectedIdx in _selection)
  1788. {
  1789. var selectedItem = PaletteManager.selectedBrush.GetItemAt(selectedIdx);
  1790. selectedItem.frequency = _itemSelectionSettings.frequency;
  1791. }
  1792. brush.UpdateTotalFrequency();
  1793. _itemSelectionState.frequency = SelectionFieldState.CHANGED;
  1794. }
  1795. }
  1796. GUILayout.Label("in " + brush.totalFrequency);
  1797. GUILayout.FlexibleSpace();
  1798. }
  1799. }
  1800. }
  1801. else
  1802. {
  1803. using (new GUILayout.HorizontalScope())
  1804. {
  1805. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1806. {
  1807. var pattern = UnityEditor.EditorGUILayout.TextField("Pattern:", brush.pattern);
  1808. if (check.changed || brush.patternMachine == null)
  1809. {
  1810. _patternWarningMsg = null;
  1811. switch (PatternMachine.Validate(pattern, brush.items.Length,
  1812. out PatternMachine.Token[] tokens, out PatternMachine.Token[] endTokens))
  1813. {
  1814. case PatternMachine.ValidationResult.EMPTY:
  1815. _patternWarningMsg = "Empty pattern"; break;
  1816. case PatternMachine.ValidationResult.INDEX_OUT_OF_RANGE:
  1817. _patternWarningMsg = "Index out of range"; break;
  1818. case PatternMachine.ValidationResult.MISPLACED_PERIOD:
  1819. _patternWarningMsg = "Misplaced period"; break;
  1820. case PatternMachine.ValidationResult.MISPLACED_ASTERISK:
  1821. _patternWarningMsg = "Misplaced asterisk"; break;
  1822. case PatternMachine.ValidationResult.MISSING_COMMA:
  1823. _patternWarningMsg = "Missing comma"; break;
  1824. case PatternMachine.ValidationResult.MISPLACED_COMMA:
  1825. _patternWarningMsg = "Mispalced comma"; break;
  1826. case PatternMachine.ValidationResult.UNPAIRED_PARENTHESIS:
  1827. _patternWarningMsg = "Unpaired parenthesis"; break;
  1828. case PatternMachine.ValidationResult.EMPTY_PARENTHESIS:
  1829. _patternWarningMsg = "Empty parenthesis"; break;
  1830. case PatternMachine.ValidationResult.INVALID_MULTIPLIER:
  1831. _patternWarningMsg = "The multiplier must be greater than one"; break;
  1832. case PatternMachine.ValidationResult.UNPAIRED_BRACKET:
  1833. _patternWarningMsg = "Unpaired bracket"; break;
  1834. case PatternMachine.ValidationResult.EMPTY_BRACKET:
  1835. _patternWarningMsg = "Empty bracket"; break;
  1836. case PatternMachine.ValidationResult.INVALID_NESTED_BRACKETS:
  1837. _patternWarningMsg = "Invalid nested bracket"; break;
  1838. case PatternMachine.ValidationResult.INVALID_PARENTHESES_WITHIN_BRACKETS:
  1839. _patternWarningMsg = "Invalid parentheses within brackets"; break;
  1840. case PatternMachine.ValidationResult.MISPLACED_VERTICAL_BAR:
  1841. _patternWarningMsg = "Misplaced vertical bar"; break;
  1842. case PatternMachine.ValidationResult.MISPLACED_COLON:
  1843. _patternWarningMsg = "Misplaced Colon"; break;
  1844. case PatternMachine.ValidationResult.INVALID_CHARACTER:
  1845. _patternWarningMsg = "Invalid character"; break;
  1846. default:
  1847. brush.pattern = pattern;
  1848. brush.patternMachine = new PatternMachine(tokens, endTokens);
  1849. break;
  1850. }
  1851. }
  1852. if (_patternWarningMsg != null && _patternWarningMsg != string.Empty)
  1853. {
  1854. var style = new GUIStyle();
  1855. style.margin.top = 4;
  1856. if (_warningTexture == null)
  1857. _warningTexture = Resources.Load<Texture2D>("Sprites/Warning");
  1858. GUILayout.Box(new GUIContent(_warningTexture, _patternWarningMsg), style,
  1859. GUILayout.Width(14), GUILayout.Height(14));
  1860. }
  1861. }
  1862. }
  1863. using (new GUILayout.VerticalScope(UnityEditor.EditorStyles.helpBox))
  1864. {
  1865. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1866. {
  1867. var restartPatternForEachStroke
  1868. = UnityEditor.EditorGUILayout.ToggleLeft("Restart the pattern for each stroke",
  1869. brush.restartPatternForEachStroke, GUILayout.Width(220));
  1870. if (check.changed)
  1871. {
  1872. changed = true;
  1873. brush.restartPatternForEachStroke = restartPatternForEachStroke;
  1874. }
  1875. }
  1876. if (!brush.restartPatternForEachStroke)
  1877. {
  1878. if (GUILayout.Button("Restart Pattern"))
  1879. {
  1880. brush.patternMachine.Reset();
  1881. BrushstrokeManager.UpdateBrushstroke();
  1882. }
  1883. }
  1884. }
  1885. }
  1886. if (changed)
  1887. {
  1888. BrushstrokeManager.UpdateBrushstroke(false);
  1889. PaletteManager.selectedPalette.Save();
  1890. UnityEditor.SceneView.RepaintAll();
  1891. }
  1892. }
  1893. }
  1894. #endregion
  1895. #endregion
  1896. }
  1897. }