CubismRenderer.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916
  1. /**
  2. * Copyright(c) Live2D Inc. All rights reserved.
  3. *
  4. * Use of this source code is governed by the Live2D Open Software license
  5. * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
  6. */
  7. using Live2D.Cubism.Core;
  8. using Live2D.Cubism.Rendering.Masking;
  9. using System;
  10. using UnityEngine;
  11. using UnityEngine.Rendering;
  12. namespace Live2D.Cubism.Rendering
  13. {
  14. /// <summary>
  15. /// Wrapper for drawing <see cref="CubismDrawable"/>s.
  16. /// </summary>
  17. [ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
  18. public sealed class CubismRenderer : MonoBehaviour
  19. {
  20. /// <summary>
  21. /// <see cref="LocalSortingOrder"/> backing field.
  22. /// </summary>
  23. [SerializeField, HideInInspector]
  24. private int _localSortingOrder;
  25. /// <summary>
  26. /// Local sorting order.
  27. /// </summary>
  28. public int LocalSortingOrder
  29. {
  30. get
  31. {
  32. return _localSortingOrder;
  33. }
  34. set
  35. {
  36. // Return early if same value given.
  37. if (value == _localSortingOrder)
  38. {
  39. return;
  40. }
  41. // Store value.
  42. _localSortingOrder = value;
  43. // Apply it.
  44. ApplySorting();
  45. }
  46. }
  47. /// <summary>
  48. /// <see cref="Color"/> backing field.
  49. /// </summary>
  50. [SerializeField, HideInInspector]
  51. private Color _color = Color.white;
  52. /// <summary>
  53. /// Color.
  54. /// </summary>
  55. public Color Color
  56. {
  57. get { return _color; }
  58. set
  59. {
  60. // Return early if same value given.
  61. if (value == _color)
  62. {
  63. return;
  64. }
  65. // Store value.
  66. _color = value;
  67. // Apply color.
  68. ApplyVertexColors();
  69. }
  70. }
  71. /// <summary>
  72. /// <see cref="UnityEngine.Material"/>.
  73. /// </summary>
  74. public Material Material
  75. {
  76. get
  77. {
  78. #if UNITY_EDITOR
  79. if (!Application.isPlaying)
  80. {
  81. return MeshRenderer.sharedMaterial;
  82. }
  83. #endif
  84. return MeshRenderer.material;
  85. }
  86. set
  87. {
  88. #if UNITY_EDITOR
  89. if (!Application.isPlaying)
  90. {
  91. MeshRenderer.sharedMaterial = value;
  92. return;
  93. }
  94. #endif
  95. MeshRenderer.material = value;
  96. }
  97. }
  98. /// <summary>
  99. /// <see cref="MainTexture"/> backing field.
  100. /// </summary>
  101. [SerializeField, HideInInspector]
  102. private Texture2D _mainTexture;
  103. /// <summary>
  104. /// <see cref="MeshRenderer"/>'s main texture.
  105. /// </summary>
  106. public Texture2D MainTexture
  107. {
  108. get { return _mainTexture; }
  109. set
  110. {
  111. // Return early if same value given and main texture is valid.
  112. if (value == _mainTexture && _mainTexture != null)
  113. {
  114. return;
  115. }
  116. // Store value.
  117. _mainTexture = (value != null)
  118. ? value
  119. : Texture2D.whiteTexture;
  120. // Apply it.
  121. ApplyMainTexture();
  122. }
  123. }
  124. /// <summary>
  125. /// Meshes.
  126. /// </summary>
  127. /// <remarks>
  128. /// Double buffering dynamic meshes increases performance on mobile, so we double-buffer them here.
  129. /// </remarks>
  130. private Mesh[] Meshes { get; set; }
  131. /// <summary>
  132. /// Index of front buffer mesh.
  133. /// </summary>
  134. private int FrontMesh { get; set; }
  135. /// <summary>
  136. /// Index of back buffer mesh..
  137. /// </summary>
  138. private int BackMesh { get; set; }
  139. /// <summary>
  140. /// <see cref="UnityEngine.Mesh"/>.
  141. /// </summary>
  142. public Mesh Mesh
  143. {
  144. get { return Meshes[FrontMesh]; }
  145. }
  146. /// <summary>
  147. /// <see cref="MeshFilter"/> backing field.
  148. /// </summary>
  149. [NonSerialized]
  150. private MeshFilter _meshFilter;
  151. /// <summary>
  152. /// <see cref="UnityEngine.MeshFilter"/>.
  153. /// </summary>
  154. public MeshFilter MeshFilter
  155. {
  156. get
  157. {
  158. return _meshFilter;
  159. }
  160. }
  161. /// <summary>
  162. /// <see cref="MeshRenderer"/> backing field.
  163. /// </summary>
  164. [NonSerialized]
  165. private MeshRenderer _meshRenderer;
  166. /// <summary>
  167. /// <see cref="UnityEngine.MeshRenderer"/>.
  168. /// </summary>
  169. public MeshRenderer MeshRenderer
  170. {
  171. get
  172. {
  173. return _meshRenderer;
  174. }
  175. }
  176. #region Interface For CubismRenderController
  177. /// <summary>
  178. /// <see cref="SortingMode"/> backing field.
  179. /// </summary>
  180. [SerializeField, HideInInspector]
  181. private CubismSortingMode _sortingMode;
  182. /// <summary>
  183. /// Sorting mode.
  184. /// </summary>
  185. private CubismSortingMode SortingMode
  186. {
  187. get { return _sortingMode; }
  188. set { _sortingMode = value; }
  189. }
  190. /// <summary>
  191. /// <see cref="SortingOrder"/> backing field.
  192. /// </summary>
  193. [SerializeField, HideInInspector]
  194. private int _sortingOrder;
  195. /// <summary>
  196. /// Sorting mode.
  197. /// </summary>
  198. private int SortingOrder
  199. {
  200. get { return _sortingOrder; }
  201. set { _sortingOrder = value; }
  202. }
  203. /// <summary>
  204. /// <see cref="RenderOrder"/> backing field.
  205. /// </summary>
  206. [SerializeField, HideInInspector]
  207. private int _renderOrder;
  208. /// <summary>
  209. /// Sorting mode.
  210. /// </summary>
  211. private int RenderOrder
  212. {
  213. get { return _renderOrder; }
  214. set { _renderOrder = value; }
  215. }
  216. /// <summary>
  217. /// <see cref="DepthOffset"/> backing field.
  218. /// </summary>
  219. [SerializeField, HideInInspector]
  220. private float _depthOffset = 0.00001f;
  221. /// <summary>
  222. /// Offset to apply in case of depth sorting.
  223. /// </summary>
  224. private float DepthOffset
  225. {
  226. get { return _depthOffset; }
  227. set { _depthOffset = value; }
  228. }
  229. /// <summary>
  230. /// <see cref="Opacity"/> backing field.
  231. /// </summary>
  232. [SerializeField, HideInInspector]
  233. private float _opacity;
  234. /// <summary>
  235. /// Opacity.
  236. /// </summary>
  237. private float Opacity
  238. {
  239. get { return _opacity; }
  240. set { _opacity = value; }
  241. }
  242. /// <summary>
  243. /// Buffer for vertex colors.
  244. /// </summary>
  245. private Color[] VertexColors { get; set; }
  246. /// <summary>
  247. /// Allows tracking of what vertex data was updated last swap.
  248. /// </summary>
  249. private SwapInfo LastSwap { get; set; }
  250. /// <summary>
  251. /// Allows tracking of what vertex data will be swapped.
  252. /// </summary>
  253. private SwapInfo ThisSwap { get; set; }
  254. /// <summary>
  255. /// Swaps mesh buffers.
  256. /// </summary>
  257. /// <remarks>
  258. /// Make sure to manually call this method in case you changed the <see cref="Color"/>.
  259. /// </remarks>
  260. public void SwapMeshes()
  261. {
  262. // Perform internal swap.
  263. BackMesh = FrontMesh;
  264. FrontMesh = (FrontMesh == 0) ? 1 : 0;
  265. var mesh = Meshes[FrontMesh];
  266. // Update colors.
  267. Meshes[BackMesh].colors = VertexColors;
  268. // Update swap info.
  269. LastSwap = ThisSwap;
  270. ResetSwapInfoFlags();
  271. // Apply swap.
  272. #if UNITY_EDITOR
  273. if (!Application.isPlaying)
  274. {
  275. MeshFilter.mesh = mesh;
  276. return;
  277. }
  278. #endif
  279. MeshFilter.mesh = mesh;
  280. }
  281. /// <summary>
  282. /// Updates visibility.
  283. /// </summary>
  284. public void UpdateVisibility()
  285. {
  286. if (LastSwap.DidBecomeVisible)
  287. {
  288. MeshRenderer.enabled = true;
  289. }
  290. else if (LastSwap.DidBecomeInvisible)
  291. {
  292. MeshRenderer.enabled = false;
  293. }
  294. ResetVisibilityFlags();
  295. }
  296. /// <summary>
  297. /// Updates render order.
  298. /// </summary>
  299. public void UpdateRenderOrder()
  300. {
  301. if (LastSwap.NewRenderOrder)
  302. {
  303. ApplySorting();
  304. }
  305. ResetRenderOrderFlag();
  306. }
  307. /// <summary>
  308. /// Updates sorting layer.
  309. /// </summary>
  310. /// <param name="newSortingLayer">New sorting layer.</param>
  311. internal void OnControllerSortingLayerDidChange(int newSortingLayer)
  312. {
  313. MeshRenderer.sortingLayerID = newSortingLayer;
  314. }
  315. /// <summary>
  316. /// Updates sorting mode.
  317. /// </summary>
  318. /// <param name="newSortingMode">New sorting mode.</param>
  319. internal void OnControllerSortingModeDidChange(CubismSortingMode newSortingMode)
  320. {
  321. SortingMode = newSortingMode;
  322. ApplySorting();
  323. }
  324. /// <summary>
  325. /// Updates sorting order.
  326. /// </summary>
  327. /// <param name="newSortingOrder">New sorting order.</param>
  328. internal void OnControllerSortingOrderDidChange(int newSortingOrder)
  329. {
  330. SortingOrder = newSortingOrder;
  331. ApplySorting();
  332. }
  333. /// <summary>
  334. /// Updates depth offset.
  335. /// </summary>
  336. /// <param name="newDepthOffset"></param>
  337. internal void OnControllerDepthOffsetDidChange(float newDepthOffset)
  338. {
  339. DepthOffset = newDepthOffset;
  340. ApplySorting();
  341. }
  342. /// <summary>
  343. /// Sets the opacity.
  344. /// </summary>
  345. /// <param name="newOpacity">New opacity.</param>
  346. internal void OnDrawableOpacityDidChange(float newOpacity)
  347. {
  348. Opacity = newOpacity;
  349. ApplyVertexColors();
  350. }
  351. /// <summary>
  352. /// Updates render order.
  353. /// </summary>
  354. /// <param name="newRenderOrder">New render order.</param>
  355. internal void OnDrawableRenderOrderDidChange(int newRenderOrder)
  356. {
  357. RenderOrder = newRenderOrder;
  358. SetNewRenderOrder();
  359. }
  360. /// <summary>
  361. /// Sets the <see cref="UnityEngine.Mesh.vertices"/>.
  362. /// </summary>
  363. /// <param name="newVertexPositions">Vertex positions to set.</param>
  364. internal void OnDrawableVertexPositionsDidChange(Vector3[] newVertexPositions)
  365. {
  366. var mesh = Mesh;
  367. // Apply positions and update bounds.
  368. mesh.vertices = newVertexPositions;
  369. mesh.RecalculateBounds();
  370. // Set swap flag.
  371. SetNewVertexPositions();
  372. }
  373. /// <summary>
  374. /// Sets visibility.
  375. /// </summary>
  376. /// <param name="newVisibility">New visibility.</param>
  377. internal void OnDrawableVisiblityDidChange(bool newVisibility)
  378. {
  379. // Set swap flag if visible.
  380. if (newVisibility)
  381. {
  382. BecomeVisible();
  383. }
  384. else
  385. {
  386. BecomeInvisible();
  387. }
  388. }
  389. /// <summary>
  390. /// Sets mask properties.
  391. /// </summary>
  392. /// <param name="newMaskProperties">Value to set.</param>
  393. internal void OnMaskPropertiesDidChange(CubismMaskProperties newMaskProperties)
  394. {
  395. MeshRenderer.GetPropertyBlock(SharedPropertyBlock);
  396. // Write properties.
  397. SharedPropertyBlock.SetTexture(CubismShaderVariables.MaskTexture, newMaskProperties.Texture);
  398. SharedPropertyBlock.SetVector(CubismShaderVariables.MaskTile, newMaskProperties.Tile);
  399. SharedPropertyBlock.SetVector(CubismShaderVariables.MaskTransform, newMaskProperties.Transform);
  400. MeshRenderer.SetPropertyBlock(SharedPropertyBlock);
  401. }
  402. /// <summary>
  403. /// Sets model opacity.
  404. /// </summary>
  405. /// <param name="newModelOpacity">Opacity to set.</param>
  406. internal void OnModelOpacityDidChange(float newModelOpacity)
  407. {
  408. _meshRenderer.GetPropertyBlock(SharedPropertyBlock);
  409. // Write property.
  410. SharedPropertyBlock.SetFloat(CubismShaderVariables.ModelOpacity, newModelOpacity);
  411. MeshRenderer.SetPropertyBlock(SharedPropertyBlock);
  412. }
  413. #endregion
  414. /// <summary>
  415. /// <see cref="SharedPropertyBlock"/> backing field.
  416. /// </summary>
  417. private static MaterialPropertyBlock _sharedPropertyBlock;
  418. /// <summary>
  419. /// <see cref="MaterialPropertyBlock"/> that can be shared on the main script thread.
  420. /// </summary>
  421. private static MaterialPropertyBlock SharedPropertyBlock
  422. {
  423. get
  424. {
  425. // Lazily initialize.
  426. if (_sharedPropertyBlock == null)
  427. {
  428. _sharedPropertyBlock = new MaterialPropertyBlock();
  429. }
  430. return _sharedPropertyBlock;
  431. }
  432. }
  433. /// <summary>
  434. /// Applies main texture for rendering.
  435. /// </summary>
  436. private void ApplyMainTexture()
  437. {
  438. MeshRenderer.GetPropertyBlock(SharedPropertyBlock);
  439. // Write property.
  440. SharedPropertyBlock.SetTexture(CubismShaderVariables.MainTexture, MainTexture);
  441. MeshRenderer.SetPropertyBlock(SharedPropertyBlock);
  442. }
  443. /// <summary>
  444. /// Applies sorting.
  445. /// </summary>
  446. private void ApplySorting()
  447. {
  448. // Sort by order.
  449. if (SortingMode.SortByOrder())
  450. {
  451. MeshRenderer.sortingOrder = SortingOrder + ((SortingMode == CubismSortingMode.BackToFrontOrder)
  452. ? (RenderOrder + LocalSortingOrder)
  453. : -(RenderOrder + LocalSortingOrder));
  454. transform.localPosition = Vector3.zero;
  455. return;
  456. }
  457. // Sort by depth.
  458. var offset = (SortingMode == CubismSortingMode.BackToFrontZ)
  459. ? -DepthOffset
  460. : DepthOffset;
  461. MeshRenderer.sortingOrder = SortingOrder + LocalSortingOrder;
  462. transform.localPosition = new Vector3(0f, 0f, RenderOrder * offset);
  463. }
  464. /// <summary>
  465. /// Uploads mesh vertex colors.
  466. /// </summary>
  467. public void ApplyVertexColors()
  468. {
  469. var vertexColors = VertexColors;
  470. var color = Color;
  471. color.a *= Opacity;
  472. for (var i = 0; i < vertexColors.Length; ++i)
  473. {
  474. vertexColors[i] = color;
  475. }
  476. // Set swap flag.
  477. SetNewVertexColors();
  478. }
  479. /// <summary>
  480. /// Initializes the mesh renderer.
  481. /// </summary>
  482. private void TryInitializeMeshRenderer()
  483. {
  484. if (_meshRenderer == null)
  485. {
  486. _meshRenderer = GetComponent<MeshRenderer>();
  487. // Lazily add component.
  488. if (_meshRenderer == null)
  489. {
  490. _meshRenderer = gameObject.AddComponent<MeshRenderer>();
  491. _meshRenderer.hideFlags = HideFlags.HideInInspector;
  492. _meshRenderer.receiveShadows = false;
  493. _meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
  494. _meshRenderer.lightProbeUsage = LightProbeUsage.BlendProbes;
  495. }
  496. }
  497. }
  498. /// <summary>
  499. /// Initializes the mesh filter.
  500. /// </summary>
  501. private void TryInitializeMeshFilter()
  502. {
  503. if (_meshFilter == null)
  504. {
  505. _meshFilter = GetComponent<MeshFilter>();
  506. // Lazily add component.
  507. if (_meshFilter == null)
  508. {
  509. _meshFilter = gameObject.AddComponent<MeshFilter>();
  510. _meshFilter.hideFlags = HideFlags.HideInInspector;
  511. }
  512. }
  513. }
  514. /// <summary>
  515. /// Initializes the mesh if necessary.
  516. /// </summary>
  517. private void TryInitializeMesh()
  518. {
  519. // Only create mesh if necessary.
  520. // HACK 'Mesh.vertex > 0' makes sure mesh is recreated in case of runtime instantiation.
  521. if (Meshes != null && Mesh.vertexCount > 0)
  522. {
  523. return;
  524. }
  525. // Create mesh for attached drawable.
  526. var drawable = GetComponent<CubismDrawable>();
  527. if (Meshes == null)
  528. {
  529. Meshes = new Mesh[2];
  530. }
  531. for (var i = 0; i < 2; ++i)
  532. {
  533. var mesh = new Mesh
  534. {
  535. name = drawable.name,
  536. vertices = drawable.VertexPositions,
  537. uv = drawable.VertexUvs,
  538. triangles = drawable.Indices
  539. };
  540. mesh.MarkDynamic();
  541. mesh.RecalculateBounds();
  542. // Store mesh.
  543. Meshes[i] = mesh;
  544. }
  545. }
  546. /// <summary>
  547. /// Initializes vertex colors.
  548. /// </summary>
  549. private void TryInitializeVertexColor()
  550. {
  551. var mesh = Mesh;
  552. VertexColors = new Color[mesh.vertexCount];
  553. for (var i = 0; i < VertexColors.Length; ++i)
  554. {
  555. VertexColors[i] = Color;
  556. VertexColors[i].a *= Opacity;
  557. }
  558. }
  559. /// <summary>
  560. /// Initializes the main texture if possible.
  561. /// </summary>
  562. private void TryInitializeMainTexture()
  563. {
  564. if (MainTexture == null)
  565. {
  566. MainTexture = null;
  567. }
  568. ApplyMainTexture();
  569. }
  570. /// <summary>
  571. /// Initializes components if possible.
  572. /// </summary>
  573. public void TryInitialize()
  574. {
  575. TryInitializeMeshRenderer();
  576. TryInitializeMeshFilter();
  577. TryInitializeMesh();
  578. TryInitializeVertexColor();
  579. TryInitializeMainTexture();
  580. ApplySorting();
  581. }
  582. #region Swap Info
  583. /// <summary>
  584. /// Sets <see cref="NewVertexPositions"/>.
  585. /// </summary>
  586. private void SetNewVertexPositions()
  587. {
  588. var swapInfo = ThisSwap;
  589. swapInfo.NewVertexPositions = true;
  590. ThisSwap = swapInfo;
  591. }
  592. /// <summary>
  593. /// Sets <see cref="NewVertexColors"/>.
  594. /// </summary>
  595. private void SetNewVertexColors()
  596. {
  597. var swapInfo = ThisSwap;
  598. swapInfo.NewVertexColors = true;
  599. ThisSwap = swapInfo;
  600. }
  601. /// <summary>
  602. /// Sets <see cref="DidBecomeVisible"/> on visible.
  603. /// </summary>
  604. private void BecomeVisible()
  605. {
  606. var swapInfo = ThisSwap;
  607. swapInfo.DidBecomeVisible = true;
  608. ThisSwap = swapInfo;
  609. }
  610. /// <summary>
  611. /// Sets <see cref="DidBecomeInvisible"/> on invisible.
  612. /// </summary>
  613. private void BecomeInvisible()
  614. {
  615. var swapInfo = ThisSwap;
  616. swapInfo.DidBecomeInvisible = true;
  617. ThisSwap = swapInfo;
  618. }
  619. /// <summary>
  620. /// Sets <see cref="SetNewRenderOrder"/>.
  621. /// </summary>
  622. private void SetNewRenderOrder()
  623. {
  624. var swapInfo = ThisSwap;
  625. swapInfo.NewRenderOrder = true;
  626. ThisSwap = swapInfo;
  627. }
  628. /// <summary>
  629. /// Resets flags.
  630. /// </summary>
  631. private void ResetSwapInfoFlags()
  632. {
  633. var swapInfo = ThisSwap;
  634. swapInfo.NewVertexColors = false;
  635. swapInfo.NewVertexPositions = false;
  636. swapInfo.DidBecomeVisible = false;
  637. swapInfo.DidBecomeInvisible = false;
  638. ThisSwap = swapInfo;
  639. }
  640. /// <summary>
  641. /// Reset visibility flags.
  642. /// </summary>
  643. private void ResetVisibilityFlags()
  644. {
  645. var swapInfo = LastSwap;
  646. swapInfo.DidBecomeVisible = false;
  647. swapInfo.DidBecomeInvisible = false;
  648. LastSwap = swapInfo;
  649. }
  650. /// <summary>
  651. /// Reset render order flag.
  652. /// </summary>
  653. private void ResetRenderOrderFlag()
  654. {
  655. var swapInfo = LastSwap;
  656. swapInfo.NewRenderOrder = false;
  657. LastSwap = swapInfo;
  658. }
  659. /// <summary>
  660. /// Allows tracking of <see cref="Mesh"/> data changed on a swap.
  661. /// </summary>
  662. private struct SwapInfo
  663. {
  664. /// <summary>
  665. /// Vertex positions were changed.
  666. /// </summary>
  667. public bool NewVertexPositions { get; set; }
  668. /// <summary>
  669. /// Vertex colors were changed.
  670. /// </summary>
  671. public bool NewVertexColors { get; set; }
  672. /// <summary>
  673. /// Visibility were changed to visible.
  674. /// </summary>
  675. public bool DidBecomeVisible { get; set; }
  676. /// <summary>
  677. /// Visibility were changed to invisible.
  678. /// </summary>
  679. public bool DidBecomeInvisible { get; set; }
  680. /// <summary>
  681. /// Render order were changed.
  682. /// </summary>
  683. public bool NewRenderOrder { get; set; }
  684. }
  685. #endregion
  686. #region Unity Events Handling
  687. /// <summary>
  688. /// Finalizes instance.
  689. /// </summary>
  690. private void OnDestroy()
  691. {
  692. if (Meshes == null)
  693. {
  694. return;
  695. }
  696. for (var i = 0; i < Meshes.Length; i++)
  697. {
  698. DestroyImmediate(Meshes[i]);
  699. }
  700. }
  701. #endregion
  702. }
  703. }