Advertisement
har5452

Untitled

Feb 9th, 2025
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.61 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI; // Required for UI elements
  5. [RequireComponent(typeof(AudioSource))]
  6. public class Chaser2 : MonoBehaviour {
  7.  
  8. public float speed = 20.0f;
  9. public float minDist = 0.2f;
  10. private float health = 100f;
  11. public Transform target;
  12. public bool isAttacking = false;
  13. private Rigidbody rb;
  14. public bool takeDamage;
  15. public ParticleSystem bloodParticles;
  16. public bool isInRange = false;
  17. public bool isDead = false;
  18. public float damageVal;
  19. public bool isEnraged;
  20. public AudioClip pickup;
  21. public AudioClip shoot;
  22. public GameObject dropPrefab; // Assign this in the Inspector
  23. public float attackRange = 15f;
  24. public float attackDamage = 10f;
  25. public float attackCooldown = 2f;
  26. private float pushThreshold = 20f; // Adjust this value as needed
  27. private bool IsBeingPushed;
  28. public bool PlayerLeft;
  29.  
  30. private AudioSource source;
  31. private Coroutine attackCoroutine;
  32.  
  33. void OnEnable() {
  34. health = 100f;
  35. }
  36.  
  37. void Awake() {
  38. source = GetComponent<AudioSource>();
  39. rb = GetComponent<Rigidbody>();
  40. }
  41.  
  42. void Start() {
  43. if (target == null) {
  44. GameObject player = GameObject.FindWithTag("Player");
  45. if (player != null) {
  46. target = player.transform;
  47. }
  48. }
  49.  
  50. if (bloodParticles == null) {
  51. bloodParticles = GetComponentInChildren<ParticleSystem>();
  52. }
  53. }
  54.  
  55. void Update() {
  56. if (!isDead) {
  57. Chase();
  58. SeparateFromOthers(); // ✅ Prevents enemies from stacking
  59.  
  60. // Ensure isInRange updates before attack logic
  61. float distance = Vector3.Distance(transform.position, target.position);
  62. isInRange = distance <= attackRange;
  63.  
  64. if (isInRange && !isAttacking) {
  65. StartAttacking();
  66. } else if (!isInRange && isAttacking) {
  67. StopAttacking();
  68. }
  69. }
  70. }
  71.  
  72. void FixedUpdate() {
  73. if (rb.velocity.magnitude > 10f) {
  74. rb.velocity = rb.velocity.normalized * 10f; // ✅ Limit speed
  75. }
  76. }
  77.  
  78. private void SeparateFromOthers() {
  79. Collider[] hitColliders = Physics.OverlapSphere(transform.position, 1.5f);
  80. foreach (Collider col in hitColliders) {
  81. if (col.gameObject != gameObject && col.CompareTag("Enemy")) {
  82. Vector3 pushDir = (transform.position - col.transform.position).normalized;
  83.  
  84. // ✅ Apply a small velocity change instead of a strong force
  85. rb.velocity += pushDir * 2f; // Adjust value for softer push
  86. IsBeingPushed = true;
  87. print("Enemy is being pushed");
  88. }
  89. }
  90. }
  91.  
  92.  
  93.  
  94. private void StopAttacking() {
  95. if (attackCoroutine != null) {
  96. StopCoroutine(attackCoroutine);
  97. attackCoroutine = null;
  98. isAttacking = false;
  99. Debug.Log("Attack coroutine stopped.");
  100. }
  101. }
  102.  
  103. private void StartAttacking() {
  104. // Only start the attack coroutine if it's not already running
  105. if (attackCoroutine == null) {
  106. float randomDelay = Random.Range(0f, 0.25f); // ✅ Add a random delay (0 to 1 sec)
  107. attackCoroutine = StartCoroutine(StartAttackWithDelay(randomDelay));
  108. }
  109. }
  110.  
  111. private IEnumerator StartAttackWithDelay(float delay) {
  112. yield return new WaitForSeconds(delay); // ✅ Wait before starting attack
  113.  
  114. // ✅ Ensure we only start attacking if still in range
  115. if (isInRange && !isDead) {
  116. attackCoroutine = StartCoroutine(ShootAtPlayer());
  117. isAttacking = true;
  118. Debug.Log("Started Attacking after delay: " + delay);
  119. }
  120. }
  121.  
  122. private IEnumerator ShootAtPlayer() {
  123. while (isInRange && !isDead) {
  124. Debug.Log("Shooting at player.");
  125. ShootRaycast();
  126.  
  127. // Enforces consistent attack timing
  128. yield return new WaitForSeconds(attackCooldown);
  129. }
  130.  
  131. // ✅ Attack stops once out of range
  132. // Attack stops if out of range
  133. isAttacking = false; // ✅ Ensure this is reset
  134.  
  135. // ✅ Instead of checking isInRange only once, start attacking again if needed
  136. StartAttacking(); // Always re-check and restart attack if applicable
  137.  
  138. }
  139.  
  140. private void Chase() {
  141. if (target == null) return;
  142.  
  143. Vector3 direction = (target.position - transform.position).normalized;
  144. float distance = Vector3.Distance(transform.position, target.position);
  145.  
  146. isInRange = distance <= attackRange;
  147.  
  148. if (distance > 20f) {
  149. rb.velocity = Vector3.zero;
  150. return;
  151. }
  152.  
  153. if (!isAttacking) {
  154. float adjustedSpeed = Mathf.Lerp(0, speed, (distance - minDist) / (attackRange - minDist));
  155. rb.MovePosition(rb.position + direction * adjustedSpeed * Time.deltaTime);
  156. } else {
  157. rb.velocity = Vector3.zero; // ✅ Stop movement when attacking
  158. }
  159. }
  160.  
  161.  
  162.  
  163.  
  164. private void ShootRaycast() {
  165. if (target == null) return;
  166.  
  167. Vector3 direction = (target.position - transform.position).normalized;
  168.  
  169. // Debugging Raycast Direction
  170. Debug.DrawRay(transform.position, direction * attackRange, Color.red, 1f);
  171.  
  172. if (Physics.Raycast(transform.position, direction, out RaycastHit hit, attackRange)) {
  173. Debug.Log("Raycast hit: " + hit.transform.name);
  174.  
  175. if (hit.transform.CompareTag("Player")) {
  176. source.PlayOneShot(shoot);
  177. playermovement.Damage(10);
  178. Debug.Log("Hit player! Damage dealt: " + attackDamage);
  179. } else {
  180. Debug.Log("Raycast hit something else: " + hit.transform.name);
  181. }
  182. } else {
  183. Debug.Log("Raycast missed the player.");
  184. }
  185. }
  186.  
  187.  
  188. public void AddDamage(float damage) {
  189. if (isDead) return;
  190.  
  191. takeDamage = true;
  192. isEnraged = true;
  193. source.PlayOneShot(pickup);
  194. damageVal = damage;
  195. health -= damage;
  196.  
  197. bloodParticles?.Play();
  198.  
  199. if (health <= 0) {
  200. Die();
  201. } else {
  202. StartCoroutine(ResetTakeDamageFlag());
  203. }
  204. }
  205.  
  206. private void Die() {
  207. isDead = true;
  208. isAttacking = false;
  209. rb.velocity = Vector3.zero;
  210. bloodParticles?.Play();
  211. StopAllCoroutines();
  212. Instantiate(dropPrefab, transform.position, Quaternion.identity);
  213. }
  214.  
  215. private IEnumerator ResetTakeDamageFlag() {
  216. yield return new WaitForSeconds(0.1f);
  217. takeDamage = false;
  218. }
  219.  
  220. public void KillCharacter() {
  221. Destroy(gameObject);
  222. }
  223. }
  224.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement