SFX_EnergyShieldController.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. // ReSharper disable once CheckNamespace
  5. namespace QFX.SFX
  6. {
  7. [RequireComponent(typeof(SFX_ColliderCollisionDetector))]
  8. [ExecuteInEditMode]
  9. public class SFX_EnergyShieldController : SFX_ControlledObject
  10. {
  11. public Renderer TargetRenderer;
  12. public float HitWaveSpeed = 1f;
  13. //In case if it's a ParticleSystem, not a object
  14. public bool ProvideObjectWorldCoordinates;
  15. private const int HitMaxCount = 10;
  16. private const string HitPositionsPropertyName = "_HitPositions";
  17. private const string HitRadiiPropertyName = "_HitRadii";
  18. private const string WorldPositionPropertyName = "_ObjectWorldPosition";
  19. private const float MaxHitRadius = 1;
  20. private const float MinHitRadius = 0;
  21. private readonly Vector4[] _hitPositions = new Vector4[HitMaxCount];
  22. private readonly float[] _hitRadii = new float[HitMaxCount];
  23. private Material _material;
  24. private int _currentHitIdx = -1;
  25. private Transform _transform;
  26. private void Awake()
  27. {
  28. _transform = transform;
  29. _material = TargetRenderer.sharedMaterial;
  30. var collisionDetector = GetComponent<SFX_ColliderCollisionDetector>();
  31. collisionDetector.OnCollision += delegate (SFX_CollisionPoint collisionPoint)
  32. {
  33. AddHitData(collisionPoint.Point);
  34. };
  35. }
  36. private void Update()
  37. {
  38. if (!IsRunning)
  39. return;
  40. var hitIdxToReset = new List<int>();
  41. for (int i = 0; i < HitMaxCount; i++)
  42. {
  43. if (Math.Abs(_hitRadii[i] - -1) < 0.01)
  44. continue;
  45. _hitRadii[i] += HitWaveSpeed * Time.deltaTime;
  46. if (_hitRadii[i] >= MaxHitRadius)
  47. hitIdxToReset.Add(i);
  48. }
  49. foreach (var idx in hitIdxToReset)
  50. {
  51. _hitPositions[idx] = Vector4.zero;
  52. _hitRadii[idx] = -1;
  53. }
  54. //Debug hit
  55. // if (Input.GetMouseButtonDown(0))
  56. // {
  57. // var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  58. // RaycastHit hit;
  59. //
  60. // if (!Physics.Raycast(ray, out hit))
  61. // return;
  62. //
  63. // AddHitData(hit.point);
  64. // }
  65. UpdateMaterial();
  66. }
  67. private void AddHitData(Vector3 position)
  68. {
  69. _currentHitIdx++;
  70. if (_currentHitIdx >= HitMaxCount)
  71. _currentHitIdx = 0;
  72. _hitPositions[_currentHitIdx] = position;
  73. _hitRadii[_currentHitIdx] = MinHitRadius;
  74. }
  75. private void UpdateMaterial()
  76. {
  77. _material.SetVectorArray(HitPositionsPropertyName, _hitPositions);
  78. _material.SetFloatArray(HitRadiiPropertyName, _hitRadii);
  79. if (ProvideObjectWorldCoordinates)
  80. _material.SetVector(WorldPositionPropertyName, _transform.position);
  81. }
  82. }
  83. }