BeamWeapon.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using UnityEngine;
  2. namespace Assets.Scripts.BeamWeapon
  3. {
  4. internal sealed class BeamWeapon : MonoBehaviour
  5. {
  6. public GameObject Beam;
  7. public GameObject ImpactSparks;
  8. public GameObject ImpactFlash;
  9. public AnimationCurve WidthOverTime = AnimationCurve.Linear(0, 1, 1, 1);
  10. public float MaxDistance = 1000;
  11. public LayerMask LayerMask = ~0;
  12. private LineRenderer _lineRenderer;
  13. private GameObject _laserBeam;
  14. private GameObject _impactFlash;
  15. private GameObject _impactSparks;
  16. private float _colorAnimationStartTime;
  17. private void Start()
  18. {
  19. InstantiateBeam();
  20. }
  21. private void InstantiateBeam()
  22. {
  23. if (Beam == null)
  24. return;
  25. _laserBeam = Instantiate(Beam, transform.position, transform.rotation);
  26. _laserBeam.transform.parent = transform;
  27. _lineRenderer = _laserBeam.GetComponent<LineRenderer>();
  28. _colorAnimationStartTime = Time.time;
  29. }
  30. private void InstantiateImpactEffect(Vector3 hitPoint, Vector3 hitNormal)
  31. {
  32. if (ImpactSparks == null)
  33. return;
  34. _impactSparks = Instantiate(ImpactSparks, hitPoint, new Quaternion());
  35. _impactSparks.transform.LookAt(hitPoint + hitNormal);
  36. _impactSparks.transform.parent = transform;
  37. }
  38. private void InstantiateImpactFlash(Vector3 hitPoint)
  39. {
  40. if (ImpactFlash == null)
  41. return;
  42. _impactFlash = Instantiate(ImpactFlash, hitPoint, new Quaternion());
  43. _impactFlash.transform.parent = transform;
  44. }
  45. private void Update()
  46. {
  47. if (_laserBeam == null)
  48. return;
  49. var time = Time.time - _colorAnimationStartTime;
  50. SetWidthOverTime(time);
  51. _laserBeam.transform.rotation = transform.rotation;
  52. RaycastHit hit;
  53. var ray = new Ray(transform.position, transform.forward);
  54. if (Physics.Raycast(ray, out hit, MaxDistance, LayerMask))
  55. {
  56. var hitPosition = hit.point;
  57. hitPosition += (transform.position - hit.point).normalized * 0.1f;
  58. SetLineRendererPosition(transform.position, hitPosition);
  59. if (_impactSparks != null)
  60. {
  61. _impactSparks.transform.position = hitPosition;
  62. _impactFlash.transform.position = hitPosition;
  63. }
  64. else
  65. {
  66. InstantiateImpactEffect(hitPosition, hit.normal);
  67. InstantiateImpactFlash(hitPosition);
  68. }
  69. }
  70. else
  71. {
  72. SetLineRendererPosition(transform.position, transform.position + transform.forward * MaxDistance);
  73. if (_impactSparks != null)
  74. {
  75. Destroy(_impactSparks.gameObject);
  76. Destroy(_impactFlash.gameObject);
  77. _impactSparks = null;
  78. _impactFlash = null;
  79. }
  80. }
  81. }
  82. private void SetWidthOverTime(float time)
  83. {
  84. var width = WidthOverTime.Evaluate(time);
  85. _lineRenderer.startWidth = width;
  86. _lineRenderer.endWidth = width;
  87. }
  88. private void SetLineRendererPosition(Vector3 startPosition, Vector3 endPosition)
  89. {
  90. _lineRenderer.SetPosition(0, startPosition);
  91. _lineRenderer.SetPosition(1, endPosition);
  92. }
  93. }
  94. }