using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; public class Enemy : MonoBehaviour { private Transform player; public float chaseSpeed = 2f; public float jumpForce = 2f; public LayerMask groundLayer; private Rigidbody2D rb; private bool isGrounded; private bool shouldJump; public int damage = 1; // Damage dealt to player on collision public int maxHealth = 3; private int currentHealth; private SpriteRenderer spriteRenderer; private Color ogColor; [Header("Loot")] public List lootTable = new List(); void Start() { rb = GetComponent(); player = GameObject.FindGameObjectWithTag("Player").GetComponent(); spriteRenderer = GetComponent(); currentHealth = maxHealth; ogColor = spriteRenderer.color; } void Update() { // Check if grounded isGrounded = Physics2D.Raycast(transform.position, Vector2.down, 1f, groundLayer); // Get player direction float direction = Mathf.Sign(player.position.x - transform.position.x); // Detect if player is above bool isPlayerAbove = Physics2D.Raycast(transform.position, Vector2.up, 5f, 1 << player.gameObject.layer); if (isGrounded) { // Chase player rb.linearVelocity = new Vector2(direction * chaseSpeed, rb.linearVelocity.y); // Jump if there is a gap ahead and no ground in front // else if player above and platform above // If ground RaycastHit2D groundInFront = Physics2D.Raycast(transform.position, new Vector2(direction, 0), 2f, groundLayer); // If gap in front Vector2 origin = (Vector2)transform.position + new Vector2(direction, 0); RaycastHit2D gapAhead = Physics2D.Raycast(origin, Vector2.down, 2f, groundLayer); // If platform above RaycastHit2D platformAbove = Physics2D.Raycast(transform.position, Vector2.up, 5f, groundLayer); if (!groundInFront.collider && !gapAhead.collider) { // No ground in front and no gap ahead, jump shouldJump = true; } else if (isPlayerAbove && platformAbove.collider) { // Player is above and there is a platform above, jump shouldJump = true; } } } private void FixedUpdate() { if (isGrounded && shouldJump) { shouldJump = false; // Reset jump flag after jumping Vector2 direction = (player.position - transform.position).normalized; // Keep speed consistent on diagonal jumps Vector2 jumpDirection = direction * jumpForce; rb.AddForce(new Vector2(jumpDirection.x, jumpForce), ForceMode2D.Impulse); } } public void TakeDamage(int damage, bool dropLoot = true) { currentHealth -= damage; StartCoroutine(FlashWhite()); if (currentHealth <= 0) { Die(dropLoot); } } private IEnumerator FlashWhite() { spriteRenderer.color = Color.white; yield return new WaitForSeconds(0.2f); spriteRenderer.color = ogColor; } void Die(bool dropLoot = true) { Debug.Log("Enemy died, checking for loot drop..."); if (dropLoot) { foreach (LootItem lootItem in lootTable) { Debug.Log($"Checking loot: {lootItem.itemPrefab?.name}, chance: {lootItem.dropChance}"); if (Random.Range(0f, 100f) <= lootItem.dropChance) { Debug.Log("Dropping loot: " + lootItem.itemPrefab?.name); InstantiateLoot(lootItem.itemPrefab); break; // Drop only one item } } } FindFirstObjectByType()?.NotifyObjectDestroyed(gameObject); Destroy(gameObject); } void InstantiateLoot(GameObject loot) { if (loot) { GameObject droppedLoot = Instantiate(loot, transform.position, Quaternion.identity); droppedLoot.GetComponent().color = Color.red; } } }