F3DBeam.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. using UnityEngine;
  2. using System.Collections;
  3. [RequireComponent(typeof(LineRenderer))]
  4. public class F3DBeam : MonoBehaviour
  5. {
  6. public LayerMask layerMask;
  7. public F3DFXType fxType; // Weapon type
  8. public bool OneShot; // Constant or single beam?
  9. public Texture[] BeamFrames; // Animation frame sequence
  10. public float FrameStep; // Animation time
  11. public float beamScale; // Default beam scale to be kept over distance
  12. public float MaxBeamLength; // Maximum beam length
  13. public bool AnimateUV; // UV Animation
  14. public float UVTime; // UV Animation speed
  15. public Transform rayImpact; // Impact transform
  16. public Transform rayMuzzle; // Muzzle flash transform
  17. LineRenderer lineRenderer; // Line rendered component
  18. RaycastHit hitPoint; // Raycast structure
  19. int frameNo; // Frame counter
  20. int FrameTimerID; // Frame timer reference
  21. float beamLength; // Current beam length
  22. float initialBeamOffset; // Initial UV offset
  23. void Awake()
  24. {
  25. // Get line renderer component
  26. lineRenderer = GetComponent<LineRenderer>();
  27. // Assign first frame texture
  28. if (!AnimateUV && BeamFrames.Length > 0)
  29. lineRenderer.material.mainTexture = BeamFrames[0];
  30. // Randomize uv offset
  31. initialBeamOffset = Random.Range(0f, 5f);
  32. }
  33. // OnSpawned called by pool manager
  34. void OnSpawned()
  35. {
  36. // Do one time raycast in case of one shot flag
  37. if (OneShot)
  38. Raycast();
  39. // Start animation sequence if beam frames array has more than 2 elements
  40. if (BeamFrames.Length > 1)
  41. Animate();
  42. // Play audio depending on weapon type
  43. switch (fxType)
  44. {
  45. case F3DFXType.PlasmaBeam:
  46. // Spawn audio source prefab at specified position linked to parent of current transform
  47. F3DAudioController.instance.PlasmaBeamLoop(transform.position, transform.parent);
  48. break;
  49. case F3DFXType.PlasmaBeamHeavy:
  50. F3DAudioController.instance.PlasmaBeamHeavyLoop(transform.position, transform.parent);
  51. break;
  52. default:
  53. break;
  54. }
  55. }
  56. // OnDespawned called by pool manager
  57. void OnDespawned()
  58. {
  59. // Reset frame counter
  60. frameNo = 0;
  61. // Clear timer
  62. if (FrameTimerID != -1)
  63. {
  64. F3DTime.time.RemoveTimer(FrameTimerID);
  65. FrameTimerID = -1;
  66. }
  67. // Play audio
  68. switch (fxType)
  69. {
  70. case F3DFXType.PlasmaBeam:
  71. F3DAudioController.instance.PlasmaBeamClose(transform.position);
  72. break;
  73. case F3DFXType.PlasmaBeamHeavy:
  74. F3DAudioController.instance.PlasmaBeamHeavyClose(transform.position);
  75. break;
  76. default:
  77. break;
  78. }
  79. }
  80. // Hit point calculation
  81. void Raycast()
  82. {
  83. // Prepare structure and create ray
  84. hitPoint = new RaycastHit();
  85. Ray ray = new Ray(transform.position, transform.forward);
  86. // Calculate default beam proportion multiplier based on default scale and maximum length
  87. float propMult = MaxBeamLength * (beamScale / 10f);
  88. // Raycast
  89. if (Physics.Raycast(ray, out hitPoint, MaxBeamLength, layerMask))
  90. {
  91. // Get current beam length and update line renderer accordingly
  92. beamLength = Vector3.Distance(transform.position, hitPoint.point);
  93. lineRenderer.SetPosition(1, new Vector3(0f, 0f, beamLength));
  94. // Calculate default beam proportion multiplier based on default scale and current length
  95. propMult = beamLength * (beamScale / 10f);
  96. // Spawn prefabs and apply force
  97. switch (fxType)
  98. {
  99. case F3DFXType.Sniper:
  100. F3DFXController.instance.SniperImpact(hitPoint.point + hitPoint.normal * 0.2f);
  101. ApplyForce(4f);
  102. break;
  103. case F3DFXType.RailGun:
  104. F3DFXController.instance.RailgunImpact(hitPoint.point + hitPoint.normal * 0.2f);
  105. ApplyForce(7f);
  106. break;
  107. case F3DFXType.PlasmaBeam:
  108. ApplyForce(0.5f);
  109. break;
  110. case F3DFXType.PlasmaBeamHeavy:
  111. ApplyForce(2f);
  112. break;
  113. default:
  114. break;
  115. }
  116. // Adjust impact effect position
  117. if (rayImpact)
  118. rayImpact.position = hitPoint.point - transform.forward * 0.5f;
  119. }
  120. // Nothing was his
  121. else
  122. {
  123. // Set beam to maximum length
  124. beamLength = MaxBeamLength;
  125. lineRenderer.SetPosition(1, new Vector3(0f, 0f, beamLength));
  126. // Adjust impact effect position
  127. if (rayImpact)
  128. rayImpact.position = transform.position + transform.forward * beamLength;
  129. }
  130. // Adjust muzzle position
  131. if(rayMuzzle)
  132. rayMuzzle.position = transform.position + transform.forward * 0.1f;
  133. // Set beam scaling according to its length
  134. lineRenderer.material.SetTextureScale("_MainTex", new Vector2(propMult, 1f));
  135. }
  136. // Advance texture frame
  137. void OnFrameStep()
  138. {
  139. // Set current texture frame based on frame counter
  140. lineRenderer.material.mainTexture = BeamFrames[frameNo];
  141. frameNo++;
  142. // Reset frame counter
  143. if (frameNo == BeamFrames.Length)
  144. frameNo = 0;
  145. }
  146. // Initialize frame animation
  147. void Animate()
  148. {
  149. if (BeamFrames.Length > 1)
  150. {
  151. // Set current frame
  152. frameNo = 0;
  153. lineRenderer.material.mainTexture = BeamFrames[frameNo];
  154. // Add timer
  155. FrameTimerID = F3DTime.time.AddTimer(FrameStep, BeamFrames.Length - 1, OnFrameStep);
  156. frameNo = 1;
  157. }
  158. }
  159. // Apply force to last hit object
  160. void ApplyForce(float force)
  161. {
  162. if (hitPoint.rigidbody != null)
  163. hitPoint.rigidbody.AddForceAtPosition(transform.forward * force, hitPoint.point, ForceMode.VelocityChange);
  164. }
  165. void Update()
  166. {
  167. // Animate texture UV
  168. if (AnimateUV)
  169. lineRenderer.material.SetTextureOffset("_MainTex", new Vector2(Time.time * UVTime + initialBeamOffset, 0f));
  170. // Raycast for laser beams
  171. if (!OneShot)
  172. Raycast();
  173. }
  174. }