ItemPickup.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace HQFPSWeapons
  4. {
  5. /// <summary>
  6. ///
  7. /// </summary>
  8. public class ItemPickup : InteractiveObject
  9. {
  10. /// <summary> </summary>
  11. public SaveableItem ItemInstance { get { return m_ItemInstance; } }
  12. public float InterractionProgress = 0f;
  13. public bool NeedToSwap { get; set; }
  14. public float SwapTime => m_SwapTime;
  15. public ItemContainerFlags TargetContainers => m_TargetContainers;
  16. [Space]
  17. [BHeader("Pick Up Method", order = 100)]
  18. [SerializeField]
  19. private PickUpMethod m_PickUpMethod = PickUpMethod.InteractionBased;
  20. [SerializeField]
  21. [ShowIf("m_PickUpMethod", (int)PickUpMethod.TriggerBased)]
  22. [Tooltip("The radius of the auto-created trigger.")]
  23. private float m_TriggerRadius = 0.5f;
  24. [SerializeField]
  25. [ShowIf("m_PickUpMethod", (int)PickUpMethod.InteractionBased)]
  26. private float m_SwapTime = 0f;
  27. [BHeader("Item", order = 100)]
  28. [SerializeField]
  29. [DatabaseItem]
  30. private string m_Item = string.Empty;
  31. [SerializeField]
  32. private int m_ItemCount = 1;
  33. [SerializeField]
  34. [Tooltip("In what container of the Player will the picked up item go")]
  35. private ItemContainerFlags m_TargetContainers = ItemContainerFlags.AmmoPouch;
  36. [SerializeField]
  37. private SoundPlayer m_CollideSounds = null;
  38. [SerializeField]
  39. private SoundPlayer m_PickupSounds = null;
  40. [SerializeField]
  41. private float m_PlayCollideSoundThresshold = 1f;
  42. [SerializeField]
  43. private LayerMask m_LayerMask = new LayerMask();
  44. [BHeader("Pick Up Message", order = 100)]
  45. [SerializeField]
  46. private Color m_BaseMessageColor = new Color(1f, 1f, 1f, 0.678f);
  47. [SerializeField]
  48. private Color m_ItemCountColor = new Color(0.976f, 0.6f, 0.129f, 1f);
  49. [SerializeField]
  50. private Color m_InventoryFullColor = Color.red;
  51. private SaveableItem m_ItemInstance;
  52. private string m_InitialInteractionText;
  53. private Rigidbody m_RigidB;
  54. private float m_NextTimePlayCollideSound;
  55. public void OnLoad()
  56. {
  57. SetInteractionText(m_ItemInstance);
  58. }
  59. public override void OnInteractionStart(Player player)
  60. {
  61. base.OnInteractionStart(player);
  62. if(NeedToSwap)
  63. InterractionProgress = 0;
  64. else
  65. OnPickUp(player);
  66. }
  67. public override void OnInteractionUpdate(Player player)
  68. {
  69. if (NeedToSwap)
  70. {
  71. InterractionProgress += Time.deltaTime;
  72. if (InterractionProgress > m_SwapTime)
  73. OnPickUp(player);
  74. }
  75. }
  76. public override void OnInteractionEnd(Player player)
  77. {
  78. base.OnInteractionEnd(player);
  79. InterractionProgress = 0;
  80. }
  81. public void EnablePickup(bool enable)
  82. {
  83. InteractionEnabled = enable;
  84. }
  85. public void SetItem(SaveableItem item)
  86. {
  87. m_ItemInstance = item;
  88. if(m_ItemInstance != null)
  89. {
  90. m_Item = m_ItemInstance.Name;
  91. SetInteractionText(m_ItemInstance);
  92. }
  93. }
  94. private void OnCollisionEnter(Collision collision)
  95. {
  96. if (m_RigidB != null && m_LayerMask == (m_LayerMask | (1 << collision.collider.gameObject.layer)) && !collision.collider.isTrigger && Time.time > m_NextTimePlayCollideSound)
  97. {
  98. float collideVolume = Mathf.Clamp(collision.relativeVelocity.sqrMagnitude / 5f, 0.1f, 0.3f);
  99. if (m_RigidB.velocity.sqrMagnitude > m_PlayCollideSoundThresshold)
  100. m_CollideSounds.PlayAtPosition(ItemSelection.Method.Random, transform.position, collideVolume);
  101. m_NextTimePlayCollideSound = Time.time + 0.5f;
  102. }
  103. }
  104. private void Awake()
  105. {
  106. m_InitialInteractionText = m_InteractionText;
  107. if(m_PickUpMethod != PickUpMethod.InteractionBased)
  108. InteractionEnabled = false;
  109. ItemData itemData;
  110. if(ItemDatabase.Default.TryGetItem(m_Item, out itemData))
  111. m_ItemInstance = new SaveableItem(itemData, m_ItemCount);
  112. // Create a trigger if the pickup method is set to WalkOver
  113. if(m_PickUpMethod == PickUpMethod.TriggerBased)
  114. {
  115. var sphereCol = gameObject.AddComponent<SphereCollider>();
  116. sphereCol.isTrigger = true;
  117. sphereCol.radius = m_TriggerRadius;
  118. }
  119. SetInteractionText(m_ItemInstance);
  120. if (GetComponent<Rigidbody>() != null)
  121. m_RigidB = GetComponent<Rigidbody>();
  122. m_NextTimePlayCollideSound = Time.time + 0.025f;
  123. }
  124. private void SetInteractionText(SaveableItem item)
  125. {
  126. if(item.CurrentStackSize < 2)
  127. m_InteractionText = string.Format(m_InitialInteractionText, item.Name.ToUpper());
  128. else
  129. m_InteractionText = string.Format(m_InitialInteractionText + " x " + item.CurrentStackSize, item.Name.ToUpper());
  130. }
  131. private void OnTriggerEnter(Collider col)
  132. {
  133. if(m_PickUpMethod != PickUpMethod.TriggerBased)
  134. return;
  135. var player = col.GetComponent<Player>();
  136. if(player != null)
  137. OnPickUp(player);
  138. }
  139. private void OnDrawGizmosSelected()
  140. {
  141. if(m_PickUpMethod == PickUpMethod.TriggerBased)
  142. {
  143. var prevColor = Gizmos.color;
  144. Gizmos.color = new Color(0.2f, 1f, 0.3f, 0.2f);
  145. Gizmos.DrawSphere(transform.position, m_TriggerRadius);
  146. Gizmos.color = prevColor;
  147. }
  148. }
  149. private void OnValidate()
  150. {
  151. m_TriggerRadius = Mathf.Clamp(m_TriggerRadius, 0f, 2f);
  152. }
  153. private void OnPickUp(Player player)
  154. {
  155. if(m_ItemInstance != null)
  156. {
  157. bool destroy = false;
  158. bool swappedItems = false;
  159. if (player.Inventory.GetContainerWithFlags(m_TargetContainers).ContainerIsFull())
  160. {
  161. if (player.EquippedItem.Get() != null && player.SwapItems.Try(ItemInstance))
  162. swappedItems = true;
  163. }
  164. if(!swappedItems)
  165. {
  166. bool addedItem = player.Inventory.AddItem(m_ItemInstance, m_TargetContainers);
  167. // Item added to inventory
  168. if (addedItem)
  169. {
  170. if (m_ItemInstance.Data.StackSize > 1)
  171. MessageDisplayer.Instance.PushMessage(string.Format("Picked up <color={0}>{1}</color> x {2}", ColorUtils.ColorToHex(m_ItemCountColor), m_ItemInstance.Name, m_ItemInstance.CurrentStackSize), m_BaseMessageColor);
  172. else
  173. MessageDisplayer.Instance.PushMessage(string.Format("Picked up <color={0}>{1}</color>", ColorUtils.ColorToHex(m_ItemCountColor), m_ItemInstance.Name), m_BaseMessageColor);
  174. destroy = true;
  175. //Play pickup sound
  176. m_PickupSounds.Play2D(ItemSelection.Method.RandomExcludeLast);
  177. }
  178. // Item not added to inventory
  179. else
  180. {
  181. MessageDisplayer.Instance.PushMessage(string.Format("<color={0}>Inventory Full</color>", ColorUtils.ColorToHex(m_InventoryFullColor)), m_BaseMessageColor);
  182. }
  183. }
  184. // Item swapped
  185. else
  186. {
  187. destroy = true;
  188. }
  189. if(destroy)
  190. Destroy(gameObject);
  191. }
  192. else
  193. {
  194. Debug.LogError("Item Instance is null, can't pick up anything.");
  195. return;
  196. }
  197. }
  198. public IEnumerator C_DelayedDestroy(float lifeTime)
  199. {
  200. yield return new WaitForSeconds(lifeTime);
  201. Destroy(gameObject);
  202. }
  203. // ------------------- Internal ------------------
  204. public enum PickUpMethod
  205. {
  206. TriggerBased,
  207. InteractionBased
  208. }
  209. }
  210. }