2021년 4학년 1학기 기업연계프로젝트2 컴퓨터소프트웨어공학과 <원광투어팀> 팀장 : 송유진 팀원 : 김나영, 이경희, 한유진
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
6.1 KiB

5 years ago
  1. using Unity.FPS.Game;
  2. using UnityEngine;
  3. namespace Unity.FPS.Gameplay
  4. {
  5. [RequireComponent(typeof(AudioSource))]
  6. public class ChargedWeaponEffectsHandler : MonoBehaviour
  7. {
  8. [Header("Visual")] [Tooltip("Object that will be affected by charging scale & color changes")]
  9. public GameObject ChargingObject;
  10. [Tooltip("The spinning frame")] public GameObject SpinningFrame;
  11. [Tooltip("Scale of the charged object based on charge")]
  12. public MinMaxVector3 Scale;
  13. [Header("Particles")] [Tooltip("Particles to create when charging")]
  14. public GameObject DiskOrbitParticlePrefab;
  15. [Tooltip("Local position offset of the charge particles (relative to this transform)")]
  16. public Vector3 Offset;
  17. [Tooltip("Parent transform for the particles (Optional)")]
  18. public Transform ParentTransform;
  19. [Tooltip("Orbital velocity of the charge particles based on charge")]
  20. public MinMaxFloat OrbitY;
  21. [Tooltip("Radius of the charge particles based on charge")]
  22. public MinMaxVector3 Radius;
  23. [Tooltip("Idle spinning speed of the frame based on charge")]
  24. public MinMaxFloat SpinningSpeed;
  25. [Header("Sound")] [Tooltip("Audio clip for charge SFX")]
  26. public AudioClip ChargeSound;
  27. [Tooltip("Sound played in loop after the change is full for this weapon")]
  28. public AudioClip LoopChargeWeaponSfx;
  29. [Tooltip("Duration of the cross fade between the charge and the loop sound")]
  30. public float FadeLoopDuration = 0.5f;
  31. [Tooltip(
  32. "If true, the ChargeSound will be ignored and the pitch on the LoopSound will be procedural, based on the charge amount")]
  33. public bool UseProceduralPitchOnLoopSfx;
  34. [Range(1.0f, 5.0f), Tooltip("Maximum procedural Pitch value")]
  35. public float MaxProceduralPitchValue = 2.0f;
  36. public GameObject ParticleInstance { get; set; }
  37. ParticleSystem m_DiskOrbitParticle;
  38. WeaponController m_WeaponController;
  39. ParticleSystem.VelocityOverLifetimeModule m_VelocityOverTimeModule;
  40. AudioSource m_AudioSource;
  41. AudioSource m_AudioSourceLoop;
  42. float m_LastChargeTriggerTimestamp;
  43. float m_ChargeRatio;
  44. float m_EndchargeTime;
  45. void Awake()
  46. {
  47. m_LastChargeTriggerTimestamp = 0.0f;
  48. // The charge effect needs it's own AudioSources, since it will play on top of the other gun sounds
  49. m_AudioSource = gameObject.AddComponent<AudioSource>();
  50. m_AudioSource.clip = ChargeSound;
  51. m_AudioSource.playOnAwake = false;
  52. m_AudioSource.outputAudioMixerGroup =
  53. AudioUtility.GetAudioGroup(AudioUtility.AudioGroups.WeaponChargeBuildup);
  54. // create a second audio source, to play the sound with a delay
  55. m_AudioSourceLoop = gameObject.AddComponent<AudioSource>();
  56. m_AudioSourceLoop.clip = LoopChargeWeaponSfx;
  57. m_AudioSourceLoop.playOnAwake = false;
  58. m_AudioSourceLoop.loop = true;
  59. m_AudioSourceLoop.outputAudioMixerGroup =
  60. AudioUtility.GetAudioGroup(AudioUtility.AudioGroups.WeaponChargeLoop);
  61. }
  62. void SpawnParticleSystem()
  63. {
  64. ParticleInstance = Instantiate(DiskOrbitParticlePrefab,
  65. ParentTransform != null ? ParentTransform : transform);
  66. ParticleInstance.transform.localPosition += Offset;
  67. FindReferences();
  68. }
  69. public void FindReferences()
  70. {
  71. m_DiskOrbitParticle = ParticleInstance.GetComponent<ParticleSystem>();
  72. DebugUtility.HandleErrorIfNullGetComponent<ParticleSystem, ChargedWeaponEffectsHandler>(m_DiskOrbitParticle,
  73. this, ParticleInstance.gameObject);
  74. m_WeaponController = GetComponent<WeaponController>();
  75. DebugUtility.HandleErrorIfNullGetComponent<WeaponController, ChargedWeaponEffectsHandler>(
  76. m_WeaponController, this, gameObject);
  77. m_VelocityOverTimeModule = m_DiskOrbitParticle.velocityOverLifetime;
  78. }
  79. void Update()
  80. {
  81. if (ParticleInstance == null)
  82. SpawnParticleSystem();
  83. m_DiskOrbitParticle.gameObject.SetActive(m_WeaponController.IsWeaponActive);
  84. m_ChargeRatio = m_WeaponController.CurrentCharge;
  85. ChargingObject.transform.localScale = Scale.GetValueFromRatio(m_ChargeRatio);
  86. if (SpinningFrame != null)
  87. {
  88. SpinningFrame.transform.localRotation *= Quaternion.Euler(0,
  89. SpinningSpeed.GetValueFromRatio(m_ChargeRatio) * Time.deltaTime, 0);
  90. }
  91. m_VelocityOverTimeModule.orbitalY = OrbitY.GetValueFromRatio(m_ChargeRatio);
  92. m_DiskOrbitParticle.transform.localScale = Radius.GetValueFromRatio(m_ChargeRatio * 1.1f);
  93. // update sound's volume and pitch
  94. if (m_ChargeRatio > 0)
  95. {
  96. if (!m_AudioSourceLoop.isPlaying &&
  97. m_WeaponController.LastChargeTriggerTimestamp > m_LastChargeTriggerTimestamp)
  98. {
  99. m_LastChargeTriggerTimestamp = m_WeaponController.LastChargeTriggerTimestamp;
  100. if (!UseProceduralPitchOnLoopSfx)
  101. {
  102. m_EndchargeTime = Time.time + ChargeSound.length;
  103. m_AudioSource.Play();
  104. }
  105. m_AudioSourceLoop.Play();
  106. }
  107. if (!UseProceduralPitchOnLoopSfx)
  108. {
  109. float volumeRatio =
  110. Mathf.Clamp01((m_EndchargeTime - Time.time - FadeLoopDuration) / FadeLoopDuration);
  111. m_AudioSource.volume = volumeRatio;
  112. m_AudioSourceLoop.volume = 1 - volumeRatio;
  113. }
  114. else
  115. {
  116. m_AudioSourceLoop.pitch = Mathf.Lerp(1.0f, MaxProceduralPitchValue, m_ChargeRatio);
  117. }
  118. }
  119. else
  120. {
  121. m_AudioSource.Stop();
  122. m_AudioSourceLoop.Stop();
  123. }
  124. }
  125. }
  126. }