using System; using System.Collections; using System.Collections.Generic; using UnityEditor.U2D.Animation; using UnityEngine; using UnityEngine.PlayerLoop; using Random = UnityEngine.Random; public class Mob : MonoBehaviour { //[SerializeField] private MobBase mobBase; Rigidbody2D rbody; Animator anim; SpriteRenderer spriteRenderer; List myList; //[SerializeField] private PlayerController playerController; public int nextMove; //public float axisH = 0.0f; bool isDead = false; bool isHit = false; [Header("Temp Stats")] public float maxHp = 100f; public float currentHp; public float moveSpeed = 1f; [Header("Item Drop")] [SerializeField] private GameObject dropItemPrefab; // 드랍할 아이템 프리팹 (에디터에서 할당) [SerializeField][Range(0, 100)] private float dropChance = 50f; // 드랍 확률 (0~100%) void Start() { rbody = GetComponent(); anim = GetComponent(); spriteRenderer = GetComponent(); //playerController = GetComponent(); currentHp = maxHp; // 체력 초기화 Invoke("Think",1); } void Update() { /*axisH = rbody.linearVelocity.x; float direction = axisH > 0 ? 1 : -1; transform.localScale = new Vector2(direction, 1);*/ if (isDead) return; // 방향 전환 if (nextMove != 0) { transform.localScale = new Vector2(nextMove > 0 ? 1 : -1, 1); } } void FixedUpdate() { if (isDead || isHit) return; rbody.linearVelocity = new Vector2(nextMove * moveSpeed, rbody.linearVelocity.y); Vector2 frontVec = new Vector2(rbody.position.x + 0.2f*nextMove, rbody.position.y); Debug.DrawRay(frontVec, Vector3.down, Color.green); RaycastHit2D rayHit = Physics2D.Raycast(frontVec, Vector3.down, 1, LayerMask.GetMask("Ground")); if (rayHit.collider == null) { nextMove *= -1; CancelInvoke("Think"); Invoke("Think", 5); } } void Think() { if (isDead || isHit) return; Debug.Log("생각!"); nextMove = Random.Range(-1, 2); float nextThinkTime = Random.Range(2f, 5f); anim.SetInteger("WalkSpeed", nextMove); Invoke("Think", nextThinkTime); } private void OnTriggerEnter2D(Collider2D other) { if (other.CompareTag("Player")) { PlayerController player = other.GetComponentInParent(); if (player != null) { player.TakeDamage(1, transform.position); } } } public void TakeDamage(float damageAmount, float stunTime, Vector2 attackerPos) //데미지 크기, 타입, 공격 위치 { if (isDead) return; currentHp -= damageAmount; Debug.Log($"몬스터 피격! 남은 체력: {currentHp}"); if (currentHp <= 0) { Die(); return; } StartCoroutine(KnockBack(attackerPos)); } IEnumerator KnockBack(Vector2 attackerPos) { isHit = true; anim.SetTrigger("Hit"); // 피격 애니메이션 (있다면) // 넉백 방향 계산 (몬스터 - 공격자 = 밀려날 방향) Vector2 knockbackDir = (transform.position - (Vector3)attackerPos).normalized; // 넉백 힘 적용 rbody.linearVelocity = Vector2.zero; // 기존 속도 초기화 rbody.AddForce(knockbackDir * 1.5f + Vector2.up * 0.5f, ForceMode2D.Impulse); // 뒤로 살짝 뜨면서 밀림 // 피격 효과 if (spriteRenderer != null) spriteRenderer.color = Color.red; yield return new WaitForSeconds(0.5f); // 0.5초 경직 if (spriteRenderer != null) spriteRenderer.color = Color.white; isHit = false; Think(); } void Die() { isDead = true; anim.SetTrigger("Die"); rbody.linearVelocity = Vector2.zero; GetComponent().enabled = false; // 시체에 또 안 맞게 Invoke("DropItem", 2); //DropItem(); Destroy(gameObject, 2f); // 2초 뒤 삭제 } void DropItem() { // 프리팹이 없으면 실행 안 함 if (dropItemPrefab == null) return; // 0 ~ 100 사이의 난수 생성 float randomValue = Random.Range(0f, 100f); // 확률 당첨 시 if (randomValue <= dropChance) { Debug.Log("아이템 드랍 성공!"); // 몬스터 위치에 아이템 생성 (Quaternion.identity는 회전 없음) Instantiate(dropItemPrefab, transform.position, Quaternion.identity); } } }