UIParticle.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.CompilerServices;
  4. using Coffee.UIParticleInternal;
  5. using UnityEngine;
  6. using UnityEngine.Rendering;
  7. using UnityEngine.Serialization;
  8. using UnityEngine.UI;
  9. using Random = UnityEngine.Random;
  10. [assembly: InternalsVisibleTo("Coffee.UIParticle.Editor")]
  11. [assembly: InternalsVisibleTo("Coffee.UIParticle.PerformanceDemo")]
  12. [assembly: InternalsVisibleTo("Coffee.UIParticle.Demo")]
  13. namespace Coffee.UIExtensions
  14. {
  15. /// <summary>
  16. /// Render maskable and sortable particle effect ,without Camera, RenderTexture or Canvas.
  17. /// </summary>
  18. [Icon("Packages/cn.etetet.yiuieffect/Editor/UIParticleEditor/UIParticleIcon.png")]
  19. [ExecuteAlways]
  20. [RequireComponent(typeof(RectTransform))]
  21. [RequireComponent(typeof(CanvasRenderer))]
  22. public class UIParticle : MaskableGraphic, ISerializationCallbackReceiver
  23. {
  24. public enum AutoScalingMode
  25. {
  26. None,
  27. UIParticle,
  28. Transform
  29. }
  30. public enum MeshSharing
  31. {
  32. None,
  33. Auto,
  34. Primary,
  35. PrimarySimulator,
  36. Replica
  37. }
  38. public enum PositionMode
  39. {
  40. Relative,
  41. Absolute
  42. }
  43. [HideInInspector]
  44. [SerializeField]
  45. [Obsolete]
  46. internal bool m_IsTrail;
  47. [HideInInspector]
  48. [FormerlySerializedAs("m_IgnoreParent")]
  49. [SerializeField]
  50. [Obsolete]
  51. private bool m_IgnoreCanvasScaler;
  52. [HideInInspector]
  53. [SerializeField]
  54. [Obsolete]
  55. internal bool m_AbsoluteMode;
  56. [Tooltip("Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported.")]
  57. [SerializeField]
  58. private Vector3 m_Scale3D = new Vector3(10, 10, 10);
  59. [Tooltip("If you want to update material properties (e.g. _MainTex_ST, _Color) in AnimationClip, " +
  60. "use this to mark as animatable.")]
  61. [SerializeField]
  62. internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
  63. [Tooltip("Particles")]
  64. [SerializeField]
  65. private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
  66. [Tooltip("Particle simulation results are shared within the same group. " +
  67. "A large number of the same effects can be displayed with a small load.\n" +
  68. "None: Disable mesh sharing.\n" +
  69. "Auto: Automatically select Primary/Replica.\n" +
  70. "Primary: Provides particle simulation results to the same group.\n" +
  71. "Primary Simulator: Primary, but do not render the particle (simulation only).\n" +
  72. "Replica: Render simulation results provided by the primary.")]
  73. [SerializeField]
  74. private MeshSharing m_MeshSharing = MeshSharing.None;
  75. [Tooltip("Mesh sharing group ID.\n" +
  76. "If non-zero is specified, particle simulation results are shared within the group.")]
  77. [SerializeField]
  78. private int m_GroupId;
  79. [SerializeField]
  80. private int m_GroupMaxId;
  81. [Tooltip("Emission position mode.\n" +
  82. "Relative: The particles will be emitted from the scaled position.\n" +
  83. "Absolute: The particles will be emitted from the world position.")]
  84. [SerializeField]
  85. private PositionMode m_PositionMode = PositionMode.Relative;
  86. [SerializeField]
  87. [Obsolete]
  88. internal bool m_AutoScaling;
  89. [SerializeField]
  90. [Tooltip(
  91. "How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.\n" +
  92. "None: Do nothing.\n" +
  93. "Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).\n" +
  94. "UIParticle: UIParticle.scale will be adjusted.")]
  95. private AutoScalingMode m_AutoScalingMode = AutoScalingMode.Transform;
  96. [SerializeField]
  97. [Tooltip("Use a custom view.\n" +
  98. "Use this if the particles are not displayed correctly due to min/max particle size.")]
  99. private bool m_UseCustomView;
  100. [SerializeField]
  101. [Tooltip("Custom view size.\n" +
  102. "Change the bake view size.")]
  103. private float m_CustomViewSize = 10;
  104. [SerializeField]
  105. [Tooltip("Time scale multiplier.")]
  106. private float m_TimeScaleMultiplier = 1;
  107. private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
  108. private Camera _bakeCamera;
  109. private int _groupId;
  110. private bool _isScaleStored;
  111. private Vector3 _storedScale;
  112. private DrivenRectTransformTracker _tracker;
  113. /// <summary>
  114. /// Should this graphic be considered a target for ray-casting?
  115. /// </summary>
  116. public override bool raycastTarget
  117. {
  118. get => false;
  119. set { }
  120. }
  121. /// <summary>
  122. /// Particle simulation results are shared within the same group.
  123. /// A large number of the same effects can be displayed with a small load.
  124. /// None: disable mesh sharing.
  125. /// Auto: automatically select Primary/Replica.
  126. /// Primary: provides particle simulation results to the same group.
  127. /// Primary Simulator: Primary, but do not render the particle (simulation only).
  128. /// Replica: render simulation results provided by the primary.
  129. /// </summary>
  130. public MeshSharing meshSharing
  131. {
  132. get => m_MeshSharing;
  133. set => m_MeshSharing = value;
  134. }
  135. /// <summary>
  136. /// Mesh sharing group ID.
  137. /// If non-zero is specified, particle simulation results are shared within the group.
  138. /// </summary>
  139. public int groupId
  140. {
  141. get => _groupId;
  142. set
  143. {
  144. if (m_GroupId == value) return;
  145. m_GroupId = value;
  146. if (m_GroupId != m_GroupMaxId)
  147. {
  148. ResetGroupId();
  149. }
  150. }
  151. }
  152. public int groupMaxId
  153. {
  154. get => m_GroupMaxId;
  155. set
  156. {
  157. if (m_GroupMaxId == value) return;
  158. m_GroupMaxId = value;
  159. ResetGroupId();
  160. }
  161. }
  162. /// <summary>
  163. /// Emission position mode.
  164. /// Relative: The particles will be emitted from the scaled position.
  165. /// Absolute: The particles will be emitted from the world position.
  166. /// </summary>
  167. public PositionMode positionMode
  168. {
  169. get => m_PositionMode;
  170. set => m_PositionMode = value;
  171. }
  172. /// <summary>
  173. /// Particle position mode.
  174. /// Relative: The particles will be emitted from the scaled position of the ParticleSystem.
  175. /// Absolute: The particles will be emitted from the world position of the ParticleSystem.
  176. /// </summary>
  177. [Obsolete("The absoluteMode is now obsolete. Please use the autoScalingMode instead.", false)]
  178. public bool absoluteMode
  179. {
  180. get => m_PositionMode == PositionMode.Absolute;
  181. set => positionMode = value ? PositionMode.Absolute : PositionMode.Relative;
  182. }
  183. /// <summary>
  184. /// Prevents the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.
  185. /// </summary>
  186. [Obsolete("The autoScaling is now obsolete. Please use the autoScalingMode instead.", false)]
  187. public bool autoScaling
  188. {
  189. get => m_AutoScalingMode != AutoScalingMode.None;
  190. set => autoScalingMode = value ? AutoScalingMode.Transform : AutoScalingMode.None;
  191. }
  192. /// <summary>
  193. /// How to automatically adjust when the Canvas scale is changed by the screen size or reference resolution.
  194. /// <para/>
  195. /// None: Do nothing.
  196. /// <para/>
  197. /// Transform: Transform.lossyScale (=world scale) will be set to (1, 1, 1).
  198. /// <para/>
  199. /// UIParticle: UIParticle.scale will be adjusted.
  200. /// </summary>
  201. public AutoScalingMode autoScalingMode
  202. {
  203. get => m_AutoScalingMode;
  204. set
  205. {
  206. if (m_AutoScalingMode == value) return;
  207. m_AutoScalingMode = value;
  208. if (autoScalingMode != AutoScalingMode.Transform && _isScaleStored)
  209. {
  210. transform.localScale = _storedScale;
  211. _isScaleStored = false;
  212. }
  213. }
  214. }
  215. /// <summary>
  216. /// Use a custom view.
  217. /// Use this if the particles are not displayed correctly due to min/max particle size.
  218. /// </summary>
  219. public bool useCustomView
  220. {
  221. get => m_UseCustomView;
  222. set => m_UseCustomView = value;
  223. }
  224. /// <summary>
  225. /// Custom view size.
  226. /// Change the bake view size.
  227. /// </summary>
  228. public float customViewSize
  229. {
  230. get => m_CustomViewSize;
  231. set => m_CustomViewSize = Mathf.Max(0.1f, value);
  232. }
  233. /// <summary>
  234. /// Time scale multiplier.
  235. /// </summary>
  236. public float timeScaleMultiplier
  237. {
  238. get => m_TimeScaleMultiplier;
  239. set => m_TimeScaleMultiplier = value;
  240. }
  241. internal bool useMeshSharing => m_MeshSharing != MeshSharing.None;
  242. internal bool isPrimary =>
  243. m_MeshSharing == MeshSharing.Primary
  244. || m_MeshSharing == MeshSharing.PrimarySimulator;
  245. internal bool canSimulate =>
  246. m_MeshSharing == MeshSharing.None
  247. || m_MeshSharing == MeshSharing.Auto
  248. || m_MeshSharing == MeshSharing.Primary
  249. || m_MeshSharing == MeshSharing.PrimarySimulator;
  250. internal bool canRender =>
  251. m_MeshSharing == MeshSharing.None
  252. || m_MeshSharing == MeshSharing.Auto
  253. || m_MeshSharing == MeshSharing.Primary
  254. || m_MeshSharing == MeshSharing.Replica;
  255. /// <summary>
  256. /// Particle effect scale.
  257. /// </summary>
  258. public float scale
  259. {
  260. get => m_Scale3D.x;
  261. set => m_Scale3D = new Vector3(value, value, value);
  262. }
  263. /// <summary>
  264. /// Particle effect scale.
  265. /// </summary>
  266. public Vector3 scale3D
  267. {
  268. get => m_Scale3D;
  269. set => m_Scale3D = value;
  270. }
  271. /// <summary>
  272. /// Particle effect scale.
  273. /// </summary>
  274. public Vector3 scale3DForCalc => autoScalingMode == AutoScalingMode.Transform
  275. ? m_Scale3D
  276. : m_Scale3D.GetScaled(canvasScale, transform.localScale);
  277. public List<ParticleSystem> particles => m_Particles;
  278. /// <summary>
  279. /// Paused.
  280. /// </summary>
  281. public bool isPaused { get; private set; }
  282. public Vector3 parentScale { get; private set; }
  283. public Vector3 canvasScale { get; private set; }
  284. protected override void OnEnable()
  285. {
  286. _isScaleStored = false;
  287. ResetGroupId();
  288. UIParticleUpdater.Register(this);
  289. RegisterDirtyMaterialCallback(UpdateRendererMaterial);
  290. if (0 < particles.Count)
  291. {
  292. RefreshParticles(particles);
  293. }
  294. else
  295. {
  296. RefreshParticles();
  297. }
  298. base.OnEnable();
  299. }
  300. /// <summary>
  301. /// This function is called when the behaviour becomes disabled.
  302. /// </summary>
  303. protected override void OnDisable()
  304. {
  305. _tracker.Clear();
  306. if (autoScalingMode == AutoScalingMode.Transform && _isScaleStored)
  307. {
  308. transform.localScale = _storedScale;
  309. }
  310. _isScaleStored = false;
  311. UIParticleUpdater.Unregister(this);
  312. _renderers.ForEach(r => r.Reset());
  313. UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
  314. base.OnDisable();
  315. }
  316. /// <summary>
  317. /// Callback for when properties have been changed by animation.
  318. /// </summary>
  319. protected override void OnDidApplyAnimationProperties()
  320. {
  321. }
  322. void ISerializationCallbackReceiver.OnBeforeSerialize()
  323. {
  324. }
  325. void ISerializationCallbackReceiver.OnAfterDeserialize()
  326. {
  327. #pragma warning disable CS0612 // Type or member is obsolete
  328. if (m_IgnoreCanvasScaler || m_AutoScaling)
  329. {
  330. m_IgnoreCanvasScaler = false;
  331. m_AutoScaling = false;
  332. m_AutoScalingMode = AutoScalingMode.Transform;
  333. }
  334. if (m_AbsoluteMode)
  335. {
  336. m_AbsoluteMode = false;
  337. m_PositionMode = PositionMode.Absolute;
  338. }
  339. #pragma warning restore CS0612 // Type or member is obsolete
  340. }
  341. /// <summary>
  342. /// Play the ParticleSystems.
  343. /// </summary>
  344. public void Play()
  345. {
  346. particles.Exec(p => p.Simulate(0, false, true));
  347. isPaused = false;
  348. }
  349. /// <summary>
  350. /// Pause the ParticleSystems.
  351. /// </summary>
  352. public void Pause()
  353. {
  354. particles.Exec(p => p.Pause());
  355. isPaused = true;
  356. }
  357. /// <summary>
  358. /// Unpause the ParticleSystems.
  359. /// </summary>
  360. public void Resume()
  361. {
  362. isPaused = false;
  363. }
  364. /// <summary>
  365. /// Stop the ParticleSystems.
  366. /// </summary>
  367. public void Stop()
  368. {
  369. particles.Exec(p => p.Stop());
  370. isPaused = true;
  371. }
  372. /// <summary>
  373. /// Start emission of the ParticleSystems.
  374. /// </summary>
  375. public void StartEmission()
  376. {
  377. particles.Exec(p =>
  378. {
  379. var emission = p.emission;
  380. emission.enabled = true;
  381. });
  382. }
  383. /// <summary>
  384. /// Stop emission of the ParticleSystems.
  385. /// </summary>
  386. public void StopEmission()
  387. {
  388. particles.Exec(p =>
  389. {
  390. var emission = p.emission;
  391. emission.enabled = false;
  392. });
  393. }
  394. /// <summary>
  395. /// Clear the particles of the ParticleSystems.
  396. /// </summary>
  397. public void Clear()
  398. {
  399. particles.Exec(p => p.Clear());
  400. isPaused = true;
  401. }
  402. /// <summary>
  403. /// Get all base materials to render.
  404. /// </summary>
  405. public void GetMaterials(List<Material> result)
  406. {
  407. if (result == null) return;
  408. for (var i = 0; i < _renderers.Count; i++)
  409. {
  410. var r = _renderers[i];
  411. if (!r || !r.material) continue;
  412. result.Add(r.material);
  413. }
  414. }
  415. /// <summary>
  416. /// Refresh UIParticle using the ParticleSystem instance.
  417. /// </summary>
  418. public void SetParticleSystemInstance(GameObject instance)
  419. {
  420. SetParticleSystemInstance(instance, true);
  421. }
  422. /// <summary>
  423. /// Refresh UIParticle using the ParticleSystem instance.
  424. /// </summary>
  425. public void SetParticleSystemInstance(GameObject instance, bool destroyOldParticles)
  426. {
  427. if (!instance) return;
  428. var childCount = transform.childCount;
  429. for (var i = 0; i < childCount; i++)
  430. {
  431. var go = transform.GetChild(i).gameObject;
  432. if (go.TryGetComponent<Camera>(out var cam) && cam == _bakeCamera) continue;
  433. if (go.TryGetComponent<UIParticleRenderer>(out var _)) continue;
  434. go.SetActive(false);
  435. if (destroyOldParticles)
  436. {
  437. Misc.Destroy(go);
  438. }
  439. }
  440. var tr = instance.transform;
  441. tr.SetParent(transform, false);
  442. tr.localPosition = Vector3.zero;
  443. RefreshParticles(instance);
  444. }
  445. /// <summary>
  446. /// Refresh UIParticle using the prefab.
  447. /// The prefab is automatically instantiated.
  448. /// </summary>
  449. public void SetParticleSystemPrefab(GameObject prefab)
  450. {
  451. if (!prefab) return;
  452. SetParticleSystemInstance(Instantiate(prefab.gameObject), true);
  453. }
  454. /// <summary>
  455. /// Refresh UIParticle.
  456. /// Collect ParticleSystems under the GameObject and refresh the UIParticle.
  457. /// </summary>
  458. public void RefreshParticles()
  459. {
  460. RefreshParticles(gameObject);
  461. }
  462. /// <summary>
  463. /// Refresh UIParticle.
  464. /// Collect ParticleSystems under the GameObject and refresh the UIParticle.
  465. /// </summary>
  466. private void RefreshParticles(GameObject root)
  467. {
  468. if (!root) return;
  469. root.GetComponentsInChildren(true, particles);
  470. for (var i = particles.Count - 1; 0 <= i; i--)
  471. {
  472. var ps = particles[i];
  473. if (!ps || ps.GetComponentInParent<UIParticle>(true) != this)
  474. {
  475. particles.RemoveAt(i);
  476. }
  477. }
  478. for (var i = 0; i < particles.Count; i++)
  479. {
  480. var ps = particles[i];
  481. var tsa = ps.textureSheetAnimation;
  482. if (tsa.mode == ParticleSystemAnimationMode.Sprites && tsa.uvChannelMask == 0)
  483. {
  484. tsa.uvChannelMask = UVChannelFlags.UV0;
  485. }
  486. }
  487. RefreshParticles(particles);
  488. }
  489. /// <summary>
  490. /// Refresh UIParticle using a list of ParticleSystems.
  491. /// </summary>
  492. public void RefreshParticles(List<ParticleSystem> particleSystems)
  493. {
  494. // Collect children UIParticleRenderer components.
  495. // #246: Nullptr exceptions when using nested UIParticle components in hierarchy
  496. _renderers.Clear();
  497. var childCount = transform.childCount;
  498. for (var i = 0; i < childCount; i++)
  499. {
  500. var child = transform.GetChild(i);
  501. if (child.TryGetComponent(out UIParticleRenderer uiParticleRenderer))
  502. {
  503. _renderers.Add(uiParticleRenderer);
  504. }
  505. }
  506. // Reset the UIParticleRenderer components.
  507. for (var i = 0; i < _renderers.Count; i++)
  508. {
  509. _renderers[i].Reset(i);
  510. }
  511. // Set the ParticleSystem to the UIParticleRenderer. If the trail is enabled, set it additionally.
  512. var j = 0;
  513. for (var i = 0; i < particleSystems.Count; i++)
  514. {
  515. var ps = particleSystems[i];
  516. if (!ps) continue;
  517. var mainEmitter = ps.GetMainEmitter(particleSystems);
  518. GetRenderer(j++).Set(this, ps, false, mainEmitter);
  519. // If the trail is enabled, set it additionally.
  520. if (ps.trails.enabled)
  521. {
  522. GetRenderer(j++).Set(this, ps, true, mainEmitter);
  523. }
  524. }
  525. }
  526. internal void UpdateTransformScale()
  527. {
  528. _tracker.Clear();
  529. canvasScale = canvas.rootCanvas.transform.localScale.Inverse();
  530. parentScale = transform.parent.lossyScale;
  531. if (autoScalingMode != AutoScalingMode.Transform)
  532. {
  533. if (_isScaleStored)
  534. {
  535. transform.localScale = _storedScale;
  536. }
  537. _isScaleStored = false;
  538. return;
  539. }
  540. var currentScale = transform.localScale;
  541. if (!_isScaleStored)
  542. {
  543. _storedScale = currentScale.IsVisible() ? currentScale : Vector3.one;
  544. _isScaleStored = true;
  545. }
  546. _tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
  547. var newScale = parentScale.Inverse();
  548. if (currentScale != newScale)
  549. {
  550. transform.localScale = newScale;
  551. }
  552. }
  553. internal void UpdateRenderers()
  554. {
  555. if (!isActiveAndEnabled) return;
  556. for (var i = 0; i < _renderers.Count; i++)
  557. {
  558. var r = _renderers[i];
  559. if (r) continue;
  560. RefreshParticles(particles);
  561. break;
  562. }
  563. var bakeCamera = GetBakeCamera();
  564. for (var i = 0; i < _renderers.Count; i++)
  565. {
  566. var r = _renderers[i];
  567. if (!r) continue;
  568. r.UpdateMesh(bakeCamera);
  569. }
  570. }
  571. internal void ResetGroupId()
  572. {
  573. _groupId = m_GroupId == m_GroupMaxId
  574. ? m_GroupId
  575. : Random.Range(m_GroupId, m_GroupMaxId + 1);
  576. }
  577. protected override void UpdateMaterial()
  578. {
  579. }
  580. /// <summary>
  581. /// Call to update the geometry of the Graphic onto the CanvasRenderer.
  582. /// </summary>
  583. protected override void UpdateGeometry()
  584. {
  585. }
  586. private void UpdateRendererMaterial()
  587. {
  588. for (var i = 0; i < _renderers.Count; i++)
  589. {
  590. var r = _renderers[i];
  591. if (!r) continue;
  592. r.maskable = maskable;
  593. r.SetMaterialDirty();
  594. }
  595. }
  596. internal UIParticleRenderer GetRenderer(int index)
  597. {
  598. if (_renderers.Count <= index)
  599. {
  600. _renderers.Add(UIParticleRenderer.AddRenderer(this, index));
  601. }
  602. if (!_renderers[index])
  603. {
  604. _renderers[index] = UIParticleRenderer.AddRenderer(this, index);
  605. }
  606. return _renderers[index];
  607. }
  608. private Camera GetBakeCamera()
  609. {
  610. if (!canvas) return Camera.main;
  611. if (!useCustomView && canvas.renderMode != RenderMode.ScreenSpaceOverlay && canvas.rootCanvas.worldCamera)
  612. {
  613. return canvas.rootCanvas.worldCamera;
  614. }
  615. if (_bakeCamera)
  616. {
  617. _bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
  618. return _bakeCamera;
  619. }
  620. // Find existing baking camera.
  621. var childCount = transform.childCount;
  622. for (var i = 0; i < childCount; i++)
  623. {
  624. if (transform.GetChild(i).TryGetComponent<Camera>(out var cam)
  625. && cam.name == "[generated] UIParticle BakingCamera")
  626. {
  627. _bakeCamera = cam;
  628. break;
  629. }
  630. }
  631. // Create baking camera.
  632. if (!_bakeCamera)
  633. {
  634. var go = new GameObject("[generated] UIParticle BakingCamera");
  635. go.SetActive(false);
  636. go.transform.SetParent(transform, false);
  637. _bakeCamera = go.AddComponent<Camera>();
  638. }
  639. // Setup baking camera.
  640. _bakeCamera.enabled = false;
  641. _bakeCamera.orthographicSize = useCustomView ? customViewSize : 10;
  642. _bakeCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
  643. _bakeCamera.orthographic = true;
  644. _bakeCamera.farClipPlane = 2000f;
  645. _bakeCamera.clearFlags = CameraClearFlags.Nothing;
  646. _bakeCamera.cullingMask = 0; // Nothing
  647. _bakeCamera.allowHDR = false;
  648. _bakeCamera.allowMSAA = false;
  649. _bakeCamera.renderingPath = RenderingPath.Forward;
  650. _bakeCamera.useOcclusionCulling = false;
  651. _bakeCamera.gameObject.SetActive(false);
  652. _bakeCamera.gameObject.hideFlags = UIParticleProjectSettings.globalHideFlags;
  653. return _bakeCamera;
  654. }
  655. }
  656. }