TemplateOptionsData.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233
  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using System.Text.RegularExpressions;
  5. using System.Collections.Generic;
  6. using UnityEngine;
  7. namespace AmplifyShaderEditor
  8. {
  9. /*ase_pass_options OLDEST
  10. DefineOnConnected:portId:definevalue
  11. DefineOnUnconnected:portId:definevalue
  12. Options:name:defaultOption:opt0:opt1:opt2
  13. SetVisible:PortId:OptionName:OptionValue
  14. */
  15. /*ase_pass_options OLD
  16. Option:Option Name:UI Type:Default:Item0,Item1,Item3...ItemN
  17. Action:Action Type:Action Data:ConditionA && ConditionB || ConditionC:
  18. */
  19. /*ase_pass_options:UniqueId:PropagateDataToHiddenPasses
  20. Option:Color Offset:A,B,C:A
  21. A:ShowPort:My Port Name
  22. B,C:HidePort:My Port Name
  23. B:SetDefine:MY_DEFINE
  24. C:SetDefine:MY_COLOR_DEFINE
  25. Option:My Other Option:True,False
  26. True:ShowOption:Color Offset
  27. False:HideOption:Color Offset
  28. Port:My Port Name
  29. On:SetDefine:MY_COLOR_DEFINE
  30. Off:UnsetDefine:MY_COLOR_DEFINE
  31. */
  32. public enum AseOptionsUIWidget
  33. {
  34. Dropdown,
  35. Toggle,
  36. Float,
  37. FloatRange,
  38. Int,
  39. IntRange
  40. }
  41. public enum AseOptionsType
  42. {
  43. Option,
  44. Port,
  45. Field
  46. }
  47. public enum AseOptionItemSetup
  48. {
  49. None,
  50. InvertActionOnDeselection
  51. }
  52. public enum AseOptionsActionType
  53. {
  54. RefreshOption,
  55. ShowOption,
  56. HideOption,
  57. SetOption,
  58. HidePort,
  59. ShowPort,
  60. SetPortName,
  61. SetDefine,
  62. RemoveDefine,
  63. SetUndefine,
  64. RemoveUndefine,
  65. ExcludePass,
  66. IncludePass,
  67. SetPropertyOnPass,
  68. SetPropertyOnSubShader,
  69. SetShaderProperty,
  70. SetMaterialProperty,
  71. ExcludeAllPassesBut
  72. }
  73. public enum PropertyActionsEnum
  74. {
  75. CullMode,
  76. ColorMask,
  77. ColorMask1,
  78. ColorMask2,
  79. ColorMask3,
  80. ZWrite,
  81. ZTest,
  82. ZOffsetFactor,
  83. ZOffsetUnits,
  84. BlendRGB,
  85. BlendAlpha,
  86. BlendOpRGB,
  87. BlendOpAlpha,
  88. BlendRGB1,
  89. BlendAlpha1,
  90. BlendOpRGB1,
  91. BlendOpAlpha1,
  92. BlendRGB2,
  93. BlendAlpha2,
  94. BlendOpRGB2,
  95. BlendOpAlpha2,
  96. BlendRGB3,
  97. BlendAlpha3,
  98. BlendOpRGB3,
  99. BlendOpAlpha3,
  100. StencilReference,
  101. StencilReadMask,
  102. StencilWriteMask,
  103. StencilComparison,
  104. StencilPass,
  105. StencilFail,
  106. StencilZFail,
  107. RenderType,
  108. RenderQueue,
  109. DisableBatching,
  110. ChangeTagValue
  111. }
  112. public enum AseOptionsSetup
  113. {
  114. CopyOptionsFromMainPass,
  115. Id,
  116. Name
  117. }
  118. [Serializable]
  119. public class ItemColorMask
  120. {
  121. public bool ValueR = true;
  122. public bool ValueG = true;
  123. public bool ValueB = true;
  124. public bool ValueA = true;
  125. public bool MaskR = false;
  126. public bool MaskG = false;
  127. public bool MaskB = false;
  128. public bool MaskA = false;
  129. public bool[] GetColorMask( bool[] input )
  130. {
  131. bool[] result = { ValueR, ValueG, ValueB, ValueA };
  132. result[ 0 ] = MaskR ? ValueR : input[ 0 ];
  133. result[ 1 ] = MaskG ? ValueG : input[ 1 ];
  134. result[ 2 ] = MaskB ? ValueB : input[ 2 ];
  135. result[ 3 ] = MaskA ? ValueA : input[ 3 ];
  136. return result;
  137. }
  138. public void SetColorMask( int index, string value )
  139. {
  140. switch( index )
  141. {
  142. default:
  143. case 0:
  144. {
  145. MaskR = !string.IsNullOrEmpty( value );
  146. if(MaskR)
  147. ValueR = Convert.ToBoolean( value );
  148. }
  149. break;
  150. case 1:
  151. {
  152. MaskG = !string.IsNullOrEmpty( value );
  153. if( MaskG )
  154. ValueG = Convert.ToBoolean( value );
  155. }
  156. break;
  157. case 2:
  158. {
  159. MaskB = !string.IsNullOrEmpty( value );
  160. if( MaskB )
  161. ValueB = Convert.ToBoolean( value );
  162. }
  163. break;
  164. case 3:
  165. {
  166. MaskA = !string.IsNullOrEmpty( value );
  167. if( MaskA )
  168. ValueA = Convert.ToBoolean( value );
  169. }
  170. break;
  171. }
  172. }
  173. }
  174. [Serializable]
  175. public class TemplateActionItemConditional
  176. {
  177. public enum Conditional
  178. {
  179. None,
  180. Equal,
  181. NotEqual
  182. }
  183. public Conditional Condition = Conditional.None;
  184. public string Option = null;
  185. public string Value = null;
  186. public bool IsValid => ( Condition != Conditional.None );
  187. public TemplateActionItemConditional( string condition, string option, string value )
  188. {
  189. Condition = condition.Equals( "=" ) ? Conditional.Equal : Conditional.NotEqual;
  190. Option = option;
  191. Value = value;
  192. }
  193. }
  194. [Serializable]
  195. public class TemplateActionItem
  196. {
  197. public TemplateActionItemConditional ActionConditional = null;
  198. public AseOptionsActionType ActionType;
  199. public string ActionData = string.Empty;
  200. public string ActionData2 = string.Empty;
  201. public int ActionDataIdx = -1;
  202. public string PassName;
  203. public bool AllPasses = false;
  204. public PropertyActionsEnum PropertyAction;
  205. //CULL
  206. public CullMode ActionCullMode;
  207. //COLOR MASK
  208. public ItemColorMask ColorMask = new ItemColorMask();
  209. public ItemColorMask ColorMask1 = new ItemColorMask();
  210. public ItemColorMask ColorMask2 = new ItemColorMask();
  211. public ItemColorMask ColorMask3 = new ItemColorMask();
  212. //DEPTH
  213. public ZWriteMode ActionZWrite;
  214. public ZTestMode ActionZTest;
  215. public float ActionZOffsetFactor;
  216. public float ActionZOffsetUnits;
  217. //BLEND OPS
  218. public AvailableBlendFactor ActionBlendRGBSource;
  219. public AvailableBlendFactor ActionBlendRGBDest;
  220. public AvailableBlendFactor ActionBlendAlphaSource;
  221. public AvailableBlendFactor ActionBlendAlphaDest;
  222. public AvailableBlendOps ActionBlendOpRGB;
  223. public AvailableBlendOps ActionBlendOpAlpha;
  224. public AvailableBlendFactor ActionBlendRGBSource1;
  225. public AvailableBlendFactor ActionBlendRGBDest1;
  226. public AvailableBlendFactor ActionBlendAlphaSource1;
  227. public AvailableBlendFactor ActionBlendAlphaDest1;
  228. public AvailableBlendOps ActionBlendOpRGB1;
  229. public AvailableBlendOps ActionBlendOpAlpha1;
  230. public AvailableBlendFactor ActionBlendRGBSource2;
  231. public AvailableBlendFactor ActionBlendRGBDest2;
  232. public AvailableBlendFactor ActionBlendAlphaSource2;
  233. public AvailableBlendFactor ActionBlendAlphaDest2;
  234. public AvailableBlendOps ActionBlendOpRGB2;
  235. public AvailableBlendOps ActionBlendOpAlpha2;
  236. public AvailableBlendFactor ActionBlendRGBSource3;
  237. public AvailableBlendFactor ActionBlendRGBDest3;
  238. public AvailableBlendFactor ActionBlendAlphaSource3;
  239. public AvailableBlendFactor ActionBlendAlphaDest3;
  240. public AvailableBlendOps ActionBlendOpRGB3;
  241. public AvailableBlendOps ActionBlendOpAlpha3;
  242. //STENCIL
  243. public int ActionStencilReference;
  244. public int ActionStencilReadMask;
  245. public int ActionStencilWriteMask;
  246. public int ActionStencilComparison;
  247. public int ActionStencilPass;
  248. public int ActionStencilFail;
  249. public int ActionStencilZFail;
  250. public bool CopyFromSubShader = false;
  251. public string ActionBuffer;
  252. public override string ToString()
  253. {
  254. return ActionType + " " + ActionData + " " + ActionDataIdx;
  255. }
  256. public bool GetIntValueFromActionBuffer( out int result )
  257. {
  258. return int.TryParse( ActionBuffer, out result );
  259. }
  260. public bool GetFloatValueFromActionBuffer( out float result )
  261. {
  262. return float.TryParse( ActionBuffer, out result );
  263. }
  264. }
  265. [Serializable]
  266. public class TemplateActionItemGrid
  267. {
  268. [Serializable]
  269. public class TemplateActionItemRow
  270. {
  271. public TemplateActionItem[] Columns;
  272. }
  273. public TemplateActionItemRow[] Rows;
  274. public TemplateActionItemGrid( int rowsCount )
  275. {
  276. Rows = new TemplateActionItemRow[ rowsCount ];
  277. }
  278. public TemplateActionItem this[ int row, int column ]
  279. {
  280. get { return Rows[ row ].Columns[ column ]; }
  281. set { Rows[ row ].Columns[ column ] = value; }
  282. }
  283. public TemplateActionItem[] this[ int row ]
  284. {
  285. get { return Rows[ row ].Columns; }
  286. set
  287. {
  288. if( Rows[ row ] == null )
  289. Rows[ row ] = new TemplateActionItemRow();
  290. Rows[ row ].Columns = value;
  291. }
  292. }
  293. }
  294. [Serializable]
  295. public class TemplateOptionsItem
  296. {
  297. public AseOptionsType Type;
  298. public AseOptionsUIWidget UIWidget;
  299. public AseOptionItemSetup Setup = AseOptionItemSetup.None;
  300. public string Id = string.Empty;
  301. public string Name = string.Empty;
  302. public string DefaultOption = string.Empty;
  303. public string[] Options = null;
  304. public string[] DisplayOptions = null;
  305. public int DisableIdx = -1;
  306. [SerializeField]
  307. private float m_defaultFieldValue;
  308. public float FieldMin;
  309. public float FieldMax;
  310. public bool FieldInline;
  311. public string FieldInlineName;
  312. public string FieldInlineOutput = string.Empty;
  313. [SerializeField]
  314. public InlineProperty FieldValue = new InlineProperty();
  315. public TemplateActionItemGrid ActionsPerOption = null;
  316. public int Count = 0;
  317. [SerializeField]
  318. private int m_defaultOptionIndex = -1;
  319. ~TemplateOptionsItem()
  320. {
  321. Options = null;
  322. }
  323. public int OptionIndexFor( string option )
  324. {
  325. for( int i = 0; i < Options.Length; i++ )
  326. {
  327. if( Options[ i ].Equals( option ) )
  328. {
  329. return i;
  330. }
  331. }
  332. Debug.LogWarning( "Couldn't find index for option: " + option );
  333. return 0;
  334. }
  335. public int DefaultOptionIndex
  336. {
  337. get
  338. {
  339. if( m_defaultOptionIndex > -1 )
  340. return m_defaultOptionIndex;
  341. for( int i = 0; i < Options.Length; i++ )
  342. {
  343. if( Options[ i ].Equals( DefaultOption ) )
  344. {
  345. m_defaultOptionIndex = i;
  346. return i;
  347. }
  348. }
  349. Debug.LogWarning( "Couldn't find index for default option: " + DefaultOption );
  350. return 0;
  351. }
  352. }
  353. public float DefaultFieldValue
  354. {
  355. get
  356. {
  357. return m_defaultFieldValue;
  358. }
  359. set
  360. {
  361. m_defaultFieldValue = value;
  362. }
  363. }
  364. }
  365. [Serializable]
  366. public class TemplateOptionsContainer
  367. {
  368. public bool Enabled = false;
  369. public string Body = string.Empty;
  370. public int Index = -1;
  371. public int Id = -1;
  372. public string Name = string.Empty;
  373. public bool CopyOptionsFromMainPass = false;
  374. public TemplateOptionsItem[] Options = null;
  375. ~TemplateOptionsContainer()
  376. {
  377. Options = null;
  378. }
  379. public void CopyPortOptionsFrom( TemplateOptionsContainer container, string passName )
  380. {
  381. if( container == null || container.Options == null )
  382. return;
  383. List<TemplateOptionsItem> newItems = new List<TemplateOptionsItem>();
  384. for( int i = 0; i < container.Options.Length; i++ )
  385. {
  386. if( container.Options[ i ].Type == AseOptionsType.Port &&
  387. container.Options[ i ].Id.Equals( passName ) )
  388. {
  389. newItems.Add( container.Options[ i ] );
  390. }
  391. }
  392. if( newItems.Count > 0 )
  393. {
  394. Enabled = true;
  395. if( Options == null )
  396. {
  397. Options = newItems.ToArray();
  398. }
  399. else
  400. {
  401. Array.Resize<TemplateOptionsItem>( ref Options, Options.Length + newItems.Count );
  402. Array.Copy( newItems.ToArray(), Options, newItems.Count );
  403. }
  404. }
  405. newItems.Clear();
  406. newItems = null;
  407. }
  408. public int EndIndex { get { return Index + Body.Length; } }
  409. }
  410. public class TemplateOptionsToolsHelper
  411. {
  412. //public const string PassOptionsMainPattern = @"\/\*ase_pass_options:([\w:= ]*)[\n]([\w: \t;\n&|,_\+-]*)\*\/";
  413. //public const string SubShaderOptionsMainPattern = @"\/\*ase_subshader_options:([\w:= ]*)[\n]([\w: \t;\n&|,_\+-]*)\*\/";
  414. public const string PassOptionsMainPattern = "\\/\\*ase_pass_options:([\\w:= ]*)[\n]([\\w: \t;\n&|,_\\+\\-\\(\\)\\[\\]\\\"\\=\\/\\.]*)\\*\\/";
  415. public const string SubShaderOptionsMainPattern = "\\/\\*ase_subshader_options:([\\w:= ]*)[\n]([\\w: \t?!;\n&|,_\\+\\-\\(\\)\\[\\]\\\"\\=\\/\\.]*)\\*\\/";
  416. public static readonly char OptionsDataSeparator = ',';
  417. public static Dictionary<string, AseOptionsSetup> AseOptionsSetupDict = new Dictionary<string, AseOptionsSetup>()
  418. {
  419. { "CopyOptionsFromMainPass",AseOptionsSetup.CopyOptionsFromMainPass},
  420. { "Id",AseOptionsSetup.Id},
  421. { "Name",AseOptionsSetup.Name},
  422. };
  423. public static Dictionary<string, AseOptionsUIWidget> AseOptionsUITypeDict = new Dictionary<string, AseOptionsUIWidget>()
  424. {
  425. { "Dropdown",AseOptionsUIWidget.Dropdown },
  426. { "Toggle", AseOptionsUIWidget.Toggle }
  427. };
  428. public static Dictionary<string, AseOptionsActionType> AseOptionsActionTypeDict = new Dictionary<string, AseOptionsActionType>()
  429. {
  430. {"RefreshOption", AseOptionsActionType.RefreshOption },
  431. {"ShowOption", AseOptionsActionType.ShowOption },
  432. {"HideOption", AseOptionsActionType.HideOption },
  433. {"SetOption", AseOptionsActionType.SetOption },
  434. {"HidePort", AseOptionsActionType.HidePort },
  435. {"ShowPort", AseOptionsActionType.ShowPort },
  436. {"SetPortName", AseOptionsActionType.SetPortName },
  437. {"SetDefine", AseOptionsActionType.SetDefine },
  438. {"RemoveDefine", AseOptionsActionType.RemoveDefine },
  439. {"SetUndefine", AseOptionsActionType.SetUndefine },
  440. {"RemoveUndefine", AseOptionsActionType.RemoveUndefine },
  441. {"ExcludePass", AseOptionsActionType.ExcludePass },
  442. {"IncludePass", AseOptionsActionType.IncludePass },
  443. {"SetPropertyOnPass", AseOptionsActionType.SetPropertyOnPass },
  444. {"SetPropertyOnSubShader", AseOptionsActionType.SetPropertyOnSubShader },
  445. {"SetShaderProperty", AseOptionsActionType.SetShaderProperty },
  446. {"SetMaterialProperty", AseOptionsActionType.SetMaterialProperty },
  447. {"ExcludeAllPassesBut",AseOptionsActionType.ExcludeAllPassesBut}
  448. };
  449. public static Dictionary<string, AseOptionItemSetup> AseOptionItemSetupDict = new Dictionary<string, AseOptionItemSetup>
  450. {
  451. {"None", AseOptionItemSetup.None },
  452. { "InvertActionOnDeselection", AseOptionItemSetup.InvertActionOnDeselection}
  453. };
  454. public static bool InvertAction( AseOptionsActionType original, ref AseOptionsActionType inverted )
  455. {
  456. bool success = true;
  457. switch( original )
  458. {
  459. case AseOptionsActionType.RefreshOption:
  460. inverted = AseOptionsActionType.RefreshOption;
  461. break;
  462. case AseOptionsActionType.ShowOption:
  463. inverted = AseOptionsActionType.HideOption;
  464. break;
  465. case AseOptionsActionType.HideOption:
  466. inverted = AseOptionsActionType.ShowOption;
  467. break;
  468. case AseOptionsActionType.HidePort:
  469. inverted = AseOptionsActionType.ShowPort;
  470. break;
  471. case AseOptionsActionType.ShowPort:
  472. inverted = AseOptionsActionType.HidePort;
  473. break;
  474. case AseOptionsActionType.SetDefine:
  475. inverted = AseOptionsActionType.RemoveDefine;
  476. break;
  477. case AseOptionsActionType.RemoveDefine:
  478. inverted = AseOptionsActionType.SetDefine;
  479. break;
  480. case AseOptionsActionType.SetUndefine:
  481. inverted = AseOptionsActionType.RemoveUndefine;
  482. break;
  483. case AseOptionsActionType.RemoveUndefine:
  484. inverted = AseOptionsActionType.SetUndefine;
  485. break;
  486. case AseOptionsActionType.ExcludePass:
  487. inverted = AseOptionsActionType.IncludePass;
  488. break;
  489. case AseOptionsActionType.IncludePass:
  490. inverted = AseOptionsActionType.ExcludePass;
  491. break;
  492. case AseOptionsActionType.SetPortName:
  493. case AseOptionsActionType.SetOption:
  494. case AseOptionsActionType.SetPropertyOnPass:
  495. case AseOptionsActionType.SetPropertyOnSubShader:
  496. success = false;
  497. break;
  498. }
  499. return success;
  500. }
  501. public static TemplateOptionsContainer GenerateOptionsContainer( bool isSubShader, string data )
  502. {
  503. TemplateOptionsContainer optionsContainer = new TemplateOptionsContainer();
  504. Match match = Regex.Match( data, isSubShader ? SubShaderOptionsMainPattern : PassOptionsMainPattern );
  505. optionsContainer.Enabled = match.Success;
  506. if( match.Success )
  507. {
  508. try
  509. {
  510. optionsContainer.Body = match.Value;
  511. optionsContainer.Index = match.Index;
  512. List<TemplateOptionsItem> optionItemsList = new List<TemplateOptionsItem>();
  513. List<List<TemplateActionItem>> actionItemsList = new List<List<TemplateActionItem>>();
  514. Dictionary<string, int> optionItemToIndex = new Dictionary<string, int>();
  515. TemplateOptionsItem currentOption = null;
  516. //OPTIONS OVERALL SETUP
  517. string[] setupLines = match.Groups[ 1 ].Value.Split( ':' );
  518. for( int i = 0; i < setupLines.Length; i++ )
  519. {
  520. if( AseOptionsSetupDict.ContainsKey( setupLines[ i ] ) )
  521. {
  522. AseOptionsSetup setup = AseOptionsSetupDict[ setupLines[ i ] ];
  523. switch( setup )
  524. {
  525. case AseOptionsSetup.CopyOptionsFromMainPass: optionsContainer.CopyOptionsFromMainPass = true; break;
  526. }
  527. }
  528. else
  529. {
  530. string[] args = setupLines[ i ].Split( '=' );
  531. if( args.Length > 1 && AseOptionsSetupDict.ContainsKey( args[ 0 ] ) )
  532. {
  533. AseOptionsSetup setup = AseOptionsSetupDict[ args[ 0 ] ];
  534. switch( setup )
  535. {
  536. case AseOptionsSetup.Id: if( !int.TryParse( args[ 1 ], out optionsContainer.Id ) ) optionsContainer.Id = -1; break;
  537. case AseOptionsSetup.Name: optionsContainer.Name = args[ 1 ]; break;
  538. }
  539. }
  540. }
  541. }
  542. //AVAILABLE OPTIONS
  543. string body = match.Groups[ 2 ].Value.Replace( "\t", string.Empty );
  544. string[] optionLines = body.Split( '\n' );
  545. for( int oL = 0; oL < optionLines.Length; oL++ )
  546. {
  547. string[] optionItems = optionLines[ oL ].Split( ':' );
  548. if( optionItems.Length > 0 )
  549. {
  550. string[] itemIds = optionItems[ 0 ].Split( OptionsDataSeparator );
  551. switch( itemIds[ 0 ] )
  552. {
  553. case "Option":
  554. {
  555. //Fills previous option with its actions
  556. //actionItemsList is cleared over here
  557. FillOptionAction( currentOption, ref actionItemsList );
  558. optionItemToIndex.Clear();
  559. currentOption = new TemplateOptionsItem();
  560. currentOption.Type = AseOptionsType.Option;
  561. string[] optionItemSetup = optionItems[ 1 ].Split( OptionsDataSeparator );
  562. currentOption.Name = optionItemSetup[ 0 ];
  563. if( optionItemSetup.Length > 1 )
  564. {
  565. if( AseOptionItemSetupDict.ContainsKey( optionItemSetup[ 1 ] ) )
  566. currentOption.Setup = AseOptionItemSetupDict[ optionItemSetup[ 1 ] ];
  567. }
  568. currentOption.Id = itemIds.Length > 1 ? itemIds[ 1 ] : optionItems[ 1 ];
  569. currentOption.DisplayOptions = optionItems[ 2 ].Split( OptionsDataSeparator );
  570. currentOption.DisableIdx = currentOption.DisplayOptions.Length;
  571. optionItems[ 2 ] += ",disable";
  572. currentOption.Options = optionItems[ 2 ].Split( OptionsDataSeparator );
  573. currentOption.Count = currentOption.Options.Length;
  574. for( int opIdx = 0; opIdx < currentOption.Options.Length; opIdx++ )
  575. {
  576. optionItemToIndex.Add( currentOption.Options[ opIdx ], opIdx );
  577. actionItemsList.Add( new List<TemplateActionItem>() );
  578. }
  579. if( optionItems.Length > 3 )
  580. {
  581. currentOption.DefaultOption = optionItems[ 3 ];
  582. }
  583. else
  584. {
  585. currentOption.DefaultOption = currentOption.Options[ 0 ];
  586. }
  587. if( currentOption.Options.Length == 2 || ( currentOption.Options.Length == 3 && currentOption.Options[ 2 ].Equals( "disable" ) ) )
  588. {
  589. if( ( currentOption.Options[ 0 ].Equals( "true" ) && currentOption.Options[ 1 ].Equals( "false" ) ) ||
  590. ( currentOption.Options[ 0 ].Equals( "false" ) && currentOption.Options[ 1 ].Equals( "true" ) ) )
  591. {
  592. // Toggle 0 is false and 1 is true
  593. currentOption.Options[ 0 ] = "false";
  594. currentOption.Options[ 1 ] = "true";
  595. currentOption.UIWidget = AseOptionsUIWidget.Toggle;
  596. }
  597. }
  598. else if( currentOption.Options.Length > 2 )
  599. {
  600. currentOption.UIWidget = AseOptionsUIWidget.Dropdown;
  601. }
  602. else
  603. {
  604. Debug.LogWarning( "Detected an option with less than two items:" + optionItems[ 1 ] );
  605. }
  606. optionItemsList.Add( currentOption );
  607. }
  608. break;
  609. case "Port":
  610. {
  611. //Fills previous option with its actions
  612. //actionItemsList is cleared over here
  613. FillOptionAction( currentOption, ref actionItemsList );
  614. optionItemToIndex.Clear();
  615. currentOption = new TemplateOptionsItem();
  616. currentOption.Type = AseOptionsType.Port;
  617. if( isSubShader && optionItems.Length > 2 )
  618. {
  619. currentOption.Id = optionItems[ 1 ];
  620. currentOption.Name = optionItems[ 2 ];
  621. }
  622. else
  623. {
  624. currentOption.Name = optionItems[ 1 ];
  625. }
  626. currentOption.Options = new string[] { "On", "Off" };
  627. optionItemToIndex.Add( currentOption.Options[ 0 ], 0 );
  628. optionItemToIndex.Add( currentOption.Options[ 1 ], 1 );
  629. actionItemsList.Add( new List<TemplateActionItem>() );
  630. actionItemsList.Add( new List<TemplateActionItem>() );
  631. optionItemsList.Add( currentOption );
  632. }
  633. break;
  634. case "Field":
  635. {
  636. //Fills previous option with its actions
  637. //actionItemsList is cleared over here
  638. FillOptionAction( currentOption, ref actionItemsList );
  639. optionItemToIndex.Clear();
  640. currentOption = new TemplateOptionsItem();
  641. currentOption.Type = AseOptionsType.Field;
  642. currentOption.Id = optionItems[ 1 ];
  643. currentOption.Name = optionItems[ 1 ];
  644. currentOption.UIWidget = AseOptionsUIWidget.Float;
  645. if( optionItems[ 2 ].Equals( "Int" ) )
  646. currentOption.UIWidget = AseOptionsUIWidget.Int;
  647. if( optionItems.Length >= 3 )
  648. {
  649. currentOption.DefaultFieldValue = Convert.ToSingle( optionItems[ 3 ], System.Globalization.CultureInfo.InvariantCulture );
  650. }
  651. if( optionItems.Length >= 6 )
  652. {
  653. if( currentOption.UIWidget == AseOptionsUIWidget.Int )
  654. currentOption.UIWidget = AseOptionsUIWidget.Int;
  655. else
  656. currentOption.UIWidget = AseOptionsUIWidget.FloatRange;
  657. currentOption.FieldMin = Convert.ToSingle( optionItems[ 4 ], System.Globalization.CultureInfo.InvariantCulture );
  658. currentOption.FieldMax = Convert.ToSingle( optionItems[ 5 ], System.Globalization.CultureInfo.InvariantCulture );
  659. }
  660. if( optionItems.Length == 5 || optionItems.Length == 7 )
  661. {
  662. currentOption.FieldInline = true;
  663. currentOption.FieldInlineName = optionItems[ optionItems.Length - 1 ];
  664. }
  665. currentOption.Options = new string[] { "Change", "Inline", "disable" };
  666. optionItemToIndex.Add( currentOption.Options[ 0 ], 0 );
  667. optionItemToIndex.Add( currentOption.Options[ 1 ], 1 );
  668. optionItemToIndex.Add( currentOption.Options[ 2 ], 2 );
  669. currentOption.DisableIdx = 2;
  670. actionItemsList.Add( new List<TemplateActionItem>() );
  671. actionItemsList.Add( new List<TemplateActionItem>() );
  672. actionItemsList.Add( new List<TemplateActionItem>() );
  673. optionItemsList.Add( currentOption );
  674. }
  675. break;
  676. default:
  677. {
  678. // @diogo: handle conditional action first
  679. const string IsConditionalPattern = @"^\s*(.+?)\s*\?\s*(.+?)\s*(=|!=)\s*(.+?)\s*$";
  680. TemplateActionItemConditional condition = null;
  681. Match isConditionalMatch = Regex.Match( optionItems[ 0 ], IsConditionalPattern );
  682. if ( isConditionalMatch.Success )
  683. {
  684. optionItems[ 0 ] = isConditionalMatch.Groups[ 1 ].Value;
  685. condition = new TemplateActionItemConditional(
  686. isConditionalMatch.Groups[ 3 ].Value,
  687. isConditionalMatch.Groups[ 2 ].Value,
  688. isConditionalMatch.Groups[ 4 ].Value );
  689. }
  690. if ( optionItemToIndex.ContainsKey( optionItems[ 0 ] ) )
  691. {
  692. int idx = 0;
  693. if( currentOption != null && currentOption.UIWidget == AseOptionsUIWidget.Toggle )
  694. {
  695. idx = ( optionItems[ 0 ].Equals( "true" ) ) ? 1 : 0;
  696. if( optionItems[ 0 ].Equals( "disable" ) )
  697. idx = 2;
  698. }
  699. else
  700. {
  701. idx = optionItemToIndex[ optionItems[ 0 ] ];
  702. }
  703. actionItemsList[ idx ].Add( CreateActionItem( isSubShader, optionItems, condition ) );
  704. }
  705. else
  706. {
  707. //string[] ids = optionItems[ 0 ].Split( ',' );
  708. if( itemIds.Length > 1 )
  709. {
  710. for( int i = 0; i < itemIds.Length; i++ )
  711. {
  712. if( optionItemToIndex.ContainsKey( itemIds[ i ] ) )
  713. {
  714. int idx = optionItemToIndex[ itemIds[ i ] ];
  715. actionItemsList[ idx ].Add( CreateActionItem( isSubShader, optionItems ) );
  716. }
  717. }
  718. }
  719. }
  720. }
  721. break;
  722. }
  723. }
  724. }
  725. //Fills last option with its actions
  726. FillOptionAction( currentOption, ref actionItemsList );
  727. actionItemsList.Clear();
  728. actionItemsList = null;
  729. optionsContainer.Options = optionItemsList.ToArray();
  730. optionItemsList.Clear();
  731. optionItemsList = null;
  732. optionItemToIndex.Clear();
  733. optionItemToIndex = null;
  734. }
  735. catch( Exception e )
  736. {
  737. Debug.LogException( e );
  738. }
  739. }
  740. return optionsContainer;
  741. }
  742. static void FillOptionAction( TemplateOptionsItem currentOption, ref List<List<TemplateActionItem>> actionItemsList )
  743. {
  744. if( currentOption != null )
  745. {
  746. int count = actionItemsList.Count;
  747. currentOption.ActionsPerOption = new TemplateActionItemGrid( count );
  748. for( int i = 0; i < count; i++ )
  749. {
  750. currentOption.ActionsPerOption[ i ] = actionItemsList[ i ].ToArray();
  751. actionItemsList[ i ].Clear();
  752. }
  753. actionItemsList.Clear();
  754. }
  755. }
  756. static TemplateActionItem CreateActionItem( bool isSubshader, string[] optionItems, TemplateActionItemConditional condition = null )
  757. {
  758. TemplateActionItem actionItem = new TemplateActionItem();
  759. try
  760. {
  761. actionItem.ActionConditional = condition;
  762. actionItem.ActionType = AseOptionsActionTypeDict[ optionItems[ 1 ] ];
  763. int optionsIdx = 2;
  764. if( optionItems.Length > 3 )
  765. {
  766. optionsIdx = 3;
  767. actionItem.PassName = optionItems[ 2 ];
  768. }
  769. else
  770. {
  771. actionItem.AllPasses = isSubshader;
  772. }
  773. actionItem.ActionData = optionItems[ optionsIdx ];
  774. switch( actionItem.ActionType )
  775. {
  776. case AseOptionsActionType.RefreshOption:
  777. {
  778. string[] arr = optionItems[ optionsIdx ].Split( OptionsDataSeparator );
  779. if ( arr.Length > 1 )
  780. {
  781. Debug.LogWarning( "RefreshOption should not have additional parameters other than Option name." );
  782. }
  783. actionItem.ActionData = arr[ 0 ];
  784. }
  785. break;
  786. case AseOptionsActionType.ShowOption:
  787. case AseOptionsActionType.HideOption:
  788. {
  789. string[] arr = optionItems[ optionsIdx ].Split( OptionsDataSeparator );
  790. if( arr.Length > 1 )
  791. {
  792. actionItem.ActionData = arr[ 0 ];
  793. if( !int.TryParse( arr[ 1 ], out actionItem.ActionDataIdx ) )
  794. {
  795. actionItem.ActionDataIdx = -1;
  796. }
  797. }
  798. }
  799. break;
  800. case AseOptionsActionType.SetOption:
  801. {
  802. string[] arr = optionItems[ optionsIdx ].Split( OptionsDataSeparator );
  803. if( arr.Length > 1 )
  804. {
  805. actionItem.ActionData = arr[ 0 ];
  806. if( !int.TryParse( arr[ 1 ], out actionItem.ActionDataIdx ) )
  807. {
  808. Debug.LogWarning( "SetOption value must be a the selection index" );
  809. }
  810. }
  811. }
  812. break;
  813. case AseOptionsActionType.HidePort:
  814. case AseOptionsActionType.ShowPort:
  815. {
  816. if( !int.TryParse( actionItem.ActionData, out actionItem.ActionDataIdx ) )
  817. actionItem.ActionDataIdx = -1;
  818. }
  819. break;
  820. case AseOptionsActionType.SetPortName:
  821. {
  822. string[] arr = optionItems[ optionsIdx ].Split( OptionsDataSeparator );
  823. if( arr.Length > 1 )
  824. {
  825. if ( !int.TryParse( arr[ 0 ], out actionItem.ActionDataIdx ) )
  826. actionItem.ActionDataIdx = -1;
  827. actionItem.ActionData = arr[ 0 ];
  828. actionItem.ActionData2 = arr[ 1 ];
  829. }
  830. }
  831. break;
  832. case AseOptionsActionType.SetDefine:
  833. case AseOptionsActionType.RemoveDefine:
  834. case AseOptionsActionType.SetUndefine:
  835. case AseOptionsActionType.RemoveUndefine:
  836. case AseOptionsActionType.ExcludePass:
  837. case AseOptionsActionType.IncludePass:
  838. case AseOptionsActionType.ExcludeAllPassesBut:
  839. break;
  840. case AseOptionsActionType.SetShaderProperty:
  841. {
  842. int optIndex = optionItems[ optionsIdx ].IndexOf( OptionsDataSeparator );
  843. if( optIndex > -1 )
  844. {
  845. actionItem.ActionData = optionItems[ optionsIdx ].Substring( 0, optIndex );
  846. actionItem.ActionBuffer = optionItems[ optionsIdx ].Substring( optIndex + 1, optionItems[ optionsIdx ].Length - optIndex - 1);
  847. }
  848. }break;
  849. case AseOptionsActionType.SetMaterialProperty:
  850. {
  851. int optIndex = optionItems[ optionsIdx ].IndexOf( OptionsDataSeparator );
  852. if( optIndex > -1 )
  853. {
  854. actionItem.ActionData = optionItems[ optionsIdx ].Substring( 0, optIndex );
  855. }
  856. }
  857. break;
  858. case AseOptionsActionType.SetPropertyOnPass:
  859. case AseOptionsActionType.SetPropertyOnSubShader:
  860. {
  861. string[] arr = optionItems[ optionsIdx ].Split( OptionsDataSeparator );
  862. actionItem.PropertyAction = (PropertyActionsEnum)Enum.Parse( typeof( PropertyActionsEnum ), arr[ 0 ] );
  863. if( arr.Length == 1 && actionItem.ActionType == AseOptionsActionType.SetPropertyOnPass )
  864. {
  865. actionItem.CopyFromSubShader = true;
  866. }
  867. else
  868. {
  869. switch( actionItem.PropertyAction )
  870. {
  871. case PropertyActionsEnum.CullMode:
  872. {
  873. if( arr.Length > 1 )
  874. actionItem.ActionCullMode = (CullMode)Enum.Parse( typeof( CullMode ), arr[ 1 ] );
  875. }
  876. break;
  877. case PropertyActionsEnum.ColorMask:
  878. {
  879. if( arr.Length > 4 )
  880. {
  881. actionItem.ColorMask.SetColorMask( 0, arr[ 1 ] );
  882. actionItem.ColorMask.SetColorMask( 1, arr[ 2 ] );
  883. actionItem.ColorMask.SetColorMask( 2, arr[ 3 ] );
  884. actionItem.ColorMask.SetColorMask( 3, arr[ 4 ] );
  885. }
  886. }
  887. break;
  888. case PropertyActionsEnum.ColorMask1:
  889. {
  890. if( arr.Length > 4 )
  891. {
  892. actionItem.ColorMask1.SetColorMask( 0, arr[ 1 ] );
  893. actionItem.ColorMask1.SetColorMask( 1, arr[ 2 ] );
  894. actionItem.ColorMask1.SetColorMask( 2, arr[ 3 ] );
  895. actionItem.ColorMask1.SetColorMask( 3, arr[ 4 ] );
  896. }
  897. }
  898. break;
  899. case PropertyActionsEnum.ColorMask2:
  900. {
  901. if( arr.Length > 4 )
  902. {
  903. actionItem.ColorMask2.SetColorMask( 0, arr[ 1 ] );
  904. actionItem.ColorMask2.SetColorMask( 1, arr[ 2 ] );
  905. actionItem.ColorMask2.SetColorMask( 2, arr[ 3 ] );
  906. actionItem.ColorMask2.SetColorMask( 3, arr[ 4 ] );
  907. }
  908. }
  909. break;
  910. case PropertyActionsEnum.ColorMask3:
  911. {
  912. if( arr.Length > 4 )
  913. {
  914. actionItem.ColorMask3.SetColorMask( 0, arr[ 1 ] );
  915. actionItem.ColorMask3.SetColorMask( 1, arr[ 2 ] );
  916. actionItem.ColorMask3.SetColorMask( 2, arr[ 3 ] );
  917. actionItem.ColorMask3.SetColorMask( 3, arr[ 4 ] );
  918. }
  919. }
  920. break;
  921. case PropertyActionsEnum.ZWrite:
  922. {
  923. if( arr.Length > 1 )
  924. actionItem.ActionZWrite = (ZWriteMode)Enum.Parse( typeof( ZWriteMode ), arr[ 1 ] );
  925. }
  926. break;
  927. case PropertyActionsEnum.ZTest:
  928. {
  929. if( arr.Length > 1 )
  930. actionItem.ActionZTest = (ZTestMode)Enum.Parse( typeof( ZTestMode ), arr[ 1 ] );
  931. }
  932. break;
  933. case PropertyActionsEnum.ZOffsetFactor:
  934. {
  935. if( arr.Length > 1 )
  936. actionItem.ActionZOffsetFactor = Convert.ToSingle( arr[ 1 ] );
  937. }
  938. break;
  939. case PropertyActionsEnum.ZOffsetUnits:
  940. {
  941. if( arr.Length > 1 )
  942. actionItem.ActionZOffsetUnits = Convert.ToSingle( arr[ 1 ] );
  943. }
  944. break;
  945. case PropertyActionsEnum.BlendRGB:
  946. {
  947. if( arr.Length > 2 )
  948. {
  949. actionItem.ActionBlendRGBSource = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 1 ] );
  950. actionItem.ActionBlendRGBDest = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 2 ] );
  951. }
  952. }
  953. break;
  954. case PropertyActionsEnum.BlendRGB1:
  955. {
  956. if( arr.Length > 2 )
  957. {
  958. actionItem.ActionBlendRGBSource1 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 1 ] );
  959. actionItem.ActionBlendRGBDest1 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 2 ] );
  960. }
  961. }
  962. break;
  963. case PropertyActionsEnum.BlendRGB2:
  964. {
  965. if( arr.Length > 2 )
  966. {
  967. actionItem.ActionBlendRGBSource2 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 1 ] );
  968. actionItem.ActionBlendRGBDest2 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 2 ] );
  969. }
  970. }
  971. break;
  972. case PropertyActionsEnum.BlendRGB3:
  973. {
  974. if( arr.Length > 2 )
  975. {
  976. actionItem.ActionBlendRGBSource3 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 1 ] );
  977. actionItem.ActionBlendRGBDest3 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 2 ] );
  978. }
  979. }
  980. break;
  981. case PropertyActionsEnum.BlendAlpha:
  982. {
  983. if( arr.Length > 2 )
  984. {
  985. actionItem.ActionBlendAlphaSource = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 1 ] );
  986. actionItem.ActionBlendAlphaDest = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 2 ] );
  987. }
  988. }
  989. break;
  990. case PropertyActionsEnum.BlendAlpha1:
  991. {
  992. if( arr.Length > 2 )
  993. {
  994. actionItem.ActionBlendAlphaSource1 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 1 ] );
  995. actionItem.ActionBlendAlphaDest1 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 2 ] );
  996. }
  997. }
  998. break;
  999. case PropertyActionsEnum.BlendAlpha2:
  1000. {
  1001. if( arr.Length > 2 )
  1002. {
  1003. actionItem.ActionBlendAlphaSource2 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 1 ] );
  1004. actionItem.ActionBlendAlphaDest2 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 2 ] );
  1005. }
  1006. }
  1007. break;
  1008. case PropertyActionsEnum.BlendAlpha3:
  1009. {
  1010. if( arr.Length > 2 )
  1011. {
  1012. actionItem.ActionBlendAlphaSource3 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 1 ] );
  1013. actionItem.ActionBlendAlphaDest3 = (AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), arr[ 2 ] );
  1014. }
  1015. }
  1016. break;
  1017. case PropertyActionsEnum.BlendOpRGB:
  1018. {
  1019. if( arr.Length > 1 )
  1020. {
  1021. actionItem.ActionBlendOpRGB = (AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), arr[ 1 ] );
  1022. }
  1023. }
  1024. break;
  1025. case PropertyActionsEnum.BlendOpAlpha:
  1026. {
  1027. if( arr.Length > 1 )
  1028. {
  1029. actionItem.ActionBlendOpAlpha = (AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), arr[ 1 ] );
  1030. }
  1031. }
  1032. break;
  1033. case PropertyActionsEnum.StencilReference:
  1034. {
  1035. if( arr.Length > 1 )
  1036. {
  1037. int.TryParse( arr[ 1 ], out actionItem.ActionStencilReference );
  1038. }
  1039. }
  1040. break;
  1041. case PropertyActionsEnum.StencilReadMask:
  1042. {
  1043. if( arr.Length > 1 )
  1044. {
  1045. int.TryParse( arr[ 1 ], out actionItem.ActionStencilReadMask );
  1046. }
  1047. }
  1048. break;
  1049. case PropertyActionsEnum.StencilWriteMask:
  1050. {
  1051. if( arr.Length > 1 )
  1052. {
  1053. int.TryParse( arr[ 1 ], out actionItem.ActionStencilWriteMask );
  1054. }
  1055. }
  1056. break;
  1057. case PropertyActionsEnum.StencilComparison:
  1058. {
  1059. if( arr.Length > 1 )
  1060. actionItem.ActionStencilComparison = StencilBufferOpHelper.StencilComparisonValuesDict[ arr[ 1 ] ];
  1061. }
  1062. break;
  1063. case PropertyActionsEnum.StencilPass:
  1064. {
  1065. if( arr.Length > 1 )
  1066. actionItem.ActionStencilPass = StencilBufferOpHelper.StencilOpsValuesDict[ arr[ 1 ] ];
  1067. }
  1068. break;
  1069. case PropertyActionsEnum.StencilFail:
  1070. {
  1071. if( arr.Length > 1 )
  1072. actionItem.ActionStencilFail = StencilBufferOpHelper.StencilOpsValuesDict[ arr[ 1 ] ];
  1073. }
  1074. break;
  1075. case PropertyActionsEnum.StencilZFail:
  1076. {
  1077. if( arr.Length > 1 )
  1078. actionItem.ActionStencilZFail = StencilBufferOpHelper.StencilOpsValuesDict[ arr[ 1 ] ];
  1079. }
  1080. break;
  1081. case PropertyActionsEnum.RenderType:
  1082. {
  1083. if( arr.Length > 1 )
  1084. actionItem.ActionData = arr[ 1 ];
  1085. }
  1086. break;
  1087. case PropertyActionsEnum.RenderQueue:
  1088. {
  1089. if( arr.Length > 1 )
  1090. actionItem.ActionData = arr[ 1 ];
  1091. if( arr.Length > 2 )
  1092. {
  1093. int.TryParse( arr[ 2 ], out actionItem.ActionDataIdx );
  1094. }
  1095. else
  1096. {
  1097. actionItem.ActionDataIdx = 0;
  1098. }
  1099. }
  1100. break;
  1101. case PropertyActionsEnum.DisableBatching:
  1102. {
  1103. if( arr.Length > 1 )
  1104. actionItem.ActionData = arr[ 1 ];
  1105. }
  1106. break;
  1107. case PropertyActionsEnum.ChangeTagValue:
  1108. {
  1109. if( arr.Length > 2 )
  1110. {
  1111. //Tag Name
  1112. actionItem.ActionData = arr[ 1 ];
  1113. //Tag Value
  1114. actionItem.ActionBuffer = arr[ 2 ];
  1115. }
  1116. }
  1117. break;
  1118. }
  1119. }
  1120. }
  1121. break;
  1122. }
  1123. }
  1124. catch( Exception e )
  1125. {
  1126. Debug.LogException( e );
  1127. }
  1128. return actionItem;
  1129. }
  1130. }
  1131. }