study/first_study/Assets/Scripts/EnemySc/Mob.cs
jh04010421 cbdf45196a 윤지호 | LostBits 기능 구현
20226.01.29 수정 (태그 게이지, 태그시 체력 회복 구현)
다음 작업 : 공중몬스터 구현, 태그 스킬 구현
2026-02-03 17:26:37 +09:00

175 lines
4.7 KiB
C#

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<GameObject> 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<Rigidbody2D>();
anim = GetComponent<Animator>();
spriteRenderer = GetComponent<SpriteRenderer>();
//playerController = GetComponent<PlayerController>();
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<PlayerController>();
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<Collider2D>().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);
}
}
}