Newer
Older
TheVengeance-Project-IADE-Unity2D / Assets / Scripts / NPC / Orc / OrcNPCController.cs
  1. using System.Collections;
  2. using UnityEngine;
  3. using MyCollections.AI.FinitStateMachine;
  4. using System.Collections.Generic;
  5. using TMPro;
  6. public class OrcNPCController : EnemyNPCContoller
  7. {
  8. [SerializeField] private int XpReward = 5;
  9. [SerializeField] private TextMeshProUGUI tmpName;
  10. [SerializeField] private State currentState;
  11. [SerializeField] private GameObject weapon;
  12. [SerializeField] private GameObject coin;
  13. [SerializeField] private float deadTimer = 2;
  14. [SerializeField] private float disabletimer;
  15. [Header("Character Combat Settings: ")]
  16. [SerializeField] private float attackTimer;
  17. [SerializeField] private float maxAttackTimer;
  18. [SerializeField] private float attackRange;
  19. [SerializeField] private int attackDamage;
  20. private Animator weaponAnimator;
  21. private Rigidbody2D rb;
  22. private SpriteRenderer sRenderer;
  23. public float AttackTimer => attackTimer;
  24. public float MaxAttackTimer => maxAttackTimer;
  25. public Animator WeaponAnimator => weaponAnimator;
  26. public GameObject Weapon => weapon;
  27. private bool isAttacking = false;
  28. public bool IsHurt { get; set; }
  29. protected override void Awake()
  30. {
  31. base.Awake();
  32. weaponAnimator = weapon.GetComponent<Animator>();
  33. weapon.SetActive(false);
  34. rb = GetComponent<Rigidbody2D>();
  35. sRenderer = GetComponent<SpriteRenderer>();
  36. }
  37. protected override void Start()
  38. {
  39. base.Start();
  40. tmpName.text = npcName;
  41. disabletimer = deadTimer;
  42. }
  43. protected override void OnEnable()
  44. {
  45. base.OnEnable();
  46. health = maxHealth;
  47. lastDirection = Vector2.right;
  48. AgentFOV.IsEnabled = true;
  49. attackTimer = MaxAttackTimer;
  50. rb.bodyType = RigidbodyType2D.Dynamic;
  51. }
  52. protected override void OnDisable()
  53. {
  54. base.OnDisable();
  55. disabletimer = deadTimer;
  56. }
  57. // Update is called once per frame
  58. protected override void Update()
  59. {
  60. base.Update();
  61. }
  62. protected void FixedUpdate()
  63. {
  64. if (isAttacking)
  65. PerformAttack();
  66. }
  67. protected override void AnimationController()
  68. {
  69. base.AnimationController();
  70. animator.SetBool("IsDead", health <= 0f);
  71. if (animator.GetBool("IsDead"))
  72. {
  73. AnimatorClipInfo deadClip = animator.GetCurrentAnimatorClipInfo(0)[0];
  74. float wait = deadClip.clip.length;
  75. disabletimer -= Time.deltaTime;
  76. if (disabletimer <= 0f)
  77. {
  78. gameObject.SetActive(false);
  79. }
  80. }
  81. if (weapon.activeSelf)
  82. {
  83. weaponAnimator.SetFloat("LookDirectionX", lastDirection.x);
  84. weaponAnimator.SetFloat("LookDirectionY", lastDirection.y);
  85. }
  86. if (isAttacking)
  87. {
  88. StartCoroutine(RecoverAttack());
  89. }
  90. }
  91. //Perform the attack on target
  92. private void PerformAttack()
  93. {
  94. if (agentFOV.GetTarget() != null)
  95. {
  96. Vector3 targetDir = agentFOV.TargetDirection;
  97. RaycastHit2D hit = Physics2D.Raycast(transform.position, targetDir, attackRange);
  98. Debug.DrawRay(transform.position, targetDir * hit.distance, Color.blue, 5f);
  99. // Check if the raycast hit something
  100. if (hit.collider != null)
  101. {
  102. // Check if the hit object has a health system component
  103. if (hit.collider.TryGetComponent(out IHealthSystem h))
  104. {
  105. h.TakeDamage(attackDamage);
  106. }
  107. }
  108. }
  109. isAttacking = false;
  110. }
  111. //Set the attack
  112. //Using int as parameter since the unity Animation event don't support booleans
  113. public void SetAttack(int value) => isAttacking = value != 0;
  114. //Cooldown timer
  115. private IEnumerator RecoverAttack()
  116. {
  117. while (attackTimer >= 0f)
  118. {
  119. attackTimer -= Time.deltaTime;
  120. yield return null;
  121. }
  122. attackTimer = maxAttackTimer;
  123. }
  124. //Take damage
  125. public override void TakeDamage(int amount)
  126. {
  127. base.TakeDamage(amount);
  128. animator.SetTrigger("Hurt");
  129. }
  130. //Animation Event
  131. //When the NPC get's it sprite changes color
  132. public void ChangeSpriteColor(string colorName)
  133. {
  134. switch (colorName)
  135. {
  136. case "white":
  137. sRenderer.color = Color.white;
  138. break;
  139. case "red":
  140. sRenderer.color = Color.red;
  141. break;
  142. }
  143. }
  144. //Checks if the chatacter is dead
  145. public override bool IsDead()
  146. {
  147. if (base.IsDead())
  148. {
  149. rb.bodyType = RigidbodyType2D.Kinematic;
  150. GameManager.Instance.GainExperience(XpReward);
  151. Instantiate(coin, transform.position, Quaternion.identity);
  152. return true;
  153. }
  154. return false;
  155. }
  156. public void OnGUI()
  157. {
  158. Rect rect = new Rect(0f, 0f, 300f, 200f); // Adjust size as needed
  159. GUI.color = Color.red;
  160. List<string> list = new List<string>();
  161. if (currentState != null)
  162. {
  163. list.Add(currentState.name);
  164. foreach (Transition t in currentState.GetTransitions())
  165. {
  166. list.Add($"Transition: {t.name}");
  167. }
  168. // Combine all strings into one string with line breaks
  169. string combinedText = string.Join("\n", list);
  170. // Create a GUIStyle to modify the text appearance
  171. GUIStyle style = new GUIStyle(GUI.skin.box);
  172. style.fontSize = 25; // Set the font size
  173. style.alignment = TextAnchor.MiddleCenter; // Center align the text (optional)
  174. // Display the combined string in the GUI.Box with the custom style
  175. GUI.Box(rect, combinedText, style);
  176. }
  177. }
  178. }