Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI; // Required for UI elements
- [RequireComponent(typeof(AudioSource))]
- public class Chaser2 : MonoBehaviour {
- public float speed = 20.0f;
- public float minDist = 0.2f;
- private float health = 100f;
- public Transform target;
- public bool isAttacking = false;
- private Rigidbody rb;
- public bool takeDamage;
- public ParticleSystem bloodParticles;
- public bool isInRange = false;
- public bool isDead = false;
- public float damageVal;
- public bool isEnraged;
- public AudioClip pickup;
- public AudioClip shoot;
- public GameObject dropPrefab; // Assign this in the Inspector
- public float attackRange = 15f;
- public float attackDamage = 10f;
- public float attackCooldown = 2f;
- private float pushThreshold = 20f; // Adjust this value as needed
- private bool IsBeingPushed;
- public bool PlayerLeft;
- private AudioSource source;
- private Coroutine attackCoroutine;
- void OnEnable() {
- health = 100f;
- }
- void Awake() {
- source = GetComponent<AudioSource>();
- rb = GetComponent<Rigidbody>();
- }
- void Start() {
- if (target == null) {
- GameObject player = GameObject.FindWithTag("Player");
- if (player != null) {
- target = player.transform;
- }
- }
- if (bloodParticles == null) {
- bloodParticles = GetComponentInChildren<ParticleSystem>();
- }
- }
- void Update() {
- if (!isDead) {
- Chase();
- SeparateFromOthers(); // ✅ Prevents enemies from stacking
- // Ensure isInRange updates before attack logic
- float distance = Vector3.Distance(transform.position, target.position);
- isInRange = distance <= attackRange;
- if (isInRange && !isAttacking) {
- StartAttacking();
- } else if (!isInRange && isAttacking) {
- StopAttacking();
- }
- }
- }
- void FixedUpdate() {
- if (rb.velocity.magnitude > 10f) {
- rb.velocity = rb.velocity.normalized * 10f; // ✅ Limit speed
- }
- }
- private void SeparateFromOthers() {
- Collider[] hitColliders = Physics.OverlapSphere(transform.position, 1.5f);
- foreach (Collider col in hitColliders) {
- if (col.gameObject != gameObject && col.CompareTag("Enemy")) {
- Vector3 pushDir = (transform.position - col.transform.position).normalized;
- // ✅ Apply a small velocity change instead of a strong force
- rb.velocity += pushDir * 2f; // Adjust value for softer push
- IsBeingPushed = true;
- print("Enemy is being pushed");
- }
- }
- }
- private void StopAttacking() {
- if (attackCoroutine != null) {
- StopCoroutine(attackCoroutine);
- attackCoroutine = null;
- isAttacking = false;
- Debug.Log("Attack coroutine stopped.");
- }
- }
- private void StartAttacking() {
- // Only start the attack coroutine if it's not already running
- if (attackCoroutine == null) {
- float randomDelay = Random.Range(0f, 0.25f); // ✅ Add a random delay (0 to 1 sec)
- attackCoroutine = StartCoroutine(StartAttackWithDelay(randomDelay));
- }
- }
- private IEnumerator StartAttackWithDelay(float delay) {
- yield return new WaitForSeconds(delay); // ✅ Wait before starting attack
- // ✅ Ensure we only start attacking if still in range
- if (isInRange && !isDead) {
- attackCoroutine = StartCoroutine(ShootAtPlayer());
- isAttacking = true;
- Debug.Log("Started Attacking after delay: " + delay);
- }
- }
- private IEnumerator ShootAtPlayer() {
- while (isInRange && !isDead) {
- Debug.Log("Shooting at player.");
- ShootRaycast();
- // Enforces consistent attack timing
- yield return new WaitForSeconds(attackCooldown);
- }
- // ✅ Attack stops once out of range
- // Attack stops if out of range
- isAttacking = false; // ✅ Ensure this is reset
- // ✅ Instead of checking isInRange only once, start attacking again if needed
- StartAttacking(); // Always re-check and restart attack if applicable
- }
- private void Chase() {
- if (target == null) return;
- Vector3 direction = (target.position - transform.position).normalized;
- float distance = Vector3.Distance(transform.position, target.position);
- isInRange = distance <= attackRange;
- if (distance > 20f) {
- rb.velocity = Vector3.zero;
- return;
- }
- if (!isAttacking) {
- float adjustedSpeed = Mathf.Lerp(0, speed, (distance - minDist) / (attackRange - minDist));
- rb.MovePosition(rb.position + direction * adjustedSpeed * Time.deltaTime);
- } else {
- rb.velocity = Vector3.zero; // ✅ Stop movement when attacking
- }
- }
- private void ShootRaycast() {
- if (target == null) return;
- Vector3 direction = (target.position - transform.position).normalized;
- // Debugging Raycast Direction
- Debug.DrawRay(transform.position, direction * attackRange, Color.red, 1f);
- if (Physics.Raycast(transform.position, direction, out RaycastHit hit, attackRange)) {
- Debug.Log("Raycast hit: " + hit.transform.name);
- if (hit.transform.CompareTag("Player")) {
- source.PlayOneShot(shoot);
- playermovement.Damage(10);
- Debug.Log("Hit player! Damage dealt: " + attackDamage);
- } else {
- Debug.Log("Raycast hit something else: " + hit.transform.name);
- }
- } else {
- Debug.Log("Raycast missed the player.");
- }
- }
- public void AddDamage(float damage) {
- if (isDead) return;
- takeDamage = true;
- isEnraged = true;
- source.PlayOneShot(pickup);
- damageVal = damage;
- health -= damage;
- bloodParticles?.Play();
- if (health <= 0) {
- Die();
- } else {
- StartCoroutine(ResetTakeDamageFlag());
- }
- }
- private void Die() {
- isDead = true;
- isAttacking = false;
- rb.velocity = Vector3.zero;
- bloodParticles?.Play();
- StopAllCoroutines();
- Instantiate(dropPrefab, transform.position, Quaternion.identity);
- }
- private IEnumerator ResetTakeDamageFlag() {
- yield return new WaitForSeconds(0.1f);
- takeDamage = false;
- }
- public void KillCharacter() {
- Destroy(gameObject);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement