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.

153 lines
5.7 KiB

5 years ago
  1. using Unity.FPS.Game;
  2. using UnityEngine;
  3. using UnityEngine.Events;
  4. namespace Unity.FPS.Gameplay
  5. {
  6. [RequireComponent(typeof(AudioSource))]
  7. public class Jetpack : MonoBehaviour
  8. {
  9. [Header("References")] [Tooltip("Audio source for jetpack sfx")]
  10. public AudioSource AudioSource;
  11. [Tooltip("Particles for jetpack vfx")] public ParticleSystem[] JetpackVfx;
  12. [Header("Parameters")] [Tooltip("Whether the jetpack is unlocked at the begining or not")]
  13. public bool IsJetpackUnlockedAtStart = false;
  14. [Tooltip("The strength with which the jetpack pushes the player up")]
  15. public float JetpackAcceleration = 7f;
  16. [Range(0f, 1f)]
  17. [Tooltip(
  18. "This will affect how much using the jetpack will cancel the gravity value, to start going up faster. 0 is not at all, 1 is instant")]
  19. public float JetpackDownwardVelocityCancelingFactor = 1f;
  20. [Header("Durations")] [Tooltip("Time it takes to consume all the jetpack fuel")]
  21. public float ConsumeDuration = 1.5f;
  22. [Tooltip("Time it takes to completely refill the jetpack while on the ground")]
  23. public float RefillDurationGrounded = 2f;
  24. [Tooltip("Time it takes to completely refill the jetpack while in the air")]
  25. public float RefillDurationInTheAir = 5f;
  26. [Tooltip("Delay after last use before starting to refill")]
  27. public float RefillDelay = 1f;
  28. [Header("Audio")] [Tooltip("Sound played when using the jetpack")]
  29. public AudioClip JetpackSfx;
  30. bool m_CanUseJetpack;
  31. PlayerCharacterController m_PlayerCharacterController;
  32. PlayerInputHandler m_InputHandler;
  33. float m_LastTimeOfUse;
  34. // stored ratio for jetpack resource (1 is full, 0 is empty)
  35. public float CurrentFillRatio { get; private set; }
  36. public bool IsJetpackUnlocked { get; private set; }
  37. public bool IsPlayergrounded() => m_PlayerCharacterController.IsGrounded;
  38. public UnityAction<bool> OnUnlockJetpack;
  39. void Start()
  40. {
  41. IsJetpackUnlocked = IsJetpackUnlockedAtStart;
  42. m_PlayerCharacterController = GetComponent<PlayerCharacterController>();
  43. DebugUtility.HandleErrorIfNullGetComponent<PlayerCharacterController, Jetpack>(m_PlayerCharacterController,
  44. this, gameObject);
  45. m_InputHandler = GetComponent<PlayerInputHandler>();
  46. DebugUtility.HandleErrorIfNullGetComponent<PlayerInputHandler, Jetpack>(m_InputHandler, this, gameObject);
  47. CurrentFillRatio = 1f;
  48. AudioSource.clip = JetpackSfx;
  49. AudioSource.loop = true;
  50. }
  51. void Update()
  52. {
  53. // jetpack can only be used if not grounded and jump has been pressed again once in-air
  54. if (IsPlayergrounded())
  55. {
  56. m_CanUseJetpack = false;
  57. }
  58. else if (!m_PlayerCharacterController.HasJumpedThisFrame && m_InputHandler.GetJumpInputDown())
  59. {
  60. m_CanUseJetpack = true;
  61. }
  62. // jetpack usage
  63. bool jetpackIsInUse = m_CanUseJetpack && IsJetpackUnlocked && CurrentFillRatio > 0f &&
  64. m_InputHandler.GetJumpInputHeld();
  65. if (jetpackIsInUse)
  66. {
  67. // store the last time of use for refill delay
  68. m_LastTimeOfUse = Time.time;
  69. float totalAcceleration = JetpackAcceleration;
  70. // cancel out gravity
  71. totalAcceleration += m_PlayerCharacterController.GravityDownForce;
  72. if (m_PlayerCharacterController.CharacterVelocity.y < 0f)
  73. {
  74. // handle making the jetpack compensate for character's downward velocity with bonus acceleration
  75. totalAcceleration += ((-m_PlayerCharacterController.CharacterVelocity.y / Time.deltaTime) *
  76. JetpackDownwardVelocityCancelingFactor);
  77. }
  78. // apply the acceleration to character's velocity
  79. m_PlayerCharacterController.CharacterVelocity += Vector3.up * totalAcceleration * Time.deltaTime;
  80. // consume fuel
  81. CurrentFillRatio = CurrentFillRatio - (Time.deltaTime / ConsumeDuration);
  82. for (int i = 0; i < JetpackVfx.Length; i++)
  83. {
  84. var emissionModulesVfx = JetpackVfx[i].emission;
  85. emissionModulesVfx.enabled = true;
  86. }
  87. if (!AudioSource.isPlaying)
  88. AudioSource.Play();
  89. }
  90. else
  91. {
  92. // refill the meter over time
  93. if (IsJetpackUnlocked && Time.time - m_LastTimeOfUse >= RefillDelay)
  94. {
  95. float refillRate = 1 / (m_PlayerCharacterController.IsGrounded
  96. ? RefillDurationGrounded
  97. : RefillDurationInTheAir);
  98. CurrentFillRatio = CurrentFillRatio + Time.deltaTime * refillRate;
  99. }
  100. for (int i = 0; i < JetpackVfx.Length; i++)
  101. {
  102. var emissionModulesVfx = JetpackVfx[i].emission;
  103. emissionModulesVfx.enabled = false;
  104. }
  105. // keeps the ratio between 0 and 1
  106. CurrentFillRatio = Mathf.Clamp01(CurrentFillRatio);
  107. if (AudioSource.isPlaying)
  108. AudioSource.Stop();
  109. }
  110. }
  111. public bool TryUnlock()
  112. {
  113. if (IsJetpackUnlocked)
  114. return false;
  115. OnUnlockJetpack.Invoke(true);
  116. IsJetpackUnlocked = true;
  117. m_LastTimeOfUse = Time.time;
  118. return true;
  119. }
  120. }
  121. }