F3DProjectile.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using UnityEngine;
  2. using System.Collections;
  3. public class F3DProjectile : MonoBehaviour
  4. {
  5. public F3DFXType fxType; // Weapon type
  6. public LayerMask layerMask;
  7. public float lifeTime = 5f; // Projectile life time
  8. public float despawnDelay; // Delay despawn in ms
  9. public float velocity = 300f; // Projectile velocity
  10. public float RaycastAdvance = 2f; // Raycast advance multiplier
  11. public bool DelayDespawn = false; // Projectile despawn flag
  12. public ParticleSystem[] delayedParticles; // Array of delayed particles
  13. ParticleSystem[] particles; // Array of projectile particles
  14. new Transform transform; // Cached transform
  15. RaycastHit hitPoint; // Raycast structure
  16. bool isHit = false; // Projectile hit flag
  17. bool isFXSpawned = false; // Hit FX prefab spawned flag
  18. float timer = 0f; // Projectile timer
  19. void Awake()
  20. {
  21. // Cache transform and get all particle systems attached
  22. transform = GetComponent<Transform>();
  23. particles = GetComponentsInChildren<ParticleSystem>();
  24. }
  25. // OnSpawned called by pool manager
  26. public void OnSpawned()
  27. {
  28. // Reset flags and raycast structure
  29. isHit = false;
  30. isFXSpawned = false;
  31. timer = 0f;
  32. hitPoint = new RaycastHit();
  33. }
  34. // OnDespawned called by pool manager
  35. public void OnDespawned()
  36. {
  37. }
  38. // Stop attached particle systems emission and allow them to fade out before despawning
  39. void Delay()
  40. {
  41. if(particles.Length > 0 && delayedParticles.Length > 0)
  42. {
  43. bool delayed;
  44. for (int i = 0; i < particles.Length; i++)
  45. {
  46. delayed = false;
  47. for (int y = 0; y < delayedParticles.Length; y++)
  48. if (particles[i] == delayedParticles[y])
  49. {
  50. delayed = true;
  51. break;
  52. }
  53. particles[i].Stop(false);
  54. if (!delayed)
  55. particles[i].Clear(false);
  56. }
  57. }
  58. }
  59. // OnDespawned called by pool manager
  60. void OnProjectileDestroy()
  61. {
  62. F3DPool.instance.Despawn(transform);
  63. }
  64. // Apply hit force on impact
  65. void ApplyForce(float force)
  66. {
  67. if (hitPoint.rigidbody != null)
  68. hitPoint.rigidbody.AddForceAtPosition(transform.forward * force, hitPoint.point, ForceMode.VelocityChange);
  69. }
  70. void Update()
  71. {
  72. // If something was hit
  73. if (isHit)
  74. {
  75. // Execute once
  76. if (!isFXSpawned)
  77. {
  78. // Invoke corresponding method that spawns FX
  79. switch (fxType)
  80. {
  81. case F3DFXType.Vulcan:
  82. F3DFXController.instance.VulcanImpact(hitPoint.point + hitPoint.normal * 0.2f);
  83. ApplyForce(2.5f);
  84. break;
  85. case F3DFXType.SoloGun:
  86. F3DFXController.instance.SoloGunImpact(hitPoint.point + hitPoint.normal * 0.2f);
  87. ApplyForce(25f);
  88. break;
  89. case F3DFXType.Seeker:
  90. F3DFXController.instance.SeekerImpact(hitPoint.point + hitPoint.normal * 1f);
  91. ApplyForce(30f);
  92. break;
  93. case F3DFXType.PlasmaGun:
  94. F3DFXController.instance.PlasmaGunImpact(hitPoint.point + hitPoint.normal * 0.2f);
  95. ApplyForce(25f);
  96. break;
  97. case F3DFXType.LaserImpulse:
  98. F3DFXController.instance.LaserImpulseImpact(hitPoint.point + hitPoint.normal * 0.2f);
  99. ApplyForce(25f);
  100. break;
  101. default:
  102. break;
  103. }
  104. isFXSpawned = true;
  105. }
  106. // Despawn current projectile
  107. if(!DelayDespawn || (DelayDespawn && (timer >= despawnDelay)))
  108. OnProjectileDestroy();
  109. }
  110. // No collision occurred yet
  111. else
  112. {
  113. // Projectile step per frame based on velocity and time
  114. Vector3 step = transform.forward * Time.deltaTime * velocity;
  115. // Raycast for targets with ray length based on frame step by ray cast advance multiplier
  116. if (Physics.Raycast(transform.position, transform.forward, out hitPoint, step.magnitude * RaycastAdvance, layerMask))
  117. {
  118. isHit = true;
  119. // Invoke delay routine if required
  120. if (DelayDespawn)
  121. {
  122. // Reset projectile timer and let particles systems stop emitting and fade out correctly
  123. timer = 0f;
  124. Delay();
  125. }
  126. }
  127. // Nothing hit
  128. else
  129. {
  130. // Projectile despawn after run out of time
  131. if (timer >= lifeTime)
  132. OnProjectileDestroy();
  133. }
  134. // Advances projectile forward
  135. transform.position += step;
  136. }
  137. // Updates projectile timer
  138. timer += Time.deltaTime;
  139. }
  140. }